cssdojo(re)learn CSS, the right way

Introduction to CSS and How the browser renders the page


CSS stands for Cascading Style Sheets. It is a core web language, with HTML and JS it forms the base for website creation. HTML conveys the meaning of the document, Javascript can change it dynamically and CSS is for improving the looks of it.

Some vocabulary first. When we write CSS, we write a lot of CSS rules:

A h1 rule with font-size and color declarations
An example of CSS rule: make all the first-level titles red and big
A selector followed by multiple declarations inside curly braces
Points to the HTML element(s) that you want to style (in the case above: h1)
A combination of a CSS property and a value (in the case above: color: red;)

We’re going to learn a lot of selectors, properties and values in the next katas. But first, it is important to understand where to write CSS and how the browser renders it.

Where do we write CSS?

There are 3 ways to include CSS in a HTML page:

  • In a <style> HTML tag inside the HTML <head>
  • In an external file linked by inserting a <link> HTML tag inside the HTML <head>
  • Inside the style attribute of any HTML tag

Task: go ahead and try every way to include CSS!

Some questions arise already:

What is the best way to include CSS?
Inline styles clutter HTML with style properties and is bad for another reason we’re going to see in the next kata. For now, remember: don’t do inline styles. Usually, external files are more practical than the style tag because we may need to write a lot of CSS. External files help keeping it tidy and clean and it separates concerns between HTML (meaning) and CSS (styles). In the following exercises, we’ll use the style tag directly and we won’t need to put html, head and body tags: the live editor will take care of it.
How the browser knows the important text must be red instead of blue?
This will be the focus of the next kata, Selectors and Specificity.
How does the browser renders the page from CSS?
This is what we are going to see, because there are some caveats.

How the browser renders the page

To optimize your website for the best User Experience and page speed as possible, it is essential to understand the Critical Rendering Path (CRP). If you want a detailed explanation, here is a fantastic article about how the browser renders a web page. Here is a summary of what is the CRP:

DOM construction
As the HTML file comes in over the network, the browser parses it and builds a DOM tree representing every HTML node encountered.
CSSOM construction
The browser also reads CSS and constructs a similar tree containing all information about how to style the page. It’s the CSSOM.
Render tree
DOM and CSSOM are combined into one tree. All DOM nodes that should not be displayed (for instance script tags or nodes hidden with CSS) are not present in the render tree.
The Layout operation takes the render tree and computes the position of every element on the page. It is also called reflow and it can happen when you scroll or resize your window.
The browser then creates layers for the elements and fill them with pixels based on the render tree rules. This is also called rasterization.
The browser takes the layers and build the final image that will be drawn on screen.
This page profiled by the chrome dev tools - all rendering operations included
You can see all these steps in the Performance tab of your browser’s dev tools

The user will see something only when the first paint is finished. It’s the First Contentful Paint (FCP) timing. We want that to happen as quickly as possible but there are two main caveats:

  • The CSS is render-blocking. The DOM tree is built incrementally as the browser receives the HTML over the network, but this is not the case with CSSOM. If the CSSOM and render tree were built and rendered incrementally, we would see the page build itself and flash every microsecond as the CSS is read. This is not good for user experience nor optimal. Thus when the browser encounters a <style> tag or an external CSS file, the CSSOM is built in one go. Until the whole CSS file is parsed, the render tree construction will be blocked. The browser will continue to parse the DOM but nothing will appear on screen until the stylesheet is downloaded and parsed.
  • The CSS is script-blocking. Javascript can manipulate the DOM and access the styles of any element throught the style object of every DOM node. Thus, it is dangerous to execute Javascript while a stylesheet is being downloaded. Imagine that a script reads a style value while a stylesheet download is in progress. Depending on when the stylesheet download finishes and the CSSOM update completes, the value may or may not be outdated. To prevent race conditions, all script execution is paused until every previous stylesheet in the DOM is downloaded and parsed.

Let that sink in. While the browser downloads a stylesheet, nothing will change on screen and all scripts will be paused. Thus, we should keep our stylesheets lightweight and fast to load.

This can lead to various edge cases. Imagine loading a CSS file from an external server (for instance by including a new font). If the server is down for whatever reason and takes 30 seconds to answer, your page will be blank for at least 30 seconds before something happens.

What happens if I write invalid CSS?

If you write invalid CSS (because of a syntax error or a property/value doesn’t exist), the browser will simply ignore it. See the example below:

That also ensures the backwards compability of CSS. When new properties are added in the spec, you can use them freely and it will not impact the rendering in browsers that don’t support them. To check if a CSS property, value or feature is compatible with a browser, use this great website: caniuse.com.

What I should remember

  • Some vocabulary: rules, selectors, declarations, properties and values.
  • Don’t do inline styles.
  • Some more vocabulary: Critical Rendering Path, DOM, CSSOM, render tree, layout and paint operations, First Contentful Paint.
  • CSS is a render-blocking and a script-blocking ressource, it can impact the load time.
  • Check if CSS features are supported by browsers with caniuse.com.