The larger the CSS project becomes, the more important it is to create a scalable and, above all, clear structure. Since there are many different approaches to this problem in the CSS environment, we would like to look at ITCSS by Harry Roberts in this article.
What is ITCSS?
ITCSS is a scalable meta-framework for CSS, which was first introduced by Harry Roberts. ITCSS stands for "Inverted Triangle CSS" and refers to the sorting of CSS instructions in ascending order of CSS Specificity. The specificity is the value of a CSS instruction and is calculated by adding the values of all selectors of an instruction. As an example, the statement
body #content .data img:hover has a specificity of 122: #content 100 + .data 10 + :hover 10 + body 1 + img 1. The individual selectors have the following values:
- 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 classic ways to structure CSS are either to mirror the web page structure (styles for the header, then content, then footer) or to group them thematically (all form styles, all media styles, blog posts, etc.). However, the problem of specificity arises: the browser must constantly jump back and forth to the display in order to be able to apply the correct cascade of styles. The resulting specificity graph looks something like this:
To minimise the resulting overflow and redundancies, we roughly sort our styles by specificity to get a much cleaner specificity graph. "Roughly sorting" in this case means that we try to maintain a steadily increasing graph, we can tolerate minimal fluctuations. This means that (in an ideal world) we first arrange all HTML elements, then all classes, and finally all IDs and statements with a !important underneath each other. The styles are thus sorted from general to specific, from far-reaching to local.
Our graph should now have roughly this shape:
With ITCSS we sort our styles by ascending specificity to get a tidy, non-redundant CSS.
Technical structure with ITCSS and Grunt
Now that the functionality of ITCSS has been explained, it's time for the technical implementation. With the help of LESS and Grunt, a technically clean and clear solution can be implemented, which we would like to present here.
As you can see in the screenshot, in our example we have created the individual ITCSS layers as directories in the template directory. In this structure we can now create individual files for different tasks for a better overview. For example, the screenshot shows a style file for media, one for forms and one for typography. The idea behind this is that all files in a directory always have the same specificity. As a best practice, it is advisable to combine all files of a directory in an _all.less file and then collect these collective files in the theme.less file. An exemplary structure according to ITCSS would be this:
- Settings: LESS or SASS variables. It would make sense here to divide up, for example, one file for colours, fonts, grid dimensions and so on.
- Tools: Mixins of all kinds. Here, for example, clear fixes can be saved or styles that can be applied to several other elements. Note: no CSS is created up to this level!
- Generic: basic styles such as normalize.css, resets or box-sizing are stored here. CSS is actually generated from this layer onwards.
- Base: simple HTML elements. Individual files for forms, media (images, videos), typography or tables are suitable here.
- Objects: class-based, non-design-relevant styles such as a grid system can be found here.
- Components: class-based, design-relevant styles. Menus, widgets or other design-specific formatting can be found here.
- Trumps: no, this layer has nothing to do with the American president. Alternatively, call it Overwrites or Peaks: here you collect all IDs, overwrites for used libraries or statements that use !important.
Now that we have structured our files in this way, it's time for further processing using Grunt. Several grunt tasks are needed for this: clean cleans up our earlier compiled files, concat combines several files, less compiles our LESS files into CSS and cssmin minimises the finished CSS. Since we stuck to the ITCSS structure, our CSS should now have a correspondingly tidy Specificity Graph.
General notes on the use of libraries
Libraries like Twitter Bootstrap or Zurb Foundation have found their place in web development. However, it is important to consider which components are actually needed and whether it is worthwhile to integrate the entire library. From our experience, this is usually not the case. Since in most cases there are also LESS or SASS versions of the libraries, you should try to integrate these versions directly at the right place in the ITCSS tree.
Of course, it is best to use mixins instead of the ready-made styles, if the library used provides them. Zurb Foundation, for example, offers mixins for many of its components, so that you can include them in the Tools layer and then use them in the respective layer (usually Objects or Components) in your own styles.
A word about media queries
Since media queries overwrite existing CSS instructions, it is good practice to place them at the end of each CSS file. Whether you work with progressive enhancement and min-width or with graceful degradation and max-width is irrelevant for the time being (although we would recommend progressive enhancement). But how can the media queries, which under normal circumstances are scattered throughout the LESS source code, be integrated cleanly into ITCSS?
With the help of the basic task mqe (Media Query Extractor), we can extract all media queries from our finished CSS into separate files. For example, we get a file for the 768px breakpoint, the 992px breakpoint and so on. We can now assemble these additional files again using the basic concat task in the order we want (with the media queries at the end) and thus obtain a CSS file in which first all the normal styles are sorted according to specificity and then all the media queries are listed in ascending order and also sorted according to ITCSS. Finally, everything can be minimised and integrated as usual.
After our files have been structured in ITCSS-compliant directories, we can optimise them using Grunt: all files are combined and compiled, media queries are extracted from the resulting CSS and finally merged into a final CSS file and minimised.
ITCSS is a powerful tool for creating high-performance and clearly structured stylesheets. ITCSS can be used with other methods such as BEM without any problems and is scalable as desired. In combination with other techniques such as progressive enhancement or optimisations such as critical CSS, you are able to quickly create high-performance and, above all, maintainable stylesheets for your own online shop or website.