There will be some hands-on activities sprinkled throughout this talk!
Just enough CSS (and Sass)
for data scientists looking to add a little pizzazz to their web pages
Sam Csik |
Data Training Coordinator
National Center for Ecological Analysis & Synthesis
Roundtable |
August 2023
National Center for Ecological Analysis & Synthesis
Setup
There will be some hands-on activities sprinkled throughout this talk!
If you’d like to follow along, please be sure to:
Hello!
Teaching in MEDS motivated me to learn more about web page styling
Until just a couple years ago, I really didn’t know anything about what goes into making a web page look the way it does…knowing even just a tiny bit now feels powerful and magical and fun.
So what’s a web page made up of?
HTML & CSS are the building blocks of web pages
HTML (Hypertext Markup Language) is a markup language that tells web browsers how to structure web pages. You can think of HTML as the skeleton of a web page. It gives authors the means to create elements like headings, text, tables, lists, add media, etc.
HTML & CSS are the building blocks of web pages
CSS (Cascading Style Sheets) is a programming language that allows you to control how HTML elements look on a web page. You can think of CSS as the outfit that is styling the skeleton. It allows authors to control aspects such as the colors, layout, and font style.
Your browser has its own internal stylesheet to render HTML
Your browser will style HTML documents using an internal style sheet, which ensures that headings are larger than normal text, links are highlighted, lists and tables are structured correctly, etc.
CSS adds pizzazz to web page renderings
CSS allows website developers to add additional styling to web browser defaults. Otherwise, websites would be pretty boring to look at (and they’d all generally look the same).
Keep in mind we need three things to style web pages:
HTML element(s)
These can be written in a number of file formats, including .html
, .md
, .rmd
, and .qmd
files
CSS rules
CSS can be written in a number of different places, but saving them to an external stylesheet is often preferred (e.g. .css
, .scss
, .sass
files)
apply those CSS rules to your HTML elements
Link a stylesheet to the file where you’re HTML lives & apply styling as necessary
A light introduction to HTML
HTML consists of a series of elements
Elements comprise start tags and end tags that render some form of content in a particular way.
The basic anatomy of an HTML element:
In Markdown syntax, this HTML element would be written as: # Welcome to your website customization workshop
Commonly used HTML tags
Browse a more complete list of HTML tags.
Tag | What it does |
---|---|
<div></div> |
defines a division or section in an HTML document |
<h1></h1> |
create a first-level heading (largest) |
<h6></h6> |
create a sixth-level heading (smallest) |
<p></p> |
begin a new paragraph |
<strong></strong> |
bold text |
<em></em> |
italicized text |
<img></img> |
present an image |
<a></a> |
define a hyperlink |
<br> |
add a line break (empty element) |
<span></span> |
an inline container used to markup part of a text or document |
HTML elements can be nested
Remember to close out tags from the inside-out to avoid unexpected renderings.
Nested HTML elements:
In Markdown syntax, this HTML element would be written as: # Welcome to your **website customization** workshop
Important: Take extra care to never skip (or incorrectly type) an end tag! Some elements will still display correctly if you forget an end tag, but you cannot rely on this. Forgotten end tags will cause you headaches as you try troubleshoot unexpected results and errors .
HTML attributes can be used for targeted styling
Attributes provide extra information about elements. They are always specified in the start tag and usually come in value/name pairs (e.g. attributeName="attributeValue"
).
Attributes can be used for targeted styling with CSS (e.g. class attributes) – more on this soon!
Let’s take a look at some HTML
Check out the following HTML by opening the practice-html.html
file in RStudio
To open in RStudio, click on the practice-html.html
file in Files pane, then Open in Editor
<!DOCTYPE html> <!-- All HTML docs start with a doc type declaration-->
<html> <!-- This tag represents the root of the HTML doc -->
<head>
<!-- Write any metadata about the HTML doc here (inluding the link to an external CSS file) -->
</head>
<body>
<!-- Write all the contents of the HTML doc here -->
<h1>Here is my level one header</h1>
<p>Here is my first paragraph</p>
<p>Here is my second paragraph, where you can read more about NCEAS <a href="https://www.nceas.ucsb.edu/roundtable">Roundtables</a>.</p>
<p>This is very important text!</p>
</body>
</html>
Click Preview to render the HTML
markdown makes it easy to “write” HTML
Check out the following markdown by opening the practice-markdown.qmd
file in RStudio
To open in RStudio, click on the practice-markdown.qmd
file in Files pane
Click Render to render your .qmd
file as HTML – it should open in RStudio’s Viewer pane and generate a practice-markdown.html
file. Note: Quarto applies the default Bootstrap 5 theme to rendered markdown (giving it a bit of styling as compared to our HTML on the previous slide).
A light introduction to CSS
CSS is a rule-based language
CSS is a rule-based language – it allows you to define groups of styles that should be applied to particular elements or groups of elements on a web page. For example, “I want all level one (<h1>
) headings to be green text with a bit of extra space between each letter” could be coded as:
We’re going to focus on element and class selectors, but check out these slides for an overview of other simple selectors. W3 Schools is also an excellent resource for learning about CSS selectors, exploring the many CSS properties, and much much more (I use this all the time!).
Select an element(s) based on its tag
Any HTML element can be used as a selector. The declarations specified apply to all HTML elements of that type.
Group multiple element selectors together (separated by commas) if you want them all styled the same way.
Target an element(s) using class selectors
A class selector uses the class
attribute of an HTML element to style that specific element. Class selectors are written using a .
followed by the selector name, e.g. .selector
. HTML elements can have more than one class, e.g. <p class="class1 class2">
Use <span>
to target part of an element
The HTML <span>
tag is used to apply class selectors to part of an element.
Conflicting rules? The more specific rule wins
It is common to have more than one CSS rule that points to the same element. As you build more complex stylesheets, determining which CSS rule “wins out” can get complicated. At a very basic level, the more specific CSS “wins”. In the context of today’s talk, class selectors are more specific than element selectors and will take precedence.
Practice writing element & class selectors
Let’s write some CSS and apply our practice-styles.css
stylesheet to practice-html.html
.
/* ------- element selectors ------- */
/* style level one headers */
h1 {
background-color: #49bf96;
border-radius: 25px;
letter-spacing: 5px;
text-align: center;
}
/* purple italicized hyperlinks */
a {
color: purple;
font-style: italic;
}
/* ------- class selectors ------- */
/* blue text */
.blue-text {
color: blue;
}
/* large red text */
.important-text {
color: red;
font-size: 30px;
}
Below, we (a) link our stylesheet (line 5), and (b) use our class selectors to apply targeted styling (lines 10 & 12). These follow the general syntax:
<html-tag class="class-selector">Content</html-tag>
<!DOCTYPE html> <!-- All HTML docs start with a doc type declaration-->
<html> <!-- This tag represents the root of the HTML doc -->
<head>
<!-- Write any metadata about the HTML doc here (inluding the link to an external CSS file) -->
<link rel="stylesheet" href="practice-styles.css">
</head>
<body>
<!-- Write all the contents of the HTML doc here -->
<h1>Here is my level one header</h1>
<p class="blue-text">Here is my first paragraph</p>
<p>Here is my second paragraph, where you can read more about NCEAS <a href="https://www.nceas.ucsb.edu/roundtable">Roundtables</a>.</p>
<p class="important-text">This is <span class="blue-text">very</span> important text!</p>
</body>
</html>
Applying a stylesheet to a .qmd
file
Note the required /*-- scss:rules --*/
region decorator, which has been added at the top of the file (required by Quarto).
/*-- scss:rules --*/
/* ------- element selectors ------- */
/* style level one headers */
h1 {
background-color: #49bf96;
border-radius: 25px;
letter-spacing: 5px;
text-align: center;
}
/* purple italicized hyperlinks */
a {
color: purple;
font-style: italic;
}
/* ------- class selectors ------- */
/* blue text */
.blue-text {
color: blue;
}
/* large red text */
.important-text {
color: red;
font-size: 30px;
}
Below, we (a) call our stylesheet in the YAML metadata header using the theme
option (line 2), and (b) use our class selectors to apply targeted styling (lines 7 & 11).
---
theme: practice-styles.css
---
# Here is my level one header
<p class="blue-text">Here is my first paragraph</p>
Here is my second paragraph, where you can read more about NCEAS [Roundtables](https://www.nceas.ucsb.edu/roundtable).
<p class="important-text">This is <span class="blue-text">very</span> important text!</p>
Note: Quarto also provides its own syntax for applying classes to elements. For example:
How are we all feeling?
To me, writing a little CSS always feels a bit magical
Now it’s time to get a little y
Syntactically Awesome Stylesheets
Sass helps to reduce repetition
Sass extends existing CSS features in a number of exciting ways, but importantly reduces repetition. For example, let’s say you’re working on a website/web page that uses three main colors:
You might imagine how often you’ll need to type those HEX codes out as you develop your stylesheet…it can get annoying rather quickly.
Define Sass variables to reduce repetition
Sass allows us to define variables (in the form $var-name: value;
) for our colors to reference instead of writing out their HEX codes each time. This makes your stylesheet more readable and easier to update (e.g. only need to change HEX codes in one spot, not multiple!)
Note: Sass has two syntaxes – SCSS syntax (.scss
), shown above, is the most common. It stands for Sassy Cascading Stylesheets
Quarto automatically compiles Sass
Recall: Web browsers can interpret CSS ( .css
) but not Sass ( .scss
or .sass
). Typically, you’ll need to compile (aka convert) Sass to CSS, then link the resulting .css
file in your HTML.
Lucky for us, Quarto compiles the contents of a .scss
file into CSS without any extra steps – you may link a .scss
file in the YAML of your .qmd
file. For example:
From here on out, we’ll be writing our Sass variables and CSS rules in a .scss
file, which we’ll use to style our fun/silly sample report.
We have a very important report in need to some styling
Open & render cuteness-report.qmd
by clicking the Render button in RStudio
Create a .scss
file
.scss
file in the report/
folder – you can do this using the touch
command in the RStudio terminal (You may need to first cd
(change directory) into this folder using the terminal, or manually move your .scss
into the report/
folder after creating it):/*-- scss:defaults --*/
and /*-- scss:rules --*/
region decorators to cuteness-report.scss
(required by Quarto):Apply your .scss
stylesheet to your .qmd
Link my-report-styles.scss
to your cuteness-report.qmd
file using the theme
option in the YAML (see lines 11-12):
Define some color variables
Because this is NCEAS-funded research (jk jk, but let’s pretend), we’ll be using NCEAS colors to style our report. Define any colors you plan to use throughout your stylesheet using the syntax, $colorName: #HEXcode;
Note: You won’t see new styling on your report just yet! We’ve defined some Sass variables here, but haven’t yet applied them.
Import Google fonts
Start by exploring fonts at https://fonts.google.com/. Once you found a one (or more) that you like:
Select which weights and styles to import from the Styles section – click the + button, , to the right of the style you want.
Click on View selected families, (top right corner), to see all of your selected fonts. Under the Use on the web section, select the radio button for @import and copy everything between the <style> </style>
tags (starting with @import
and ending with ;
) to your clipboard.
Import & define Google font variables
my-report-styles.scss
, beneath /*-- scss:defaults --*/
Here, we import two font families:
Note: You must import a higher font weight (e.g. 800) if you wish to bold text.
Checking in – any questions?
Ok, now let’s use our colors & fonts
We can do this in two different ways (spoiler, we’ll be using both!):
Specify font variables
Define font style Sass variables, beneath /*-- scss:defaults --*/
, using the syntax below:
/*-- scss:defaults --*/
// import fonts from fonts.google.com
@import url('https://fonts.googleapis.com/css2?family=Arvo&family=Nunito:wght@400;800&display=swap');
// colors
$green: #348553;
$light-green: #589244;
$yellow: #E9A300;
$red: #A23601;
$white: #FFFFFF;
$gray: #ADADAD;
$black: #525452;
// font styles
$font-family-sans-serif: 'Nunito', sans-serif;
$font-family-serif: 'Arvo', serif;
Note: $font-family-sans-serif
will automatically be applied across your Quarto document.
Specify additional Quarto variables
Note: All specified Sass variables could alternatively be written using CSS. However, this approach is quick, easy to write, and importantly, easy to read.
/*-- scss:defaults --*/
// import fonts from fonts.google.com
@import url('https://fonts.googleapis.com/css2?family=Arvo&family=Nunito:wght@400;800&display=swap');
// colors
$green: #348553;
$light-green: #589244;
$yellow: #E9A300;
$red: #A23601;
$white: #FFFFFF;
$gray: #ADADAD;
$black: #525452;
// font styles
$font-family-sans-serif: 'Nunito', sans-serif;
$font-family-serif: 'Arvo', serif;
// find all Quarto Sass vars here: https://quarto.org/docs/output-formats/html-themes.html#sass-variables
$body-color: $black;
$link-color: $red;
$toc-color: $green;
$toc-active-border: $yellow;
$toc-inactive-border: $gray;
$code-color: $light-green;
Re-render to check out your new styling
Next up: fine-tuning with some CSS
“Inspect”ing reveals how CSS is used to target HTML elements
Temporarily “edit” CSS selectors (refreshing your browser will revert your page back to its original state) – helps to identify exactly which elements different selectors are manipulating and allows you to try out styles before actually hard-coding them.
Start with element selectors (at least, I like to)
The following CSS rules apply styling to level 2 & 3 headers (inspecting the page helped me test these out first!):
<h2>
/##
):
<h3>
/###
):
Note: we’re now writing our rules beneath the /*--- scss:rules ---*/
region decorator.
/*-- scss:defaults --*/
// import fonts from fonts.google.com
@import url('https://fonts.googleapis.com/css2?family=Arvo&family=Nunito:wght@400;800&display=swap');
// colors
$green: #348553;
$light-green: #589244;
$yellow: #E9A300;
$red: #A23601;
$white: #FFFFFF;
$gray: #ADADAD;
$black: #525452;
// font styles
$font-family-sans-serif: 'Nunito', sans-serif;
$font-family-serif: 'Arvo', serif;
// find all Quarto Sass vars here: https://quarto.org/docs/output-formats/html-themes.html#sass-variables
$body-color: $black;
$link-color: $red;
$toc-color: $green;
$toc-active-border: $yellow;
$toc-inactive-border: $gray;
$code-color: $light-green;
/*-- scss:rules --*/
// level two styling
h2 {
color: $green;
border-bottom: 3px solid $yellow;
font-family: $font-family-serif;
}
// level three stying
h3 {
color: $green;
}
Modify existing class selectors
Inspecting reveals the existing class selectors (already defined by the Quarto framework), .title
and .lead
, which are used to target the document title and subtitle, respectively. We can modify what these do by including them in our stylesheet. I’ll make the following updates:
.title
class):
.lead
class):
/*-- scss:defaults --*/
// import fonts from fonts.google.com
@import url('https://fonts.googleapis.com/css2?family=Arvo&family=Nunito:wght@400;800&display=swap');
// colors
$green: #348553;
$light-green: #589244;
$yellow: #E9A300;
$red: #A23601;
$white: #FFFFFF;
$gray: #ADADAD;
$black: #525452;
// font styles
$font-family-sans-serif: 'Nunito', sans-serif;
$font-family-serif: 'Arvo', serif;
// find all Quarto Sass vars here: https://quarto.org/docs/output-formats/html-themes.html#sass-variables
$body-color: $black;
$link-color: $red;
$toc-color: $green;
$toc-active-border: $yellow;
$toc-inactive-border: $gray;
$code-color: $light-green;
/*-- scss:rules --*/
// level two styling
h2 {
color: $green;
border-bottom: 3px solid $yellow;
font-family: $font-family-serif;
}
// level three stying
h3 {
color: $green;
}
// style document title
.title {
color: $green;
font-family: $font-family-serif;
font-size: 2.3em;
}
// adjust size of documment subtitle
.lead {
font-size: 1.5em;
}
Create new class selectors
Let’s say we want to better highlight the very last sentence of our report, which links out to our GitHub repo & provides instructions for contributing:
We can create three new classes that:
.large-text
).center-text
).highlight-text
)/*-- scss:defaults --*/
// import fonts from fonts.google.com
@import url('https://fonts.googleapis.com/css2?family=Arvo&family=Nunito:wght@400;800&display=swap');
// colors
$green: #348553;
$light-green: #589244;
$yellow: #E9A300;
$red: #A23601;
$white: #FFFFFF;
$gray: #ADADAD;
$black: #525452;
// font styles
$font-family-sans-serif: 'Nunito', sans-serif;
$font-family-serif: 'Arvo', serif;
// find all Quarto Sass vars here: https://quarto.org/docs/output-formats/html-themes.html#sass-variables
$body-color: $black;
$link-color: $red;
$toc-color: $green;
$toc-active-border: $yellow;
$toc-inactive-border: $gray;
$code-color: $light-green;
/*-- scss:rules --*/
// level two styling
h2 {
color: $green;
border-bottom: 3px solid $yellow;
font-family: $font-family-serif;
}
// level three stying
h3 {
color: $green;
}
// style document title
.title {
color: $green;
font-family: $font-family-serif;
font-size: 2.3em;
}
// adjust size of documment subtitle
.lead {
font-size: 1.5em;
}
// center text
.center-text {
text-align: center;
}
.large-text {
font-size: 1.4em;
}
// yellow highlight
.highlight-text {
background-color: rgba(233, 163, 0, 0.2);
padding-top: 5px;
padding-bottom: 5px;
padding-right: 5px;
padding-left: 5px;
border-radius: 25px;
}
Apply new class selectors
Now that we’ve written our class selectors, we need to apply them to the HTML elements we want to style (recall, HTML elements can have more than one class):
which will render as:
Check out your final styled document!
Styling web pages can be challenging. Here are some tips!
For me, it’s a lot of it is trial and error. Inspecting your website can take patience and persistence to figure out how exactly to target your desired element. Some things that have helped me:
Happy styling!
This is a Quarto Presentation. To learn more, visit https://quarto.org.
If you see mistakes or want to suggest changes, please create an issue on the source repository.