The best CSS methodologies for scalable e-commerce frontends

Let’s be honest – CSS can quickly turn into an unmanageable mess if not structured properly. Ever struggled with overriding styles, tangled selectors, or bloated stylesheets? Not only you. That’s where CSS methodologies come in.

The right approach can make your styles scalable, maintainable, and predictable. But with so many options – OOCSS, BEM, SMACSS, Atomic CSS – how do you know which one fits your project best?

In this guide, we break down the most popular CSS methodologies, showing their strengths, weaknesses, and when to use them. Let’s dive in.

What are CSS methodologies?

CSS methodology is a set of guidelines, principles, and best practices for writing and organizing CSS to improve maintainability, scalability, and readability. It helps prevent:

  • Styles that are too tightly coupled to HTML, making updates painful.
  • Specificity nightmares that make styles impossible to override.
  • Bloated stylesheets filled with redundant or unused rules.

Modern e-commerce frameworks tend to use a CSS framework or library that already implements one of these methodologies. When working on such a platform, it is usually best to reuse existing CSS rules and, when needed, add new ones while adhering to the principles of the current methodology.

However, sometimes – such as when preparing a storefront from scratch – we can decide which CSS methodology to implement. Knowing the strengths and (sometimes) weaknesses of the most common CSS methodologies can help in choosing the one best suited to meet the project’s needs.

The most popular CSS methodologies (and when to use them)

Each methodology has its own philosophy, strengths, and trade-offs. Let’s go through the major ones.

In order to understand the differences between CSS methodologies, let’s look at a basic html of a button element with some text and icon inside and implement some styling to it by using some of the most popular CSS methodologies:

<button>
    <span>Click me!</span>
    <svg>...</svg>
</button>

OOCSS (Object-Oriented CSS) – reusability first

It focuses on preparing multiple classes in such a way that they can be as reusable as possible. Its core principles require separating structure from skin and separating container from content. When implemented, the HTML of a button could look like this:

<button class="button-primary button-structure"> 
 <span class="button-text">Click me!</span>
 <svg class="button-icon">...</svg>
</button>

In this example, the classes are used in the following way:

  • .button-structure consists of generic button styles that are common for multiple types of buttons, such as border, padding, and margin
  • .button-primary includes specific styles for the button, such as background and :hover rules
  • .button-text contains rules targeting button text, including color, font-size, and letter-spacing
  • .button-icon handles icon size and positioning

This way, when trying to change the appearance of the button, the intended OOCSS approach is to add new classes to the HTML elements or replace the existing ones.

For example, to change the button’s background-color property, we would need to replace the button-primary class with button-secondary. If there was a third variant of the button that had not yet been prepared, we would need to add and style a new .button-* class accordingly. Naturally, as you can see, the more variations are needed, the more classes must be prepared in the CSS.

Why use OOCSS?

OOCSS’s main strengths are reusability, scalability, maintainability, and ease of debugging. For newcomers to a project, it may take some time to get familiar with all the classes and their usage, but for experienced developers, it significantly reduces styling time. Overriding styles are minimized, which leads to better performance and faster load times.

OOCSS works very well with large, scalable projects but may be overkill for small ones that don’t have many reusable elements.

Downsides of OOCSS

The “separating container from content” principle may sometimes be challenging. For example, if HTML content is provided by an admin panel, it must also be styled. In such cases, a decision has to be made:

  • Some exceptions are introduced, where rules like .box-content p {…} are allowed.
  • Additional logic handles WYSIWYG and assigns specific class names to corresponding HTML elements.

Atomic CSS – tiny, reusable utility classes

Atomic CSS focuses on writing small, reusable utility classes, each with only a single style rule. The class list of a button using Atomic CSS would be significantly larger:

<button class="bg-green px-2 py-1 rounded">
 <span class="text-white text-bold">Click me!</span>
 <svg class="mr-1 w-16 h-16">...</svg>
