March 11, 2015

Sass, BEM, and Semantics

This is a repost of an article I wrote originally posted on the Lookthink blog here.

Today’s post is brought you by our fantastic summer intern, Sarah Federman. Sarah is a New Media Design major at the Rochester Institute of Technology and has brought her A-game to our Development team. From spearheading website builds to supporting the design team, Sarah has played a major role in the projects flowing through our office this summer. Follow @sarah_federman on Twitter for the latest and greatest in bleeding edge techniques for front end development!

There’s a nice buzz around the topics of modular CSS and CSS Preprocessors these days, but do they go hand in hand?

If you haven’t heard of it, BEM stands for Block-Element-Modifier, and is a syntax system and philosophy for creating flexible css modules. You can read more about it here: http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/

I recently started working on a news site that displays articles in several distinct ways. Thus, the easiest and most reusable abstraction was to create a module for displaying article information.

My blocks included things like:

.article__title
 .article__date
 .article__description

One modifier is for displaying articles in a tile-like grid format

.article—tile

…but they’re also styled differently in the footer:

.article—tile—footer

Add in more modifiers for promoted “sticky” tiles, featured articles, articles that go within a media object, articles overlaying an image…and suddenly you’ve got a sizable module going.

I started out going as Sass as possible, with something like this:

.article {
 &__title {}
&__date {}
&__description {}
&—tile {
 &__title {}
&__date {}
&—footer {
 &__title {}
&__description {}
 } // end footer
 } // end tile
&—media {}
 } // end article

…And so on. And suddenly we’ve nested 6 levels down 350 lines. It might compile something pretty, but right now I’m looking through my own file and all I see are ampersands, and I’ve scrolled down and I can’t orient myself. Am I still looking at a tile? Am I back in the article root? Could someone else read this? Would this confuse my team members? Extending blocks closer to the root is suddenly complicated as well.

It’s ugly and un-semantic. Is it theoretically well organized? Sure. Maybe I could have heavily commented, but I ended up taking out all of the ampersands and switching out of pure sass.

.article{}
.article__title {}
 .article__date {}
 .article__description {}
.article—tile {}
.article—tile__title {}
 .article—tile__date {}
.article—tile—footer {}
.article—tile—footer__title {}
 .article—tile—footer__description {}

400 lines in, this is much more readable and easily maintainable. There are some places where I might consider making “article—“ a variable. This method certainly takes much more typing, but I think it’s worth it when it comes down to maintenance and semantics. Extending is also much easier. At-root is an option, but we still retain the same readability problems.

Sass is still great for all sorts of functionality, like mixins and creating partials for your modules. I love Sass. But personally, I would caution against sacrificing semantics for quick typing.

If I were to redo this, I might break it down further and start making more classes with less that I could use together in the HTML instead of extending the other blocks and rewriting rules.