Why you need this?
Disclaimer here is, you may not! This guideline is based on my opinion and experience, and it has worked so well for me, it is something I propose every time I start a new project. This 'customisation' of the BEM system serves me so well and has saved me so much time in code reviews, that I don't think I'll want to give up to it any time soon.
BEM and modular systems
There are of course other methodologies to write efficient CSS, but my favourite has, since I came across it, BEM. It plays really well with component based systems like the one I use at work (AEM) and even with my favourite framework architecture (Angular).
The 'block' in Bem
You don't even need to think much what the 'block' in BEM will be. The component/module is the block.
// The file is called example.scss , you noticed? Yes, call your file as your block, and put only code related to it, in it. | |
// do! | |
.example { | |
// your code here | |
} | |
// don't! | |
.my-Example-component { | |
// your code here | |
} |
The 'elements' in bEm
Most components have the need of an outer wrapper, an inner wrapper, a headline, a sub headline, an image, a description or text, a list and the list items, so you can create conventions on how to name those, too. That allows you to reutilise code from one component to another.
// ok, this file is called example-block?! How is that?! | |
// No, this is just to identify gists ;) | |
// Sooo, name the element after, you know, an element or a generic reference to it! | |
// do! | |
.example { | |
&__wrapper { | |
// code | |
} | |
&__innerWrapper { | |
// code | |
} | |
&__hl { | |
// code | |
} | |
&__subHl { | |
// code | |
} | |
&__list { | |
// code | |
} | |
&__listItem { | |
// code | |
} | |
&__txt { | |
// code | |
} | |
} | |
// don't! what if you want to reuse the same styles in another component? or the requirement changes! | |
.example { | |
&__copyrightNotice { | |
// code | |
} | |
&__productDescription { | |
// code | |
} | |
&__largeTitle { | |
// code | |
} | |
} |
Basically, try to refer to those elements when you create your classname. Avoid calling a classname after what the block content is about. That renders your code non-reusable. And seriously, it never scales! You will end up in a mess.
The 'modifier' in beM
Again, try to be as generic as possible. Try not to use the modifier to refer to the content for that element. It restricts you and it's a mess when the requirement changes, if it does. It makes you go through a lot more hassle if you want to reuse the code later.
Try to focus in naming the modifier after a cosmetic attribute. It describes a wider element, compared to a more narrow one? It maps to a color of your scheme? It implements a font definition? (bold, italic, etc)
// Now let's talk about modifiers | |
// do! | |
.example { | |
&__wrapper { | |
&--wide { | |
// code | |
} | |
&--narrow { | |
// code | |
} | |
} | |
&__hl { | |
&--red { | |
// code | |
} | |
} | |
} | |
// don't! | |
.example { | |
&__wrapper { | |
&--info { | |
// code | |
} | |
&--firstElement { | |
// code | |
} | |
} | |
&__hl { | |
&--productTitle { | |
// code | |
} | |
} | |
} |
State
Modifiers can come in the form of states. State is something that your element 'is' or not, 'has' or has not. So use those verbs to compose the name of your state. Is it active, is it collapsed, does it have icons?
// States should also be easily identifiable. | |
// Because they're connected to dynamic behavior! | |
// And you want to quickly spot them | |
// do! | |
.example { | |
&__list { | |
&-isCollapsed { | |
// code | |
} | |
&-isExpanded { | |
// code | |
} | |
} | |
// don't | |
.example { | |
&__listExpanded { | |
// code | |
} | |
&__listCollapsed { | |
// code | |
} | |
// that looks like a modifier,...done wrong! | |
&__listItem--noIcon { | |
// code | |
} | |
} | |
Syntax
Syntax is important to deliver clean and consistent codebases, that are easy to understand and maintain.
Here is a simple table you can share with your team, to have a reference and use during code reviews! I hope it's as much useful to me, as it is for me!
Have a great day!
Top comments (2)
Great to read about your ideas in a little more detail π. Thanks for sharing, Natalia!
So glad you find it useful!