You’re assigned with a small task to fix some little styling issues here and there. You found the correct css rules to apply the fix, you quickly drop those rules at the bottom of your css file, push your changes and then move on with more important stuff. Over time this happens a couple of times and before you know it “the bottom” of your css file consists of a few hundred lines of css that nobody understands and nobody dares to remove as it will inevitably break stuff.
Recognize this scenario because you either did this yourself or you saw colleagues do this? Well, lets read on and promise yourself that you will never do this again, because here’s an easy way to manage your css files.
Introducing the Inverted triangle architecture
The Inverted triangle architecture, also know as ITCSS, is a methodology for structuring your css in the most effective and least wasteful way. ITCSS was first introduced by Harry Roberts and can be best visualized by an upside-down, layered triangle. ITCSS defines the shared css-rules of a project in logical and sane manner, whilst also providing a solid level of encapsulation and decoupling that prevents non-shared css-rules from interfering with one another. ITCSS is very flexibele as it does not force you to use any specific naming convention methodologies like SMACCS, OOCSS or BEM.
ITCSS works by structuring your entire css project according to these 3 principles.
- Generic to explicit
We start with the most generic, low-level, catch-all styles. This could be font settings or for example color variables if you’re using scss.
- Low to high specificity
The lowest specificity selectors appear at the start of your project. The specificity steadily increases. This way we avoid specificity conflicts and specificity overrides using !important.
- Far-reaching to localized
Selectors at the start of our project affect a lot of DOM-elements, for example your browser reset styles, while selectors later in our project become very localized, for example specific styles for one component.
The triangle layers
Sticking to the above principles means we have to break up our css into layers. Each layer must be introduced in a location that honors each of the criteria. It happens often that css is grouped by for example typographic styles, form styles and styles for a specific component. These groups are often not imported in the most efficient order and thus creates some inheritance or specificity problems.
In ITCSS each layer is a logical progression from the last. It increases in specificity, narrows in reach and get more explicit. This means our css is easier to scale as we’re only adding to what is already there and not override what was previously written. Another big advantage of following this structure is that everybody always knows where to find certain css-rules as they’re logically placed. This avoids that people drop their css-rules at the bottom of the file.
ITCSS as created by Harry Roberts has Seven layers. He ordered them as follows:
If you’re using a preprocessor like scss this is your starting point. In this layer you define your variables.
This layer can be used for your tooling. Think about mixins and functions that need to be globally available. If they don’t need to be, just place them in the layer where they’re needed.
In this layer we house all the very high-level, far reaching styles. This layer is often the same across all your projects as it contains things like Normalize.css, css resets and for example box-sizing rules.
In this layer we put styles for bare, unclassed HTML elements. You could for example think about underlines for anchors on hover or font-sizes for the different headings.
In the object layer we style the first elements that have classes. Think about your containers, wrappers or rows. You can also define your grid here.
The component layer is the place where most of styling magic happens as you will be styling your ui elements here. In component based frameworks like Angular, Vue or React this is the layer where you import your styling for each component if you don’t include them directly in your component.
The trumps layer is the dirty layer. Even after structuring your styling according to the ITCSS principles it can happen that you have to use !important to for example override some third-party styling. Do that in this layer as this is the most specific, local and explicit layer.
The end result
Now that i’ve explained the layers it’s time to look at how a simple end result could potentially look.
// settings @import "globals"; @import "branding";
// tools @import "mixins";
// generic @import "normalize";
// elements @import "fonts"; @import "form";
// objects @import "grid"; @import "wrappers";
// components @import "header"; @import "sidebar"; @import "carousel"; @import "card";
// trumps @import "overrides";
Just as ITCSS doesn’t force you to use a certain naming convention, it doesn’t force you to use all layers. Use a layer structure that works best for you while maintaining the ITCSS principles of generic to explicit, low to high specificity and far-reaching to localized. If you notice that you have to override styles it almost always means your structure is inefficient. If you feel like learning more about this, i recommend to watch this video:
Thanks for reading. Any feedback? Let me know. Also check my other articles: