In large CSS projects, it is very important to create a scalable and clear structure. And because the offerings are manifold when it comes to CSS frameworks, we want to have a closer look at ITCSS from Harry Roberts.
What is ITCSS?
ITCSS is a scalable meta framework for CSS which was firstly coined by Harry Roberts. ITCSS stands for “Inverted Triangle CSS” and refers to the inverted order of the specificity of all CSS rules within a stylesheet. The specificity of a CSS rule can be calculated by adding the specificities of all selectors of a CSS rule. As an example,
body #content .data img:hover has a specificity of 122: #content 100 + .data 10 + :hover 10 + body 1 + img 1. The specificities of single selectors are:
- Universal selector *: 0
- HTML elements and pseudo elements: 1
- Classes, pseudo classes and attributes: 10
- IDs: 100
- Inline styles: 1000
- !important has an “infinite” specificity
The two classical ways to organize CSS are mirroring the website structure and grouping by topic. But those approaches both has the disadvantage of creating an unstructured specificity graph, as you can see in the screenshot. To render the design the browser must jump through the code to get the correct cascade, which is both not very performant as well as difficult to maintain.
To get rid of the overhead and get more performant CSS, we want to order our style by the specificity ascending, thus getting a much nicer specificity graph. Now the browser already has the correct cascade and is able to calculate any styles much faster. Minimal ups and downs within the specificity graph are tolerable as long as the graph is steadily rising. Using the specificity we should get an ideal order like this: first all HTML and pseudo elements, than all classes, pseudo classes and attribute selectors, and at least all IDs or rules with an !important in it.
With ITCSS we sort our CSS by specificity ascending so that we will get a correct cascade and thus a performant CSS.
Technical structure with ITCSS and Grunt
After explaining the mechanics of ITCSS we will now have a look at the technical realisation of such a structure. We will use Grunt as a task manager to compile multiple LESS files, extract the media queries and concat all extracted files into one optimized stylesheet.
First, we will created several directories, for each ITCSS layer one:
- Settings: LESS or SASS variables. It would be considered a best practice to split all settings into multiple files: one for colours, typography, gridss and so on.
- Tools: Mixins of all kind. Here you can store clearfixes, reoccurring styles for buttons or grid systems. N. B. including this layer no CSS was created yet!
- Generic: Styles like normalize or resets. In this layer we will create our first lines of CSS.
- Base: simple HTML elements. Consider to split your styles into files for single topics, like headings, tables or forms.
- Objects: class based, non-design related styles. Here you can find styles like visibility helpers, grid systems and so on.
- Components: class based, design related styles. These styles will define menus, widgets and other design elements.
- Trumps: no, this layer has nothing to do with the current american president – lucky us! Here we will store overwrites for external libraries or CSS rules with !important in it.
As soon as the structure is ready, we can start with our Grunt tasks. We will use clean to clean up old files, concat to merge multiple files, less (or sass) for compilation and cssmin for minification. After all these optimizations we should get an optimized stylesheet according to ITCSS rules.
A word about external libraries
In modern day web development, frontend libraries like Twitter Bootstrap or Zurb Foundation is common sense. In case you wonder if it is possible to use such libraries within ITCSS: yes, of course! We would recommend to use the LESS/ SASS variants of the library of your choice (if available). Additionally, never include a style rule from the library. A better way would be to use library mixins within your own styles. Thus, you will not disturb the specificity graph of your stylesheet with external styles not under your control.
And what about Media Queries?
Because media queries are overwriting already existing styles, it is a best practice to put all media queries at the end of your stylesheet. To achieve that we already mentioned Grunt. The mqe task (Media Query Extractor) will extract all media queries from our compiled LESS files and write them into a base file and several other files, for each breakpoint one. Afterwards wen can use concat to merge them back together in the correct order. And because you wrote your media queries where your base style was, all styles within your media query will follow the ITCSS method automatically.
After creating our basic file structure, we will use Grunt tasks to optimize our styles even further: we will compile our LESS/ SASS, extract all media queries and concat the resulting files into one single stylesheet. This file will be finally minified.
To create clean structured and performant stylesheets, ITCSS is a very good tool. It can be combined with other methods like BEM or OOCSS and is scalable for every kind of project. In combination with techniques like Progressive Enhancement or Critical CSS we will be able to create highly maintainable and performant stylesheets for or online shop or website very quickly.