This post serves as a detailed reference and rationale of how to name HTML classes and equivalent CSS selectors using a ECSS methodology.

Related information:

Here is the format for writing ECSS classes/selectors:

.namespace-ComponentName_ComponentSection-variant-flag

To illustrate the separate sections, here is the anatomy of that selector with the sections delineated with square brackets:

.[namespace][-ComponentName][_ComponentSection][-variant-flag]

With more than a couple of developers it would be recommended that commits to a codebase were rejected that don’t follow this pattern. A regex something like /\.(\w*)+\-+(([A-Z][a-z]+)+$)/g could be used to parse class names and ensure adherence to the required sections of a ECSS style selector.

Explanation

  • namespace : all lowercase/train-case. Usually an abbreviation (required).
  • ComponentName : upper camel case/pascal case (required)
  • _ComponentSection : upper camel case/pascal case preceded by an underscore (optional)
  • -variant-flag : all lowercase/train-case (optional)

Each part of a class name can be logically discerned from another. More information on what these sections are and how they should be employed follows:

Namespace

The first part of a HTML class/CSS selector is a namespace (all lowercase/train-case). The namespace is used to prevent collisions and provide some soft isolation for easier maintenance. More on that rationale here: http://benfrain.com/enduring-css-writing-style-sheets-rapidly-changing-long-lived-projects/

The principle types of namespaces employed are:

  • namespace a component, visual area or feature
  • namespace a JavaScript hook
  • namespace a state

Most namespaces are abbreviations, for example:

  • .sc- could be ‘Shopping Cart’
  • .asc- could be for ‘Aside Callout’
  • .ocn- could be for ‘Off Canvas Navigation’

Component/feature/visual area namespace

Any component should be namespaced for easy maintenance and to provide soft isolation from other components. Anything that is different from something else, regardless of the subtleties should be namespaced into its own component.

State Namespace

A State namespace is used to communicate a change in ‘state’. For example:

.has-MiniCartActive

Indicates that on, or somewhere below this node, the ‘Mini Cart’ is active.

Another example:

.is-ShowingValue

This would communicate that the Component or one within it is showing some value (that was previously hidden).

JS Namespace

The final use of the namespace section is to communicate a hook for dynamic JS. For example:

.js-CurrentScore

Would mean this Component or node has the current score injected via JavaScript.

Note: CSS authors should not remove js- namespaced Components or classes without checking potential impact on the JS.

Component Name

The Component Name is main name of ‘the thing’. For example:

.sc-Item

Would be an ‘Item’ within the ‘sc’ (shopping cart in this example) namespace. It usually doesn’t exist on its own (unless the component has no individual sections).

Component Section

If something UpperCamelCase is preceded by an underscore it is a ComponentSection (if not it is a ComponentName).

For example:

.sc-Item_Wrapper

Here, _Wrapper is indicating that this node is the ‘Wrapper’ section of the ‘Item’ that is part of the ‘sc’ namespace

Variant Flag

If something is all lowercase/train-case and not the first part of a class name it is a variant flag.

.sc-Item_Wrapper-warning

Here the -warning flag indicates that this .sc-Item_Wrapper is a warning version (and may subsequently be subtly different.)

Utility classes

The only exception to these rules are ‘Utility’ classes. If a class is lowercase, all by itself, then it is a utility class. These classes are used for one specific job.

For example:

.w100

This is a utility class for adding 100% width to a node.

Note: the use of utility classes is discouraged as it then ties markup to a visual pattern that may not be suitable at all viewports.