B.2 CSS

The Cascading Stylesheets (CSS) language is used to describe the look and formatting of documents written in HTML. CSS is responsible for the visual style of your site. CSS is a lot of fun to play with, but it can also easily steal your time.

In the Hugo framework (https://gohugo.io/tutorials/creating-a-new-theme/), CSS is one of the major “non-content” files that shapes the look and feel of your site (the others are images, JavaScript, and Hugo templates). What does the “look and feel” of a site mean? “Look” generally refers to static style components including, but not limited to

  • color palettes,
  • images,
  • layouts/margins, and
  • fonts.

whereas “feel” relates to dynamic components that the user interacts with like

  • dropdown menus,
  • buttons, and
  • forms.

There are 3 ways to define styles. The first is in line with HTML. For example, this code

<p>Marco! <em>Polo!</em></p> 

would produce text that looks like this: Marco! Polo!

However, this method is generally not preferred for numerous reasons.

A second way is to internally define the CSS by placing a style section in your HTML:

<html>
<style> 
#favorite {
    font-style: italic;
}
</style>
<ul id="tea-list">
  <li>Earl Grey</li>
  <li>Darjeeling</li>
  <li>Oolong</li>
  <li>Chamomile</li>
  <li id="favorite">Chai</li>
</ul>
</html>

In this example, only the last tea listed, Chai, is italicized.

The third method is the most popular because it is more flexible and the least repetitive. In this method, you define the CSS in an external file that is then referenced as a link in your HTML:

<html>
    <link rel="stylesheet" href="/css/style.css" />
</html>

What goes inside the linked CSS document is essentially a list of rules (the same list could appear internally between the style tags, if you are using the second method). Each rule must include both a selector or group of selectors, and a declarations block within curly braces that contains one or more property: value; pairs. Here is the general structure for a rule:

/* CSS pseudo-code */
selectorlist {
    property: value;
    /* more property: value; pairs*/
}

Selectors can be based on HTML element types or attributes, such as id or class (and combinations of these attributes):

/* by element type */
li { 
    color: yellow; /* all <li> elements are yellow */
}

/* by ID with the # symbol */
#my-id { 
    color: yellow; /* elements with id = "my-id" are yellow */
}

/* by class with the . symbol */
.my-class { 
    color: yellow; /* elements with class = "my-class" are yellow  */
}

Because each HTML element may match several different selectors, the CSS standard determines which set of rules has precedence for any given element, and which properties to inherit. This is where the cascade algorithm comes into play. For example, take a simple unordered list:

<ul id="tea-list">
  <li>Earl Grey</li>
  <li>Darjeeling</li>
  <li>Oolong</li>
  <li>Chamomile</li>
  <li>Chai</li>
</ul>

Now, let’s say we want to highlight our favorite teas again, so we’ll use a class attribute.

<ul id="tea-list">
  <li>Earl Grey</li>
  <li class="favorite">Darjeeling</li>
  <li>Oolong</li>
  <li>Chamomile</li>
  <li class="favorite">Chai</li>
</ul>

We can use this class attribute as a selector in our CSS. Let’s say we want our favorite teas to be in bold and have a background color of yellow, so our CSS would look like this:

.favorite {
  font-weight: bold;
  background-color: yellow;
}

Now, if you want every list item to be italicized with a white background, you can set up another rule:

li { 
  font-style: italic;
  background-color: white;
}

If you play with this code (which you can do easily using sites like http://jsbin.com, https://jsfiddle.net, or https://codepen.io/pen/), you’ll see that the two favorite teas are still highlighted in yellow. This is because the CSS rule about .favorite as a class is more specific than the rule about li type elements. To override the .favorite rule, you need to be as specific as you can be when choosing your group of selectors:

ul#tea-list li.favorite {
  background-color: white;
}

This example just scratches the surface of cascade and inheritance.

For any Hugo theme that you install, you can find the CSS file in the themes/ folder. For example, the default lithium theme is located in: themes/hugo-lithium/static/css/main.css. Once you are familiar with CSS, you can understand how each set of rules work to shape the visual style of your website, and how to alter the rules. For some themes (i.e., the hugo-anatole theme), you have the option of linking to a custom CSS, which you can use to further customize the visual style of your site.

A few one-line examples illustrate how simple CSS rules can be used to make dramatic changes:

  • To make circular or rounded images, you may assign a class img-circle to images (e.g., <img class="img-circle" src="foo.png" />) and define the CSS:

    .img-circle {
      border-radius: 50%;
    }
  • To make striped tables, you can add background colors to odd or even rows of the table, e.g.,

    tr:nth-child(even) {
      background: #eee;
    }
  • You can append or prepend content to elements via pseudo-elements ::after and ::before. Here is an example of adding a period after section numbers: https://github.com/rstudio/blogdown/issues/80.