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.Modifier
There 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.