A semantic BEM style
Introduction of my modified version of BEM naming style guide.
Naming is a big problem in programming, especially in CSS. There are a lot of ways to maintain CSS class names, it seems that BEM beats them all. I've always been using BEM in my projects, but in a modified way.
.block-name_element-name.ModifierThere are lots of people who don't like BEM. I don't like the original BEM too. Because it is ugly and takes too many characters. e.g.
<button class="button button--primary button--large"></button>So I created a modified version of BEM, it is a mix of semantic and BEM. I've used it for a while, and it works pretty well. I'd like to share it with you.
<button class="button Primary Large"></button>Naming rules
Rules for block, element and modifier names:
- if block/element names have multiple words, words should be joined with
- - block and element names are connected with
_ - modifier name is in
CamelCase - modifier can not be used alone
Flat instead of Nested
Always use flat class names for css rules:
.dialog {
}
.dialog_head {
}
.dialog_foot {
}
.dialog.Primary {
}Don't do this:
.dialog .dialog_head {
}However, you will use nested style when there is a modifier:
.dialog.Primary .dialog_head {
}Prefer block level modifier
Always put a modifier on the block part if possible. For instance:
<div class="dialog Primary">
<div class="dialog_head"></div>
</div>Don't put modifier on element. Don't do this unless you have to:
<div class="dialog">
<div class="dialog_head Primary"></div>
</div>Prefer class name over tag name
There are two ways to create a component:
class name
<div class="dialog">
<div class="dialog_head"></div>
</div>tag name
<section class="dialog">
<header></header>
</section>The class name way is preferred. But it is better to combine them together:
<section class="dialog">
<header class="dialog_head"></header>
</section>Component inner state
State is different from modifier. A state can only be used to create a component.
<button-comp class="Large">Button</button-comp>The class name Large is a modifier. But <button-comp> has a _hover class when hovering:
<button class="button-comp _hover Large">Button</button>This _hover is added by <button-comp> itself, don't add it yourself. Naming state starts with _ as protected class.
Break the rules
Sometime, you have to break the rules. For instance, you need to change the color of dialog_head, but the flat way has a very low priority, the color will be overwritten by the outer elements.
In this case, you can add .block before .block_element to create a higher priority:
.dialog .dialog_head {
}Rules are created for better maintenance. When a rule makes it very hard to implement your component, it is time to break it.
But don't break too many.