After learning the basics of CSS, you start using it on your website and realize it can get messy very quickly. Everything is on the global scope and you must keep you're variables readable. At some point, you start mixing up the names or create selectors that do the same thing as you had on a previous page.
Why have guidelines? Fiona Chan at Web Directions South explains the problem of Spaghetti Code in CSS in the video below.
This StackOverflow post sums it up quite nicely.
In general, the rule of thumb is that you should ask yourself: "is there more than one element which requires the same style, now or at any time in the future?", and the answer is even "maybe", then make it a class
If you've come across this issue before, you may start to think about different ways to change the structure of your CSS file. You'll realize it's probably easier if your CSS isn't all on one file, and you want to incur a separation of responsibility for each CSS file.
Multiple selectors WIP
e.g. .nav .item .label .header .title .icon {}
would not be good practice.
If you use CSS preprocessors like SASS, you can utilize nested selectors. However, those can become cumbersome if you nest too deep. You should try not to nest more than 3 levels.
BEM stands for block, element, and modifier. It is used for keeping a convention for variable naming. You can learn more about the methodology on the informative BEM website.
A block is a parent id or class than encompasses the top-level of a component.
.nav {
width: 100%;
}
.btn {
color: blue;
}
For multi-word CSS selectors, a hyphen is used as a delimiter between each word. For example, navTab
would be incorrect. Instead, use nav-tab
.
Elements should be thought of as child elements to the block (parent). They have some description to where or why they are used. They should be preceded by two underscores.
.nav__listItem {
background-color: green;
}
Modifiers describe some change to the block for a theme or style without changing the component to becoming something entirely different. For example, it could be a quick color change. They are preceded by two hyphens.
.media-object__image--reversed {}
.media-object__image--left {}
.media-object__image--right {}
If you use Sass, you can integrate blocks with your elements and modifiers rather than creating separate selectors.
.media-object {
&__image {
&--reversed {}
&--left {}
&--right {}
}
}
Joe Richardson, Robin Rendle, and a bunch of the CSS-Tricks staff stated the following with the criticism BEM had.
If you want to dislike BEM, that's absolutely fine, but I think it would be hard to argue that having a set of rules that aid in understanding and assist in keeping CSS maintainable is a bad idea.
What it really important here is to have some convention and to stick by it. If it's not BEM, then at least have some naming convention everyone on the team is going to stick with. Otherwise, it is extremely easy to start messing with the global space and tack on unnecessary, and unmaintainable, class selectors for a single element.
This guide was primarily sourced by this article called BEM 101 by Joe Richardson, Robin Rendle, and a bunch of the CSS-Tricks staff.
There are other types of naming conventions you may want to follow that correlate to this way of BEM. Check out the Naming Convention section of the informative BEM website for more information.
- Normalize CSS - Nicolas Gallagher and other contributers - Removes presets set by browsers on CSS elements
- CSSLint - Nicholas C. Zakas and Nicole Sullivan
- PostCSS - Use Tomorrow's CSS features today (like Babel for CSS)
- CSS Style Guides - CSS-Tricks, Chris Coyier
- Organizing CSS: OOCSS, SMACSS, and BEM - Matt Stauffer
- SMACSS Book - Jonathan Snook
- BEM 101 - CSS-Tricks, Joe Richardson, Robin Rendle, and a bunch of the CSS-Tricks staff
- ID vs. Class Selectors - Stack Overflow, nickf