DEV Community

Xiaohan Du
Xiaohan Du

Posted on

Improve SCSS structure

Alt Text

A bad example

An example SCSS which is structured as:

.widget {
    background-color: red;
    .widget-body {
        background-color: black;
        .widget-link-block {
            background-color: yellow;
            .widget-link-block-menu {
                background-color: green;
            }
        }
    }
}

Which compiles to CSS:

.widget {
    background-color: red;
}

.widget .widget-body {
    background-color: black;
}

.widget .widget-body .widget-link-block {
    background-color: yellow;
}

.widget .widget-body .widget-link-block .widget-link-block-menu {
    background-color: green;
}

It has 2 disadvantages:

  1. we are repeating keywords like 'widget'
  2. the compiled CSS relies on HTML structure, i.e. it only works on the following HTML:
<div class='widget'>
  <div class='widget-body'>
    <div class='widget-link-block'>
      <div class='widget-link-block-menu'>

      </div>
    </div>
  </div>
</div>

Violating the hierarchy would cause them stop working:

<div class='widget-body'>
<div>

does not work

<div class='widget'>
  <div class='widget-body'>
    <div class='widget-link-block-menu'>
      <div class='widget-link-block'>

      </div>
    </div>
  </div>
</div>

does not work

Suggested method

Use SCSS properly and Follow BEM

The above SCSS example can be modified to:

.widget {
    background-color: red;
    &-body {
        background-color: black;
    }
    &__link {
        &__block {
            background-color: yellow;
            &__menu {
                background-color: green;
            }
        }
    }
}

which compiles to CSS:

.widget {
    background-color: red;
}

.widget-body {
    background-color: black;
}

.widget__link__block {
    background-color: yellow;
}

.widget__link__block__menu {
    background-color: green;
}

As you can see, the compiled CSS is more compact, less complex. When write SCSS, we no longer repeat writing '.widget'. More importantly, the compiled CSS no longer relies on HTML structure, it can be used like this:

<div class='widget'>
  <div class='widget-body'>
    <div class='widget__link__block'>
      <div class='widget__link__block__menu'>

      </div>
    </div>
  </div>
</div>

or in different order:

<div class='widget'>
  <div class='widget-body'>
    <div class='widget__link__block__menu'>
      <div class='widget__link__block'>

      </div>
    </div>
  </div>
</div>

or individually:

<div class='widget-body'>
</div>

Top comments (0)