</button>

    Why use Atomic CSS?

    As you can see, each class corresponds to a single style rule, and class names are structured generically, where each name refers to its specific style property. This results in an extremely small CSS file but at the cost of a larger number of classes applied to each HTML element.

    This approach ensures that each class is reusable, speeds up development, and encourages consistency. Since there’s no deep nesting, styles don’t override each other unpredictably.

    Downsides of Atomic CSS

    However, this comes at the expense of HTML readability, as having many classes in each DOM element can make it harder to scan visually. As with OOCSS, sometimes adding a new CSS rule may be necessary, requiring extra caution to stay consistent with the methodology.

    Atomic CSS works well with “Atomic Design” methodology, where the UI is broken down into Atoms, Molecules, Organisms, Templates, and Pages for better reusability and maintainability.

    BEM (Block, Element, Modifier) – structured naming

    BEM (Block, Element, Modifier) focuses on class naming conventions and provides a structured way to create CSS classes for components, ensuring clear and consistent relationships between HTML and CSS. It encourages developers to separate the HTML structure into reusable components.

    The BEM structure, as the name suggests, is organized in the following way:

    • A block is the outermost wrapper of a component, representing a distinct part of the UI. Its class name should describe its purpose, for example, .header, .form, etc.
    • An element is a part of a block that cannot exist independently. Elements are descendants of blocks and are separated by a double underscore: .header__list, .form__input.
    • A modifier defines different states or variations of a block or an element (e.g., a different color, size, or theme).

    Modifiers are attached to blocks or elements and are separated by a double hyphen: .header–small, .form–sidebar.

    <button class="button button--primary">
     <span class="button__text">Click me!</span>
     <svg class="button__icon">...</svg>
    </button>

    Elements shouldn’t exist without their parents, which makes BEM’s concept different from OOCSS and Atomic CSS – “the components are reusable, not their individual parts.”

    The BEM methodology relies on a consistent and strict naming convention, which can be challenging to maintain without proper guidelines. It may also be harder to use for people who aren’t experienced in writing CSS.

    Combining BEM with other methodologies is encouraged, where, for example, reusable components use BEM and small, individual elements use OOCSS.

    SMACSS (Scalable and Modular Architecture for CSS) – a flexible approach

    SMACSS (Scalable and Modular Architecture for CSS) provides a flexible and scalable approach to organizing styles in large web projects.

    It is designed to help developers manage and maintain CSS in a modular way, improving both reusability and scalability.

    SMACSS doesn’t prescribe strict naming conventions like BEM, but it focuses on creating a clear structure for categorizing CSS rules based on their purpose.

    SMACSS organizes CSS rules into five categories:

    • Base Styles – default styles for basic HTML elements like body, h1, a, etc. They typically include things like typography settings, font sizes, and link styles that are applied universally across the website.
    • Layout Styles – responsible for defining the overall structure of the page (e.g., grid systems, positioning). These rules are for larger structural elements like headers, footers, and sidebars.
    • Module Styles – for reusable, self-contained components (e.g., buttons, forms, cards). These are typically smaller UI pieces. Each module can have its own set of rules, and these rules are designed to be reusable across different parts of the site.
    • State Styles – describe the variations of elements based on their state, such as active, hover, or disabled states. These styles help modify the appearance of a module or layout element when it is in a certain state.
    • Theme Styles – define the overall theme or appearance of the website, like colors, fonts, and overall aesthetic. These styles can be easily swapped out for different themes (e.g., light/dark modes). Theme styles are often applied globally or at the root level to change the look and feel of the entire site.

    Unlike BEM, SMACSS doesn’t impose strict naming conventions, so the styles of our button would be divided into theme, state, module, and base styles.

    Conclusion

    The methodologies presented here are just a few among many available options. Other well-known approaches include ITCSS, CSS-in-JS, and DoCSSa, each offering unique strategies for handling styles in large and complex projects.

    The key takeaway is that there is no one-size-fits-all solution. What works best for your project largely depends on its specific needs, your team’s workflow, and the scale of the project. Some methodologies prioritize reusability, others focus on scalability or flexibility, and some aim to simplify the development process.

    The most important factor is to choose the methodology that works best for you and aligns with the specific requirements of your project. By doing so, you can ensure that your code remains maintainable, scalable, and efficient as the project grows.

    Table of Contents