Styling bible

My way of defining SCSS styling. Based on BEM naming methodology. Using same and strictly ruled way of styling makes development easier and more maintainable.

SCSS code example

Example of SCSS file for component.

/* Block */
.list {
  background-color: #FFF;
  display: block;
  width: 400px;
  
  /* Higher component modifier */
  .app--disabled & {
    opacity: 0.7;
  }
}

/* Element */
.list__item {
  border: 1px solid #FF0;
  display: block;
  height: 50px;
  overflow: hidden;
  width: 100%;
  
  /* Pseudo elements */
  &:hover {
    border: 1px solid #FF0;
  }
}

/* Modifier */
.list__item--done {
  background-color: #E9FCF6;
}

HTML code example

Part of HTML where this SCSS styling is used.

<div class="list">
  <div class="list__item list__item--done">Dog</div>
  <div class="list__item">Cat</div>
  <div class="list__item">Otter</div>
</div>

Rules

More exact defination for rules.

  1. Only block, element and modifiers start from first level. They should never be nested.
  2. Element sign is two underscores.
  3. Modifier sign is two dashes
  4. Block, element and modifier names are formed with dashes and lover case letters.
  5. Class properties should be in alphabetic order.
  6. Every class in project should have BEM style class name. Elements without right naming convention, makes code vulnerable to effect on unexpected place.
  7. Try to avoid Higher component modifier defination. This is used in CMS projects where DOM is not fully customizable. Please use modifiers.
  8. Use maximum of 3 nesting levels. This should be no problem if higher component modifiers are not used. Maximum 3 level nesting of block, element and modifier comes with: [block / element / modifier] > [pseudo element selector] > [pseudo element selector].

Example:

.list__item {
  &:first-of-type {
    &:hover {
      background-color: #FF0;
    }
  }
}
  1. Do not use referencing parent selector (&) for defining modifier or element inside block defination.
  2. Always style HTML elements with classes. Do not use element selector. Id selectors are for JavaScript.

Common mistakes

Here are some commonly used ways which are working, can be seen as a bad habit. They make code less maintainable, less readable and for do not isolate component styles.

Do not declare modifiers or element with referencing parent selector

Common way of declaring elements and modifiers is to use & key. For example:

.list {
  background-color: #FFF;
  display: block;
  width: 400px;

  &__item {
    border: 1px solid #FF0;
    display: block;
    height: 50px;
    overflow: hidden;
    width: 100%;
  }
}

This can seem to be more efficient code. There is though more backsides. It get's messy and it's harder to separate block properties from modifiers and elements. It's also too easy accidentally to add a property which effects wrong selector.

Developers will also enjoy when certain selectors can be found just by searching .list__item and not block and element separately.

Styling elements without BEM naming

Lazy way which affects wrong component's HTML elements. Here is an example:

/* list.scss */
.list {
  background-color: #FFF;
  display: block;
  width: 400px;
  
  /* .list__item selector */
  div {
    border: 1px solid #FF0;
    display: block;
    height: 50px;
    overflow: hidden;
    width: 100%;
  }
}

/* button.scss */
.button {
  background-image: url("/assets/img/accep-image.png");
  border: 1px solid #000;
  margin: 0 0 0 10px;
}

There can come a case where these component styles are eachother's parents and childs.

<div class="list">
  <div>
    Otter
    <div class="button">Mark done</div>
  </div>
</div>

In this example .list__item selector without certain class selector also affects on button component. Still relatively easy to fix, but makes unexpected styling. That one who fixes, maybe do not understand these rules and might make code more messy code.

Notice that this is also affected when elements are named whith simple names like 'item' or 'list-item.

Less spoken effect is also that HTML elements are slower found by selectors, if there more optional elements. Read more about this at Writing efficient CSS selectors - CSS Wizardy.