BEM and SMACSS: Advice From Developers Who've Been There

Originally published at: http://www.sitepoint.com/bem-smacss-advice-from-developers/

CSS methodologies can be mind bogglingly confusing and tough to decide upon. Let’s consider two of the most well known options: BEM and SMACSS.

Should you choose one of these for your next project? What are they best suited for? What might go wrong? If you’re already working with one – are you using it as intended? To the fullest potential? How do you know if you’re doing it right? I thought I’d be nice to ask people who’ve already been through those questions in their own projects and learn from their experiences.

I asked developers who’ve worked with BEM and/or SMACSS for their success stories, horror stories, advice, and words of caution. I gave some developers a whole list of questions and others just free-formed their thoughts to me. I’ve compiled the results into what I hope will be valuable reading for those considering optimizing their CSS.

For those new to BEM and SMACSS, I’ll start by giving a very high-level overview of what BEM and SMACSS are.

What is BEM?

BEM stands for Block Element Modifier and originated at Yandex. It provides a rather strict way to arrange your CSS classes into independent modules. There are a few variations on the idea but the most common one looks like this:

.block {}
.block__element {}
.block--modifier {}
.block__element--modifier {}

A Block represents an object in your website. For example:

* a person
* a login form
* a menu
* a search form

An Element is a component within the block that performs a particular function. It should only make sense in the context of its block. For example:

* a hand
* a login button
* a menu item
* a search input field

A Modifier is how we represent the variations of a block. For example:
* a female person
* a condensed login form (e.g. we’re hiding the labels in one version)
* a menu modified to look differently for a footer or sitemap
* a search input field with a particular button style

In the example of our menu, the class names could look like this:

.menu {}
.menu__item {}
.menu__item--featured {}
.menu--footer {}

There are other architectural principles and tools for BEM on the bem.info website, however, when developers discuss BEM, they’re often focused mainly on the naming convention above and that is true of the majority of the discussion below.

Continue reading this article on SitePoint

I’ve been thinking about this the past year. I work in a very, very small team and I am pretty much the only person that writes the HTML & CSS on our projects. I found, that sometimes, these principles only really shine in webapps, not so much in sites that just deliver content; Plus a lot of its advantages get lost when there is not another person working on it.

And, working with BEM, you might easily end up with something like .article–news–listed__headline__date__year–pink. And that is not very readable anymore imho.

The sass behind that thing might be easier to understand though:

