Based on material by Carlos Scheidegger and Kevin Sun

HTML specifies the content of a web page, but plain HTML says relatively little about how the content looks. This is where CSS comes in. CSS stands for Cascading Style Sheets: they are external declarations that control the way your elements will get rendered by a web browser. A full discussion of CSS syntax is, as usual, given at the MDN CSS website; we show the very basics here.

A stylesheet will usually consist of a list of CSS rules that are inserted in <style> elements in the HTML header, <head>. A single CSS rule associates a CSS selector with a set of CSS declarations.

More important than styling, however, are the rules on how we identify elements in the dom, the selectors.

CSS Element Selectors

Let’s look at a very simple CSS rule:

See output in new page.

In this rule, strong is the element selector, and each line inside the curly brackets is a declaration.

Roughly, the way this goes is: for every DOM element with tag name strong, make its background color brown, and its font size 150% of the base size.

CSS rules are applied in order that they appear in the document, and if more than one rule matches the element, then they both apply (there is more nuance than this, but for now that’s OK). For instance, the example below is entirely equivalent to the above:

See output in new page.

CSS Class Selectors

CSS selectors can be much more powerful than selecting on element names. For example, we can create user-defined “classes” of styles. Classes allow us to define certain elements to be of a specific type that is then formatted consistently. Here is an example with “important” text and a “footnote”. Both are in a <div>, but they have different semantics, and we also want to display them differently.

Class selectors are identified by a leading period ., e.g., .important in CSS.

See output in new page.

Note that we can also apply multiple classes to a single element, as you can see in the important footnote.

CSS ID Selectors

ID selectors work similar to class selectors, but IDs may only be used once for an element in the DOM (as is often the case in HTML, this isn’t enforced by the browser, but you SHOULD definitely do it). ID selectors are identified by a leading hashtag/number/pound sign #, e.g., #header. You can use IDs as “anchors” to refer to a site by appending #idname to the URL. For example, following this link (#css-id-selectors) will scroll your browser to this section.

But you can also use IDs to apply custom styles in CSS:

See output in new page.

You can also use the combination of IDs and CSS to create layouts of a page:

See output in new page.

However, nowadays, you should use CSS Grid Layouts to lay out a potentially responsive web page.

CSS Relationship Selectors

CSS selectors let you match elements based on their relationship with other elements. While I will simply refer you to the MDN Selectors webpage for the full reference, I want to highlight two particularly important ones: the child selector and the descendant selector.

The child selector matches every time an element is directly enclosed by a different element. For example, consider the following rule involving the child selector:

See output in new page.

Multiple Rules in CSS

When more than one CSS rule matches, then different CSS declarations might conflict with one another. In that case, “the most specific declaration wins”. The rules for what counts as more specific are really disgusting, so if you find yourself debugging CSS code because the styles “don’t take”, the first thing you should try is to set completely different classes for the element and add all the declarations to this class. Then, with help from the Developer Tools, you can add classes back to your element to see which declarations might be winning the specificity race. In order to avoid this kind of trouble, it’s better to stick to simple declarations as much as possible.

Try editing CSS directly in the inspector!

Pseudo Classes

Pseudo classes are selectors for states that can be combined with other selectors. Typical examples are :hover, :visited, or :nth-child() which can be used like this:

See output in new page.

Other ways of declaring CSS

You can provide CSS stylesheets as an external file. This is very useful when you want to share CSS rules across many different documents. In that case, you include the following element in your <head>:

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

In this case, style.css should be an additional file that consists entirely of CSS rules.

Finally, you can place CSS declarations directly inside an element. You do this using the style attribute, which most HTML elements support. For example, if you have this CSS rule:

See output in new page.

It’s a bad idea to do this in HTML that you write manually: you’re mixing content with presentation, and making it hard to reuse the declarations. But later on we will be writing code to generate elements in the DOM for us, and in that case, this will be a very common and good thing to do, because in that case reusability will be achieved in our Javascript source code.