Breaking The Naming Convention

You can have more-composable, faster (performance) and faster (time-to-develop) components by breaking away from selector styling conventions that overload a separator character (e.g. the hyphen character -).

It's common to see the separator character used to denote hierarchy and to represent human-parsed naming semantics (e.g. a space between words). This leads to complexity.

.component-name - this is a common practice. it only allows for one dimension of identification in that particular class. The - just means something like "I want an identifier that I'd write with a space if I was writing it for humans to read."

Let's make a styled 'list' component as an example.


This example contains a few complexity-increasing practices alongside the one mentioned above:

ul.adorned-list {
  margin: 0 0 1em;
  list-style: none;

  li.list-item {
    position: relative;
    padding-left: 1.25em;
    margin-bottom: 1em;

    &:after {
      position: absolute;
      top: 0;
      left: 0;
      background-image: ('bullet.png');
      background-repeat: no-repeat;
    }

    &.list-item-highlighted {
      &:after {
        background-image: ('bullet-special.png');
      }
    }
  }
}

The pre-processed CSS above compiles to:

ul.adorned-list {
  margin: 0 0 1em;
  list-style: none;
}
ul.adorned-list li.list-item {
  position: relative;
  padding-left: 1.25em;
  margin-bottom: 1em;
}
ul.adorned-list li.list-item:after {
  position: absolute;
  top: 0;
  left: 0;
  background-image: 'bullet.png';
  background-repeat: no-repeat;
}
ul.adorned-list li.list-item.list-item-highlighted:after {
  background-image: 'bullet-special.png';
}

There are a few problems here but let's just focus on one: Given the dash-as-semantic-space paradigm, we have no way of suggesting hierarchy with a single classname.


.componentName - we have liberated the hyphen, but this in-and-of-itself is not better. However, it unlocks another iteration.


.componentName-descendantName - we have revealed the new meaning of the hyphen. It can now work for us to provide additional dimensions of meaning (or potentially many dimensions), but never again will it have its old semantic meaning.

This convention is borrowed from the SUIT CSS naming conventions. The SUIT CSS convention is a flavor of block-element-modifier methodology.


Quick Aside on Allowable Characters In Selectors

The specification gives us a-z, hyphen, underscore as viable characters in a CSS class.

It also gives lots of ISO 10646 characters, but these extra characters must be escaped, so we should probably never use them.


Using The New Convention

.componentName-descendantName--modifierName

.adornedList {
  margin: 0 0 1em;
  list-style: none;
}
.adornedList-listItem {
  position: relative;
  padding-left: 1.25em;
  margin-bottom: 1em;

  &:after {
    position: absolute;
    top: 0;
    left: 0;
    background-image: 'bullet.png';
    background-repeat: no-repeat;
  }
}

.adornedList-listItem--highlighted {
  background-image: 'bullet-special.png';
}

compiles to:

.adornedList {
  margin: 0 0 1em;
  list-style: none;
}
.adornedList-listItem {
  position: relative;
  padding-left: 1.25em;
  margin-bottom: 1em;
}
.adornedList-listItem:after {
  position: absolute;
  top: 0;
  left: 0;
  background-image: 'bullet.png';
  background-repeat: no-repeat;
}
.adornedList-listItem--highlighted {
  background-image: 'bullet-special.png';
}

Styling to Element Tags

What are some good reasons to not style directly to tags?

What are some good reasons to style directly to tags?

What are some misguided justifications for styling directly to tags?


Also see: "CSS Componentry"