.article {
&--news {
	@extend .article;
	&--listed {
		@extend .article--news;
		&__headline {
			&__date {
				&__year {
					&--pink;
					@extend .article--news--listed__headline__date__year;
					color: HotPink;
				}
			}
		}
	}
}

gives you a feeling for the code, but is still not very readable. Of course that was an extreme example, but not that unlikely if you think about it.

What worked for me best, is mixing these methodologies together. So for example, in my article, I have:

<article class="article--listed  news-article">
<div class="article__headline">
	<time class="article__headline__date"></time>
	<h1 class="article__headline__text"></h1>
</div></article>

–listed extends the .article-object, while .news-article provides the context. I have a “__article.scss”, that gets imported first, and then I have a “__page-news.scss” partial, that gets included later on, that provides the context with the .news-article.

That way, I can safely overwrite my selector, without having to worry about specificity. This is more or less an applied approach from Harry Roberts ITCSS.

I used to try not to overwrite anything, and of course you could use %placeholder-classes or @mixins for the .article object, but I found, that this takes up a lot of time, which I often do not have.

btw, that preformatted-text thing messes up my tabs, so sorry, if it looks messy :confused: Oh well, I tried to get the scss-selector code with the extends to work, but it just makes it even worse. Hope my point is clear :smiley:

Thanks for your comment and for reading!

All methodologies have their variations so I’ll just put in my thoughts on this one but then I’d really like it if others do something different to provide their thoughts too :smile:

This is how I’ve approached it in my own projects:

No nesting beyond two levels
I’ve found that BEM is best when you stick to just one level of parent and child. I never nest more than two levels. I did so in my first attempts at BEM, then realised that it’s the wrong way to go about things and it becomes a mess. Anything which is potentially deeper nesting, is separated into a new element. As Josh mentions in the article - you don’t want to be mapping your whole HTML structure in your class names.

So:

<article class="article--listed  news-article">
    <div class="article__headline">
	<time class="article__headline__date"></time>
	<h1 class="article__headline__text"></h1>
    </div>
</article>

In the way I do BEM would be:

<article class="article article--listed article--news-article">
    <div class="headline">
	<time class="headline__date"></time>
	<h1 class="headline__text"></h1>
    </div>
    <div class="article__content"></div>
</article>

With article__content being an example of a container that would have its own blocks within it and such too.

Or even this if I wanted to introduce a variation on headlines that should look a certain way for an article compared to something else:

<article class="article article--listed article--news-article">
    <div class="headline headline--article">
	<time class="headline__date"></time>
	<h1 class="headline__text"></h1>
    </div>
    <div class="article__content"></div>
</article>

As I see the fact that the headline is a more complicated element means it’s one that is a more independent module. Chances are you might have a headline in a different style within article snippets on a homepage that don’t show the whole thing, or in a video gallery which lists videos rather than articles with headlines… etc.

Nesting
I also avoid having any nesting after a modifier, so rather than .article--news__headline, I’d work with .article--news .headline in CSS. I wouldn’t have nested modifiers like .article--news--listed either. Each modifier would be in its own class like .article--news and .article--listed.

I’d love to know what others think too.

have you seen getbem.com with another BEM guides?

I actually have come across it! I see you’re a contributor :slight_smile: Great job helping provide guidance on it all!

One suggestion I’d love to make - the internet is missing some really nice, clear examples of how to use BEM in more complex projects. I think it’d be great if getbem.com included some of the more complex end of the scale stuff. Clearing up some of the misconceptions and confusion around how to use BEM (e.g. nesting of many child selectors best practice, examples of when to go modular and use a new BEM object compared to a child one… etc).

Also, I’d love any of your thoughts and ideas on using BEM - do you have any success/horror stories you could share in the comment stream? The more thoughts and advice the better!

Thanks for reading and getting in touch!

I’ve looged in to suggest getbem too :slight_smile: Actually, I see that in your article you clarify many things that we try to explain in BEM FAQ http://getbem.com/faq/
Do you mind if some pieces of your article would be quoted in there? With a link to this article, of course.
Or, if you would add some text in the FAQ by yourself, you are very welcomed!

Hi there! We’ve come across your post about BEM and SMACSS http://www.sitepoint.com/bem-smacss-advice-from-developers/ its cool! thank you so much! The issue here is that Russian and English worlds of BEM are so separate so they have to pass evolution twice :wink: And we as a team developing BEM together with our mostly Russian contributors who went further on from using BEM only in CSS to JS and full stack, written own open sourced solutions etc would like very much to engage you into discussion and have a look on everything we have from scaffolding to other tools and experience, and really looking into helping with all questions you’ve got. Just tag it #b_ if you tweet or ask us in gitter chat that we use for English speakers https://gitter.im/bem/talk It’s our pleasure to get to know all of you! Official BEM site is bem.info. We try to put there everything we have asap + documented in English as well. If you have any suggestions we would be happy to listen too.

Hi Varya!

I’m really glad the article has managed to clarify and explain BEM a bit more!

You’re more than welcome to quote this article in getbem.com, as long as you clearly link to it :slight_smile: If it’s a particular developer’s quote in the article, please make sure they’re attributed to their thoughts too.

Thanks for the great work on getbem.com!

Thanks for the comment and kind words guys! Really glad you liked the article. I’d be interested to see how the BEM team and other Russian web agencies are developing in BEM, along with your thoughts on where it’s progressing in terms of the CSS naming structures that are evolving from it.

I’ll have to come join your chat some time, or hit you up on Twitter.

Thanks for this, Patrick. I find your explanation of never nesting elements beyond second level really cool. In fact, I have come up with a similar idea. Although our ways differ in that I suggest having a BEM mixin on a node, while you suggest just a regular block (headline in this case) with a possible modifier (headline--article). I would have the following: <div class="article__headline headline"></div>. Thanks for the article too )

Hi skip405! Thanks for reading and the kind words!

I’ve actually done it your way in the past too, I think it depends on the situation. I suggested doing it headline--article as I think it comes across a bit less coupled?

Though, having it as article__headline headline would be nice for keeping the headline with specific article stylings within the article hierarchy in your CSS. I think I’m 50/50 about which to go with!

Maybe it depends on where you intend on keeping the variations on the style in your CSS? If you want the headline styles to all be together, then headline--article is the way to go, whilst if you want the article related styles to all be together, then article__headline would work :smile:

Great post, and I wanted to mention MVCSS (http://mvcss.io/). I’ve used it on multiple projects, and it seems to be this “combination” of BEM and SMACSS that is mentioned at various points in this post.

Glad you enjoyed it @withinsight, thanks for commenting!

I checked out MVCSS and it looks alright! It doesn’t seem to have the same BEM style with the underscores, so at a glance I couldn’t see whether there is a separation of blocks and elements within it, or whether it’s more focused on OOCSS?

Might need to look at it closer later! Thanks for the suggestion :smile:

It does use prefixes (like in the variable examples here: http://mvcss.io/foundation/config/) and modifiers (http://mvcss.io/styleguide/naming/). Its managed by the Code School and Envy Labs teams, so I think it arose from common patterns they saw in their day to day projects.

Ah I see! So it’s got the prefixes like SMACSS and the modifiers from BEM. That’s pretty neat. Does it have guidelines for keeping things modular and reusable like blocks and elements in BEM? How would you approach those? Is it just block and block-element?

Yes, MVCSS defines them as components and structures (http://mvcss.io/components/). Components are smaller, reusable modules, and structures are larger and more complex, typically being composed of one or more components.

Interesting! I think I personally find the __ between blocks and elements clearer but that’s more a personal preference. MVCSS does seem similar in a lot of regards! Thanks for the insight, @withinsight :slight_smile:

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.