The Component, Element, Modifier Design Pattern

The Component, Element, Modifier pattern increases the reusability and maintainability of CSS code by scoping CSS styles to particular components through the use of class naming conventions.

Problem

CSS can easily get out of hand on large projects if not managed properly. As a project grows, often so does the length of selectors—creating ongoing specificity wars in which one style overrides another which overrides another and so on and so on. The resulting over-specified selectors make these styles nearly impossible to reuse as they become more and more tightly coupled to the HTML in which they were originally styled. This leads to fragile styles and unpredictable results when future changes need to be made.

Solution

The Component, Element, Modifier pattern helps mitigate these issues of over-specified selectors and style contamination through naming conventions—making styles more modular and reusable. This pattern aims to reduce specificity across selectors, instead relying on unique class names to scope styles to DOM elements.

Note 'reduce' not 'eliminate' specificity. Specificity and the cascade are essential tools in the CSS developer's toolbox. The goal is not to get rid of them, just manage them better.

Traditional programming languages implement some sort of scope that prevents variables from getting cross contaminated. CSS is not a programming language. It is a stylesheet language. It does not have variable scope. Instead, scope refers to the elements for which a given ruleset applies. In CSS, scope is controlled by selectors and the cascade. The selector p {} is scoped to all paragraph tags. .nav > li {} is scoped to all li elements that are direct descendants of elements with the nav class.

Component

A component is an independent chunk of styled HTML that can be added to any region of a page while maintaining its visual style. The outer most wrapping element of a component is refered to as the Base Component. It includes a CSS class named after the component itself. This is referred to as the Base Class. For example: a search component might have a base class of search.

Element

Elements are the individual HTML elements that are combined to create a component. Each element includes a CSS class which is a derivative of the base class name. For example: a search component has an input field with a class of search__input and a submit button with the class of search__button.

Modifier

Modifiers are classes that alter the appearance of the base component by adding additional styles or overriding the base component's defaults. Modifiers are typically named after the base component, however certain types of modifiers can use their own naming conventions, for instance the state classes in SMACSS.

For clarity, choose a different naming convention than that used for elements so modifiers and elements are easily distinguishable. For example: a search component might have a modifier class of search--inline which sets the input and button on a single line as opposed to the default stacked layout.

In most cases a modifier is applied via additional classes added to the base component. In some cases a modifier may be applied via a CSS preprocessor such as SASS's extend directives.

Example

<ul class="nav">
  <li class="nav__item">
    <a class="nav__link" href="/" >Home</a>
  </li>
  <li class="nav__item">
    <a class="nav__link" href="/about" >About</a>
  </li>
  <li class="nav__item">
    <a class="nav__link" href="/contact">Contact</a>
  </li>
</ul>

In the above example of navigation markup; nav is the base component class; nav__item and nav__link are element classes and nav--inline is the modifier class.

Sub-Components

Components nested within a larger component are referred to as sub-components. These may or may not follow the same naming conventions as elements of the larger component. However, sub-components are still components and their appearance should remain independent of their location within their parent component.

CSS Source Order

Due to the more level playing field the class based selectors are on, greater attention to CSS source order is needed. With all others things equal, selectors appearing later in the stylesheet will override those appearing before. Always group your component styles together in your stylesheet with base component definitions first and modifiers that should take precedence last.

Examples in Use

The Component, Element, Modifier pattern has been made popular in recent years with the release of SMACSS by Jonathon Snook. Similar solutions can be found in other CSS architectures and front-end frameworks. The following are examples of varying implementations of the same basic pattern.

SMACSS (Scalable Modular Architecture for CSS)

[SMACSS](http://smacss.com) uses this pattern as part of the [Module](http://smacss.com/book/type-module) chapter, using the term module instead of component and sub-class for modifier. However there is no distinction between elements and modifiers in the naming conventions. SMACSS has additional naming conventions for dealing with layout and states.

BEM Methodology (Block Element Modifier)

[BEM](http://bem.info/method/definitions/) uses the term block instead of component. The BEM naming convention uses a single underscore to distinguish modifiers from base classes Example: search_inline. It uses double underscores for elements Example: search__input

Drupal CSS Coding Standards

[Drupal](http://drupal.org) utilizes this pattern in its [CSS standards](http://drupal.org/node/1887918) for Drupal 8, using the term sub-component for elements and variant classes for modifiers. There is no distinction between a sub-component and an element. Element class names are distinguished with a double underscore. Example: search__input. Modifiers use a double hyphen. Example: search__input.

Montage JS

[Montage](https://github.com/montagejs/montage/wiki/Naming-Conventions) uses this pattern, using the term state for elements and variant classes for modifiers. All class names are prefixed with the name of the framework. Base classes are named in CamelCase with the first letter capitalized. Example: montage-BaseClass. Element class names are distinguished with a single hyphen Example: montage-BaseClass-elementClass. Modifiers use a double hyphen Example: montage-BaseClass--modifierClass.

Twitter Bootstrap

[Bootstrap](http://twitter.github.com/bootstrap/components.html) makes partial use of this pattern in its naming of components such has nav and button and their associated modifiers. However, it doesn't class elements within components, relying instead on HTML element selectors. This has the upside of less page-weight in the HTML at the cost tightly coupling components to a specific HTML structure, which can limit a components reuse and increase CSS specificity. That may or may not be appropriate for your situation.

A Note on Design Patterns

Design patterns are common solutions to recurring problems within a given context. Despite their name, design patterns are not designed, but observed. They are not step-by-step instructions. They represent the basic concepts required to solve a problem and can be implemented in different ways based on the use case and context.

Code

Read This Next