Arrow Down Arrow Left Arrow Right Arrow Down Arrow Left Arrow Right Arrow Arrow Down Arrow Left Arrow Right Articles Case Study Close CV Facebook GitHub Google+ Menu Information Link LinkedIn x five Interview Location Code Snippet Twitter Tick

ITCSS: Scalable and Maintainable CSS Architecture

by Lubos Kmetko on February 10, 2016
Published in Web Development 20 Comments

How do I make my CSS scalable and maintainable? It’s a concern for every front-end developer. ITCSS has an answer.

Last year when we started to plan our HEROized redesign and new Xfive.co website, I was looking for a CSS architecture which would allow for easy website development and further maintenance.

CSS Modules were quite young and exotic at that time and I’ve always considered the Atomic Design chemistry analogy to be a bit artificial. Then I came across Harry Roberts’s ITCSS in the June 2015 issue of the net magazine and immediately fell in love with this simple, down to earth CSS approach.

What is ITCSS?

ITCSS stands for Inverted Triangle CSS and it helps you to organize your project CSS files in such way that you can better deal with (not always easy-to-deal with) CSS specifics like global namespace, cascade and selectors specificity.

ITCSS can be used with preprocessors or without them and is compatible with CSS methodologies like BEM, SMACSS or OOCSS.

One of the key principles of ITCSS is that it separates your CSS codebase to several sections (called layers), which take form of the inverted triangle:

ITCSS Layers

Those layers are as follows:

  • Settings – used with preprocessors and contain font, colors definitions, etc.
  • Tools – globally used mixins and functions. It’s important not to output any CSS in the first 2 layers.
  • Generic – reset and/or normalize styles, box-sizing definition, etc. This is the first layer which generates actual CSS.
  • Elements – styling for bare HTML elements (like H1, A, etc.). These come with default styling from the browser so we can redefine them here.
  • Objects – class-based selectors which define undecorated design patterns, for example media object known from OOCSS
  • Components – specific UI components. This is where majority of our work takes place and our UI components are often composed of Objects and Components
  • Utilities – utilities and helper classes with ability to override anything which goes before in the triangle, eg. hide helper class

The triangle also shows how styles represented by selectors are ordered in the resulting CSS: from generic styles to explicit ones, from low-specificity selectors to more specific ones (but still not too specific, IDs are not allowed) and from far reaching to localized ones.

ITCSS Key Metrics

Such CSS organization should help you avoid Specificity Wars and is represented by a healthy specificity graph.

Documentation

Update 10/27/2016: The net magazine has just republished the original article from the print version (see the resources below).

Normally, at this point I would refer you to the ITCSS webpage for further study. However, nothing like open source documentation exists.

ITCSS remains partially proprietary and if you want to fully utilize it, you should study the original introduction in the net magazine. I’m not here to judge author’s intentions (I’m thankful to him for sharing his knowledge), but I think this prevents ITCSS wider adoption (which might be the intention, after all).

The partially proprietary character of ITCSS prevents its wider adoption.

This shouldn’t prevent you from start to use it in your projects, though, if you are really interested in doing so. Get that particular issue of the net magazine to learn ITCSS fundamentals, and then study available online resources and examples to help you with its adoption in real-life projects.

Resources

I’ve used ITCSS on 4 projects so far (including Xfive.co) and the following resources helped me to get better understanding of it:

You can also check out Chisel, our Yeoman generator for front-end and WordPress projects, which supports ITCSS.

Experience

Here are a few thoughts based on my experience with ITCSS projects:

Less thinking on naming and styles location

ITCSS’s prescriptive nature especially when combined with BEMIT naming convention allows you to focus more on solving front-end challenges rather than thinking up names and styles location. This is what Xfive.co main.scss looks like:

@import "settings.colors";
@import "settings.global";

@import "tools.mixins";

@import "normalize-scss/normalize.scss";
@import "generic.reset";
@import "generic.box-sizing";
@import "generic.shared";

@import "elements.headings";
@import "elements.hr";
@import "elements.forms";
@import "elements.links";
@import "elements.lists";
@import "elements.page";
@import "elements.quotes";
@import "elements.tables";

@import "objects.animations";
@import "objects.drawer";
@import "objects.list-bare";
@import "objects.media";
@import "objects.layout";
@import "objects.overlays";

@import "components.404";
@import "components.about";
@import "components.archive";
@import "components.avatars";
@import "components.blog-post";
@import "components.buttons";
@import "components.callout";
@import "components.clients";
@import "components.comments";
@import "components.contact";
@import "components.cta";
@import "components.faq";
@import "components.features";
@import "components.footer";
@import "components.forms";
@import "components.header";
@import "components.headings";
@import "components.hero";
@import "components.jobs";
@import "components.legal-nav";
@import "components.main-cta";
@import "components.main-nav";
@import "components.newsletter";
@import "components.page-title";
@import "components.pagination";
@import "components.post-teaser";
@import "components.process";
@import "components.quote-banner";
@import "components.offices";
@import "components.sec-nav";
@import "components.services";
@import "components.share-buttons";
@import "components.social-media";
@import "components.team";
@import "components.testimonials";
@import "components.topbar";
@import "components.reasons";
@import "components.wordpress";
@import "components.work-list";
@import "components.work-detail";

@import "vendor.prism";

@import "trumps.clearfix";
@import "trumps.utilities";

@import "healthcheck";

Note: We use separate folders for each layer and load newly added stylesheets automatically in Chisel.

Objects reusability for fast development

ITCSS’ objects are perfect candidates for building a library of reusable components to allow fast front-end development.  UI parts would then be composed of generic objects and project specific components. For example, innuitcss as a generic ITCSS based framework contains a bunch of objects but only one sample component.

Animations

I recommend defining generic, global animations as objects too, eg. @keyframes o-fade-in in file _objects.animations.scss

Component specific animations should be defined in respective components files, eg. @keyframes c-hero-scale in _components.hero.scss.

Flexibility

ITCSS is quite flexible in terms of your workflow and tools. One of our developers expressed a concern about how much boilerplate ITCSS comes with. But in fact this is totally up to you - ITCSS doesn't prescribe that you need to have all layers present (only in what order they should be if they are present).

So in a minimal setup you can have just components with default elements styling coming from the browser. Of course, this is not very practical - some settings, reset and/or normalize CSS are used by almost everyone for good reasons.

Critical CSS

ITCSS plays nice with critical CSS due to the inverted triangle key metrics. The component based model allows you to separate above the fold UI into logical components so you can even pick parts of your critical CSS ‘manually’ (more on that in an upcoming article).

File size and styles duplication

If there is any concern with an architecture like ITCSS or basically any component like CSS architecture, it might be the resulting file size. Components encapsulate styles and allow us to avoid CSS conflicts and overrides but it also means that styles repetition can occur quite often.

ITCSS cannot compete with a functional CSS in this sense. On the other hand, if you find yourself repeating a lot of styling in components, you could consider moving those styles to separate objects.

Conclusion

You cannot go wrong with ITCSS. It’s the result of the experience and many years of work by Harry Roberts, one of the most renowned CSS authors out there. If you don’t mind digging into the resources a bit, you will be rewarded with a simple but powerful architecture which will allow you to create scalable and maintainable CSS for your small or big projects.

But don’t forget to keep an eye on other players like CSS modules, in the meantime.

--

Interested in more ITCSS?

  • ITCSS: A Year After - Five insights from the year with Inverted Triangle CSS.
  • Check out Chisel, a Yeoman generator for front-end and WordPress projects, which supports ITCSS.

About the author

Lubos Kmetko

Lubos Kmetko started to work for Xfive (formerly XHTMLized) as a front-end developer in 2006. He currently helps with business operations and writes for the Xfive blog.

More articles from Lubos

Comments

Nico February 18, 2016

Great roundup -- thanks for sharing!

As you mention, there are many objects that need to be included in the vast majority of your projects. Do you actually use the InuitCSS framework, or some alternative? I've been wondering if it's still getting attention ...

Lubos Kmetko February 18, 2016

Thanks, Nico!

We don't use InuitCSS. ITCSS was a new concept to us and we didn't want to make it too complex for the beginning. But certainly InuitCSS is a great inspiration.

Hien Dao July 14, 2016

Useful article, thanks for sharing!

Do you think we should locate the css files into folders instead of using naming prefix?
For example:
- settings/global.scss
- settings/colors.scss
- tools/mixins.scss
...
I think it will make the structure more clean, not too much css files in a folder.

Lubos Kmetko July 14, 2016

Thanks, Hien.

Yes, I don't see any problem with that, although Harry recommends flat structure. With folders you can use gulp-css-globbing and don't have to worry about importing every new file. I've used it here https://github.com/xfiveco/chisel-sample/tree/master/src/styles (that's just a work-in-progress demo of our new generator supporting ITCSS)

Martin July 21, 2016

Great article and for sharing the other articles related to ITCSS.

I'm starting to use (and understand) the ITCSS concept, applying the cssguidelin.es also from Harry Roberts, and adding Bourbon with Neat to build a solid foundation for a project we are working on.

Now that you're using ITCSS for a while, did the rest of your team were able to follow along? Did they found easy to add new components?

Cheers!

Lubos Kmetko July 21, 2016

Thanks, Martin, and good luck with ITCSS!

At the time, there were 3 of us working on the front-end of xfive.co, all new to ITCSS, but I didn't notice any major problems in following ITCSS. Slight disadvantage is lack of authoritative documentation so maybe it's worth to have have one team member who has more in-depth knowledge and can do basic setup and guide others if necessary.

Mgpeng August 10, 2016

Great article ! Thank you very much, I am using ITCSS in my project right now.

Lubos Kmetko August 10, 2016

Thanks, Mgpeng! And good luck with your project :)

Billy Halim September 9, 2016

I have something to tell about ITCSS of the layer order. It is about specificity. Going down the triangle, there will be more specificity in components, elements, and objects. At the tip of the triangle, there are trumps or helper classes. Let me give you example :

Element
table > tr > th{
border: 1px solid red;
}

Helper class
.border-blue{
border: 1px solid blue;
}

If we write , the won't have blue border because of specificity. Because of that, is it the principle of ITCSS to use Objects to solve this problem ?

Instead of writing table > tr > th, we can directly create a class named .table-header to avoid specificity.

Is it good ?

Thanks in advance.

Lubos Kmetko September 16, 2016

Hi, Billy, according ITCSS you can use !important in the trumps layer but I would be careful about using too many helper classes with the !important rule.

As you suggested it would be better to create a custom class based component for a custom table design. Also I would avoid using selectors like table > tr > th in the elements layer. If you want to override default browser styling for th, you can define it directly on the th element which will make applying styles from the components easier.

Jitendra Vyas October 20, 2016

What methodology you would choose today? Would you go for CSS Module?

Lubos Kmetko October 21, 2016

Hi Jitendra, we are still using ITCSS in our projects, in fact we now have a Yeoman generator which supports ITCSS - https://github.com/xfiveco/generator-chisel

I think CSS Modules like approach is most suitable in situations when you can have your other component related code (HTML, JS) at the same place too (for example like in Vue.js apps)

Steve tomlin November 28, 2016

I've adopted a similar approach during my tenure of 16 years of front end development. I have never given it a name. Experience has taught me the more layers the more complex and complexity should be avoided if possible, but the general steps outlined with a reset, common elements, re-usable objects and components keeps the code organised and dry where it can be. So i support about 80% of the reasoning behind 'itcss'. I'm not sold on oocss yet because i have spent a lot of my time doing dom manipulation to create new dynamic behaviour which is easier to do on single classes than several. It depends on the project.

gavin November 30, 2016

In what layer would you put helper classes?

Lets say I have a header component wit use javascript to stick it to the top once scrolled. I add .sticky class to it.... where would be the best place to place such classes

Lubos Kmetko December 1, 2016

@steve nice to see you've been using similar approach for many years, I'd say it's not surprising as ITCSS is a simple, common sense approach.

@gavin such classes should go into trumps or utilities layer (originally it was called trumps but if you check inuitcss framework, it's been renamed to utilities). Then you can call the class .u-sticky or you can use stateful class .is-sticky. ITCSS doesn't mention where to put stateful classes but the utilities layer seems to be the right place (unless you introduce a new layer called states). For more info on namespaces check http://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/

Bill December 12, 2016

Why don't you put Tools first and Settings second? Can you explain the benefit of having Settings first when Tools can work completely independent of Settings whereas sometimes settings will rely on Tools. Am I missing something?

Lubos Kmetko December 13, 2016

@bill the original ITCSS article says "The Tools layer comes after the Settings layer because a mixin may require one of the global settings as a default parameter." However, I think that if this is not your case, you can switch their order if that suits your needs better. The beauty of ITCSS is its simplicity and flexibility with just a few simple rules to follow.

Thomas Goemaere December 28, 2016

Where do third party dependencies like fancybox, photoswipe, slick, ... fit into the ITCSS architecture?

Andrew January 2, 2017

I am just afraid, that in a long run, all CSS will end up in the "Trumps".

Lubos Kmetko January 9, 2017

@thomas we usually install and import those from npm modules but if you download and uses files directly, you can put them into a separate layer called 'vendor'

@andrew that's possible if ITCSS isn't used properly. To avoid this I would try to use independent components as much as possible.

Would you like to add something?

All fields are required. Your email address will not be published.

Check out 6 reasons why our clients keep coming back

Partner with us

More from the blog

Submit a Project