The Layers of CSS

Laurie - Apr 8 '19 - - Dev Community

So, when last I was here we discussed the various layers of the Javascript stack and how they all come together to make frameworks on frameworks of beautiful confusion!

If you missed that post, check it out here: The Layers of Javascript.

That post seemed to resonate with a bunch of people, which was wonderful. Around the time I wrote it I started trying to fix an alignment issue with an element on my site. In the course of trying to do that it dawned on me that CSS also has layers. So, here we go!

W3C and Standards

Stop me if you've heard this before, CSS has a standard. The standard is controlled by the CSS Working Group (W3C). In 2011 the W3C made the decision that CSS standards would be divided into modules that could move forward independently. As a result, the language doesn't have full version updates anymore. You may have heard of CSS3 as the most modern version of CSS. Technically that standard doesn't exist formally since it is all independent modules now, but people use the term because all the modules started by standardizing at level 3.

Based on this standard, it's up to the browsers to support it. Each browser has its own CSS parser/rendering engine. This is why you often hear people talking about what Internet Explorer does and doesn't support. So, just like Javascript, you're worried about whether your CSS can be interpreted by the browser it will be displayed in.

CSS and the DOM

When you pull up your site in the browser the rendering engine parses the HTML and interprets the CSS. As it adds elements to the DOM tree it maps them to their associated styles. This is where you can pull up your inspector and look at the specifics of what styles a given element ended up with.

Chrome inspector showing CSS styles.
You can even play around with the styles if you want!

Cascading Styles, like a river in Egypt

CSS actually stands for Cascading Style Sheets. When the browser is interpreting the CSS it has to take into account different style sheets coming from different sources.

There are browser styles which are provided by the browser itself; there are "author" styles which are the style sheets you (or someone else) built to apply to the site being rendered; you may even have user styles that override the styles for a particular person's view of the site.

What happens when they clash? Who wins out? CSS has a hierarchy for how these differing styles are merged together and which is authoritative depending on the situation.

For more details check out Introducing the CSS Cascade

I know CSS! Wait, who is this LESS person?!

So aside from the layers of how the code is interpreted, there are numerous layers to writing CSS in the first place. When we think of styles we typically think of a CSS file full of key-value pairs that assign styles to our code. These are essentially rules that get applied to the specified HTML elements.

a {
    color: black;
}
Enter fullscreen mode Exit fullscreen mode

However, CSS has gained some friends. Equally popular are things like LESS and Sass. These are considered CSS pre-processors. They take basic CSS and extend the available syntax so you can include variables and nested rules (and more) directly in your style files.

$brand-color: #fc3;
a {
    color: $brand-color;
}
nav {
    background-color: $brand-color;
}
Enter fullscreen mode Exit fullscreen mode

This is an example of Sass syntax

As an aside Sass used to be its own language. After version 3 it was made to be compatible with CSS, so modern Sass is really SCSS and uses the file extension .scss. Oh, and both still exist and some people prefer to use the original Sass syntax, so watch out for that. Fun times!

Specificity and Selectors

One of the important things to understand about styles is that they are designed in a way that allows developers to apply them at whatever level is most efficient. Since there are so many HTML elements on a page choosing a style that affects all headers, or all buttons, is a lot easier than having to style each one individually. CSS handles this by using selectors that map styles to elements. There are three types of selectors.

  • Type selectors
  • Class selectors
  • Attribute selectors
  • Id selectors

There are also universal selectors, but those do not have an effect on specificity

Selectors can be used in combination in a variety of ways. The first is by using multiple selectors to increase the specificity of the element you're mapping to.

a {
    color: black;
}

a.thanos {
    color: purple;
}
Enter fullscreen mode Exit fullscreen mode

Combined with this HTML, what color will the link be?

<a class="thanos" href="/"> Click Me! </a>
Enter fullscreen mode Exit fullscreen mode

The link will be purple! This is because it has the class name thanos, giving it two selectors. The a tag style we have uses only one selector to map to an element, so the thanos rule is more specific and wins out.

Using this type of specificity you can make all links on the site black and still decide that one link on one page should be purple. However, what happens if you try and do this?

a {
    color: black;
}

.thanos {
    color: purple;
}
Enter fullscreen mode Exit fullscreen mode

There is only a single selector in both cases, so presumably, the styles will clash. However, CSS has rules for which style it will listen to. This is the second way that selector specificity comes into play. The order of operations is id selectors are the most specific, next is class selectors which are tied with attribute selectors, then tag selectors.

Mozilla has more in-depth explanations on this if you're interested. Note that you can use both of these specificity concepts in combination.

Inline styles

Ok, next layer! Thus far I've been operating on the assumption that all of the CSS is included in some stylesheet or another. However, styles can be dictated directly in HTML. However, this overrides the styles in the project's stylesheet for that element. That's because inline styles are considered more specific according to CSS.

return (
    <h1 style={{ margin: 0, flex: 1 }}>
        LAURIE             
    </h1>
)}
Enter fullscreen mode Exit fullscreen mode

Many consider inline styles poor practice. The reason for that is because of this specificity issue. Having styles get overridden without realizing where, because you've written them at a lower level, can get confusing quickly. In addition, inline styles normally force you to write far more CSS because you are individually styling elements that may repeat and share styles.

I think I know where this style came from?

There are lots of permutations of these style layers. And part of the challenge of CSS is that any given style can be produced in numerous different ways. It matters where you put your styles, what triggers them, etc. But knowing the right layer to work in will help you keep things straight. And if you have trouble remembering keep this handy dandy cheat sheet in your back pocket.


If you're looking for other content like this check out:
Don't Get Fooled By Errors
Online Learning Tips and Tricks
My Series on Gatsby and GraphQL

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .