How To Solve Large-Scale CSS Bottlenecks with ITCSS and BEM

Published on December 12, 2019

    Peter Ekene

    How To Solve Large-Scale CSS Bottlenecks with ITCSS and BEM

    While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

    ###Introduction On frontend codebase projects, requirements and sometimes scopes can change frequently. When requirements change and you adjust the stylesheet or extend the styles of a selector in a particular page, such changes often affects other views that share similar styles.

    This may lead to many hours of specificity wars while trying to override styles. That happens because the project was not structured in a proper way that would ensure that changes to the stylesheets would not have a negative impact on the entire project. In this tutorial, you’ll see how to combine Block Element Modifier (BEM) CSS with Inverted Triangle CSS (ITCSS) to avoid problems.

    Common Difficulties Faced while Working with CSS

    CSS as a language has a few issues that make managing it a bit difficult for developers.

    • It is declarative, meaning that it does not have a control flow that tells you the state of a project.
    • Everything exists on the global scope, making style collisions possible.
    • There is also the issue of specificity, which determines the style that is being applied to a particular selector.

    These issues become much more evident when a project grows and more developers are working in the same codebase. If proper structures are not put in place, then changes to the stylesheets tend to become unpredictable.

    In order to properly structure CSS in a way that would help us avoid these issues, Harry Roberts created “Inverted Triangle CSS (ITCSS)”. It is a methodology that can help us structure CSS in such a way that they behave in a more predictable manner. It was designed to help developers working in large scale projects to better organize and manage their CSS.

    According to Harry, ITCSS is a collection of principles and metrics by which developers should group and order their CSS to keep it scalable, terse, logical, and manageable. It’s a methodology that involves visualizing a CSS project as a layered, upside-down triangle. This hierarchical shape represents a model that will order CSS by metrics defined by the design of the language with better scalability and maintainability than we’d get if we were to write CSS around how a person thinks.

    ITCSS is also flexible and can be used with or without preprocessors. It is compatible with other CSS methodologies like BEM, SMACSS or OOCSS. As we progress in this tutorial, I will show you how you can use ITCSS with BEM.

    Basic Principles of ITCSS

    No IDs in CSS

    IDs have high selector specificity and this can make it difficult to override styles. To override an ID, we add more IDs or use !important, which can begin specificity wars in your stylesheets. Overriding and extending styles shouldn’t be difficult so as to make your CSS maintainable and pleasant to work with.

    Component UI Pattern

    A component is a collection of reusable markups usually with some logic and styling. Components are self-contained and they serve as building blocks of modern frontend technologies: React, Angular, Vue, Ember, etc. ITCSS favors componentized UI architecture over pages.

    Class-Based Architecture

    A good CSS architecture is one that is reusable and flexible. ITCSS favors the use of classes since they can be used multiple times on the same page and multiple classes can be placed in a particular element. Classes also make HTML easier to read.

    Key metrics of ITCSS

    ITCSS orders your project using three key metrics.

    Generic Styles to Explicit Styles

    Start out with generic, high-level and far-reaching selectors and then gradually proceed to explicit and more specific selectors. You can start with browser reset rules and then proceed to element selectors and right through to explicit rules such as btn-primary.

    Low Specificity to High Specificity

    Every CSS rule has a specificity weight which means that it could be more or less important than the others or equally as important. This weight defines which properties will be applied to an element when there are conflicting rules. Keeping less specific rules at the top and high specific rules under them ensure that your styles cascade properly to avoid conflicts and specificity wars.

    Far-Reaching to Localised

    At the start of a project, CSS rules affect a lot of the DOM, but as we progress through the project the rules affect less of the DOM and become more specific to components. We might start by wiping the margins and paddings off everything. Next, we might style every type of element, then narrow it down to every type of element with a certain class applied to it, and so on. It is this gradual narrowing down of reach that gives us the triangle shape.


    Following these three key metrics has a lot of benefits, to mention a few:

    • Global and far-reaching styles are shared more effectively and efficiently.

    • The probability of specificity wars is reduced since CSS is written in a logical and progressive order in terms of specificity.

    • CSS becomes more extensible and redundant styles are avoided leading to lesser file sizes, and latency.

    • We spend very little time undoing things because our cascade and specificity are all pointing in the same direction

    ITCSS Layers

    Breaking our CSS into layers helps us stick to the above mentioned metrics. Each layer is added in a location that aligns with the metrics. Each layer is usually a logical progression of the previous layer. As we progress through the layers, explicitness and specificity increases and the reach of the selectors are narrowed.

    This means that CSS becomes easier to scale since we are writing it in an order that only adds to what was previously written. It also means that everything has its own predictable location to live, which makes it easier to find and add styles.

    ITCSS has seven layers which we would take a closer look at here:


    This is the starting point when using CSS preprocessors. It contains global variables that can be accessed from anywhere within your CSS project. Examples of global settings are font sizes and colour definitions.


    This contains global functions and mixins and it comes after the settings since the mixins and functions might need access to global settings. This layer is the second layer if you are using preprocessors. Examples are font-size mixins px-to-rem mixins, etc. It is important to avoid writing actual styles in the first two layers.


    This is the point where actual CSS is written and it is also the starting point if you are not using a preprocessor. It contains styles such as CSS reset roles, global box-sizing rules, and CSS normalising rules. The styles here affect much of the DOM.


    This layer contains element selector styles. It contains styles for bare and un-classed HTML elements. Styles for form, heading, img, links and table elements also come in here. Styles here are still very low-specificity but affects slightly less of the DOM.


    This is the first layer with class-based selector. It contains styles for non-cosmetic objects such as containers, wrappers and layout systems. This layer affects less of the DOM than the last layer, has a higher specificity, and is slightly more explicit given that we are now targeting specific sections of the DOM with classes.


    This layer holds the style for each component in your project. It’s more explicit than the previous layer because we are now styling visible UI elements. 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.


    This layer beats other layers. This is where utility and helper styles are defined. It is specificity heavy, can override previous styles and is the tip of the triangle. Most of the styles here contain the !important flag.

    The result

    When all the layers are combined together, it could look like this.

    // main.scss
    @import "settings.fontsize";
    @import "settings.colors";
    @import "tools.functions";
    @import "tools.mixins";
    @import "generic.reset";
    @import "generic.normalize";
    @import "elements.forms";
    @import "elements.table";
    @import "objects.contianer";
    @import "objects.grid";
    @import "components.site-nav";
    @import "components.buttons";
    @import "components.carousel";
    @import "trumps.clearfix";
    @import "trumps.utilities";

    Using BEM with ITCSS

    Block Element Modifier(BEM) is a methodology for naming CSS styles. According to Getbem, BEM is a highly useful, powerful, and simple naming convention that makes your front-end code easier to read and understand, easier to work with, easier to scale, more robust and explicit, and a lot more strict.

    BEM is particularly useful for the six and seventh layer of ITCSS where class-based selectors are heavily used. Following BEM would ensure that classes are properly named for better readability.

    Exemplifying the BEM Methodology

    B (Block) A block is a top-level node, the highest level abstraction of a component. It is a standalone entity or a component, on a web page.


    .btn {

    E (Element) Elements are children of a block. They have no standalone meaning and are semantically tied to a block. Elements are prefixed with their block name and a double underscore.


    .btn__text {
    .btn__icon {

    M (Modifiers) Modifiers are used to change the appearance of a block or an element. They provide us with a way of creating variations of blocks and elements rules.

    .btn--lg {
    .btn__text--light {
    .btn__icon--right {


    When there is a need for change in your codebase, you don’t want to spend time overriding styles and fighting specificity wars. The inverted triangle architecture makes sure that there is no war by helping you visualize the state of your entire codebase in simple terms.

    Following its principles helps create a system that is approachable, predictable, guessable, rule based, prone to smaller file sizes, and geared toward scalability and growth.

    If you’re working on a front-end project that makes heavy use of CSS, i would recommend using ITCSS with BEM so as to make your code easier to read and understand. This will not only ensure good maintenance of the code but also promote empathy for incoming developers.

    Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

    Learn more about us

    About the authors
    Default avatar
    Peter Ekene


    Still looking for an answer?

    Ask a questionSearch for more help

    Was this helpful?
    Leave a comment

    This textbox defaults to using Markdown to format your answer.

    You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

    Try DigitalOcean for free

    Click below to sign up and get $200 of credit to try our products over 60 days!

    Sign up

    Join the Tech Talk
    Success! Thank you! Please check your email for further details.

    Please complete your information!

    Featured on Community

    Get our biweekly newsletter

    Sign up for Infrastructure as a Newsletter.

    Hollie's Hub for Good

    Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

    Become a contributor

    Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

    Welcome to the developer cloud

    DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

    Learn more
    DigitalOcean Cloud Control Panel