Made Tech Blog

Ensuring the Code Quality of Your SCSS

At Made we create web software that is built to last, so every aspect of the codebase has to be easy to understand and maintainable by any member of the team. Because of this we run our server side code through tools like Tailor and Cane to keep complexity low and consistency high.

To keep our front end styles at the same standard we rely heavily on the front end team to produce modular and stylistically consistent CSS. It’s all too easy to mistakenly wrap a background URL in double quotes when only single quotes are needed, or throw a global style in, whether it’s down to laziness or by mistake.

With the aim of enforcing this consistency many front end teams choose to employ a naming convention, as well as other practices like sorting CSS declarations alphabetically.

**SMACSS and BEM**

There are many routes available to a front end developer wishing to write modular, scalable stylesheets. Broadly speaking they all do the same thing: they recommend a file structure, naming conventions and methodologies for inheritance. However it is most likely the established naming conventions that will dictate which one you use, primarily down to a personal preference. Some, like BEM, are very specific and lead to some very verbose classes, and are meant to be coupled with others like SMACSS.

**Scalable and Modular Architecture for CSS** (**SMACSS)**

I bought the SMACSS book a while ago, when I first started looking into best practices for CSS, and I really liked some of the concepts. In SMACCS you modify your modules by doubling up the base module with the modified module styles. This is great if you aren’t using SASS/LESS but you could easily end up with a “class soup” situation on your markup. However, the concept of applying state based CSS classes is great, and when this is coupled with JS you can achieve rich animations without writing CSS in JS.

Unfortunately, SMACCS does do some things I don’t agree with, the main one being using IDs to style layout elements like headers and footers. Having IDs in your markup to be used as targets for your JS is fine, but in CSS they should be avoided in my opinion. Good CSS should be repeatable, yet IDs are not, unlike classes. In addition to that, IDs also add a high level of specificity to the styles applied to an element, which can lead to style inheritance hell in the long run.

**Block Element Modifier (BEM)**

Once I had started reading into ways to better my CSS I soon discovered BEM. BEM is a more OO way of naming your CSS and applying it to your HTML markup (and yes, I know OOCSS is a thing too).

As the name suggests the BEM naming convention is quite simple: you namespace a module into a block (e.g. header) and then any elements and modifiers on those elements get delimited by double underscores (“__”) and dashes (“—“) respectively.

The biggest pro of BEM is also its biggest con, which is the ability to get really specific with naming your classes. When used well this can lead to really succinct class names that describe their blocks and elements perfectly, but when used poorly you could end up with an eighty character-long class, which isn’t ideal.

**Pre-processors Make It All So Easy…**

Writing all these rules in CSS can be very laborious. Pre-processors like LESS and SASS eliminate many of the pain points that exist in CSS and they can make your modular CSS clearer too. Usage of a pre-processor can also help us with writing SMACSS and BEM. Through the usage of placeholders/extend declarations and mixins you can refactor common styles and apply them where needed.

SMACCS subclassing:

.thing {  
  &-subclass {...}
}

becomes:

.thing-subclass {...}

BEM modifiers:

.block {  
  &__element { 
    &—modifier {}
  }
}

become:

.block__element--modifier {...}

We Chose…

BEM, and applied the stateful concepts from SMACSS.

**Enforcing Quality**

As with our back-end code, automating the quality control of our SCSS is important. Whilst searching for a solution to this I found SCSS Lint, a Ruby gem (there is also a gulp module) that can be used either as a standalone linting tool or as part of your CI workflow.

SCSS Lint comes bundled with 37 configurable linting rules so you can tailor the behaviour of the linter to your own requirements. One of the more useful linting rules is the ability to specify a naming format, with one of the two out-of-the-box formats being BEM. If you are a Sublime Text 3 user you can also make use of the SCSS lint extension for SublimeLinter.

**Getting SCSS Lint Ready for CI**

One of the available output formats of SCSS Lint is an XML file that can be consumed by Jenkins CI. So if you piped the stdout into a report xml file this can then be integrated into your Jenkins build configuration. You could then fail a build if any of your front end team get sloppy. The below is an excerpt from our front end test suite:

export FAIL_SCSS_WARNINGS=false
mkdir -p reports
bundle exec scss-lint --format=XML app/assets/stylesheets > reports/TEST-scss-lint.xml
_scss_violations_errors = ` grep -o 'severity="error"' ./reports/TEST-scss-lint.xml  | wc -l`
_scss_violations_warnings = ` grep -o 'severity="warning"' ./reports/TEST-scss-lint.xml  | wc -l`

if [ $_scss_violations_errors -gt 0 ]; then
  echo -e "e[31mNumber of SCSS errors: $_scss_violations_errorse[39m"
  exit 1;
fi

if [ $_scss_violations_warnings -gt 0 ]; then
  echo -e "e[93mNumber of SCSS warnings: $_scss_violations_warningse[39m"
fi
if [ $_scss_violations_warnings -a $FAIL_SCSS_WARNINGS ]; then
  exit 1;
fi

tl;dr

Whatever your tool chain, it’s important to enforce consistency within your team, and this applies just as much to your front end as it does to your back end. One way of introducing common practices is through using naming conventions like the ones used in SMACSS and BEM. Using a CSS pre-processor like SASS can make using these naming conventions faster. If, like us, you use SCSS then perhaps SCSS Lint will solve this for you too. SCSS Lint can also be combined with Jenkins CI (perhaps using the snippet above) to fail a build if you want to take it to such levels.

Useful Links

About the Author

Avatar for Seb Ashton

Seb Ashton

Lead Software Engineer at Made Tech