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


Slides & source code available on

Setup


There will be some hands-on activities sprinkled throughout this talk!

If you’d like to follow along, please be sure to:

  1. install R and RStudio – I’ll be using RStudio, though you may use alternative IDEs (e.g. VS Code) if that’s where you’re most comfortable
  2. install Quarto – this may require updating R/RStudio if you already have those installed
  3. grab the materials from GitHub, https://github.com/samanthacsik/cute-cats-dogs, using one of the following approaches:
    1. instructions for downloading the GitHub repository to work locally (do this if you don’t have git/GitHub configured)
    2. instructions for forking & cloning the GitHub respository (do this if you do have git/GitHub configured)

Hello!


  • I’m Sam Csik (pronounced “chick”)
  • I’m obsessed with my two cats and dog (hang tight, this is relevant)
  • I’m the NCEAS/MEDS Data Training Coordinator
  • I’m a data science educator and primarily an R user
  • I’m not a web developer

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.

Source: Adapted from Nicolas Karasiak

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.

Source: Adapted from Nicolas Karasiak

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.

HTML

Browser default styling

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).

Browser default styling

CSS styling

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

Note: Some HTML elements have no content (e.g. the <br>, or “break” element) – these are called empty elements and do not have an end tag.

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 Face Grin Beam Sweat .

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

# Here is my level one header

Here is my first paragraph

Here is my second paragraph, where you can read more about NCEAS [Roundtables](https://www.nceas.ucsb.edu/roundtable).

This is very important text!

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 HTML 5 Logo



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.

CSS

h1 {
  color: green;
  letter-spacing: 5px;
}


HTML

<h1>My level one header will be styled</h1>
<h2>This level two header will not be styled</h2>
<p>Neither will this paragaph</p>
<h1>But this second level one header will be</h1>



Output

Group multiple element selectors together (separated by commas) if you want them all styled the same way.

CSS

h1, h2, p {
  text-align: center;
  color: purple;
}


HTML

<h1>My level one header will be styled</h1>
<h2>This level two header will be styled</h2>
<h3>This level three header will not be styled</h3>
<p>This paragraph will be styled</p>



Output

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">

CSS

.blue-italicized {
  color: blue;
  font-style: italic;
}


HTML

<p class="blue-italicized">My first paragraph is styled</p>
<p>But my second paragraph is not</p>


Output

Use <span> to target part of an element


The HTML <span> tag is used to apply class selectors to part of an element.


CSS

.blue-italicized {
  color: blue;
  font-style: italic;
}


HTML

<p>Only the word <span class="blue-italicized">blue</span> is styled.</p>


Output

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.

CSS

h1 {
  color: blue; 
  font-style: italic; 
}

.orange-text {
  color: orange;
}


HTML

<h1>This level one header will be blue</h1>
<h1 class="orange-text">This one will be orange</h1>



Output

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:

---
theme: practice-styles.css
---

# Here is my level one header

[Here is my first paragraph]{.blue-text}

Here is my second paragraph, where you can read more about NCEAS [Roundtables](https://www.nceas.ucsb.edu/roundtable).

[This is [very]{.blue-text} important text!]{.important-text}

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 is a CSS extension (provides additional features, like variables)
  • Sass is a CSS preprocesser (converts Sass code into standard CSS because browsers can’t interpret Sass)

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!)

/* define Sass vars */

$green: #348553;
$yellow: #E9A300;
$red: #A23601;

/* use vars in CSS rules */

h1 {
  color: $green;
}

.button-styling {
  background: $yellow;
  color: $red; 
  border-color: $green;
}

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:

---
theme: practice-styles.scss
---


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


  1. Create a .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):
touch my-report-styles.scss 
  1. Add the /*-- scss:defaults --*/ and /*-- scss:rules --*/ region decorators to cuteness-report.scss (required by Quarto):
/*-- scss:defaults --*/

// Sass variables will go here

/*-- scss:rules --*/

// CSS rules will go here

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;

/*-- scss:defaults --*/

// colors
$green: #348553;
$light-green: #589244; 
$yellow: #E9A300;
$red: #A23601;
$white: #FFFFFF;
$gray: #ADADAD;
$black: #525452; 

/*-- scss:rules --*/

// CSS rules will go here


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:

  1. Select which weights and styles to import from the Styles section – click the + button, , to the right of the style you want.

  2. 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


  1. Paste your import code into my-report-styles.scss, beneath /*-- scss:defaults --*/
/*-- 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; 

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!):

  1. Specifying Quarto’s Sass Variables – this is a super fast and easy way to make larger-scale changes to your theme
  2. Writing CSS rules, just like we practiced earlier – this is great for making fine-tuned adjustments

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


Without my-report-styles.scss applied

With my-report-styles.scss applied

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!):

  • Level 2 headers (<h2>/##):
    • colored green
    • section underlined in yellow
    • serif font (Arvo)
  • Level 3 headers (<h3>/###):
    • colored green

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:

  • Document title (targeted with .title class):
    • colored green
    • serif font (Arvo)
    • increase font size
  • Document subtitle (targeted with .lead class):
    • increase font size
/*-- 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:

  • increase the size of the text (.large-text)
  • center the text (.center-text)
  • color/style the background of our text to make it stand out (.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):

<p class="large-text highlight-text center-text">Explore our analysis on [{{< fa brands github >}} GitHub](https://github.com/samanthacsik/cute-cats-dogs). If you have suggestions on how to improve this report, please [file an issue](https://github.com/samanthacsik/cute-cats-dogs/issues).</p>

which will render as:

Check out your final styled document!


Styling web pages can be challenging. Here are some tips!


^ I feel this way often when trying to write CSS

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:

  • re-rendering often to ensure your Sass/CSS is working as expected
  • Google! (lots of queries that look like, “CSS underline text”, “CSS rounded corners”, etc.)
  • W3 Schools – seriously such a valuable resource (especially their interactive tutorials)
  • drawing inspiration (and borrowing source code) from other webpages

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.