With expensive we mean in the sense of performance or overwriting:
1 level selector
.this-one-class {
color: #ccc;
}
.grandfather.is-deaf .grandfather .son .grandchild {
color: #ccc;
}
VS
5 levels selector
Which one is the most expensive? And takes more time to find the element?
1 level selector
Expensive selector!
Harder to read and maintain
.this-one-class {
color: #ccc;
}
.grandfather.is-deaf .grandfather .son .grandchild {
color: #ccc;
}
VS
5 levels selector
1 level selector
#section {
color: #ccc;
}
.grandfather .grandchild {
color: #ccc;
}
VS
2 levels selector
Which one is the most expensive? And takes more time to find the element?
1 level selector
#section {
color: #ccc;
}
.grandfather .grandchild {
color: #ccc;
}
VS
2 levels selector
#ID selectors makes it expensive for debugging or overwriting.
More lightweight, easier to debug, easier to maintain
1 level selector
.home-section {
color: #ccc;
}
nav.navigation ul.grandchild li a {
color: #ccc;
}
VS
6 levels selector
Which one is the most expensive? And takes more time to find the element?
1 level selector
.home-section {
color: #ccc;
}
nav.navigation ul.grandchild li a {
color: #ccc;
}
VS
2 levels selector
Gives context, easy to overwrite or maintain
Selectors with elements and classes are very expensive. If elements are not in html, style does not apply
How a human read your selector:
nav ul li a
a li ul nav
How a browser read your selector:
<nav>
<ul>
<li>
<a href="#">Link</a>
</li>
</ul>
</nav>
nav
ul
li
a
4.
3.
2.
1.
A browser start with the latest character and ends with the first
Block, Element, Modifier
.btn {}
<a href="#" class="btn">Button</a>
.navigation {}
<nav class="navigation"></nav>
.footer {}
<footer class="footer"></footer>
Block components are removable in one piece and are for a spexific purpose or use.
.btn__icon {
font-size: 1em;
color: #000000;
}
<a href="#" class="btn">
<i class="btn__icon"></i>
</a>
.navigation__list {}
.navigation__list-item {}
.navigation__link {}
<nav class="navigation">
<ul class="navitgation__list">
<li class="navigation__list-item">
<a href="#" class="navigation__link">
</li>
</ul>
</nav>
Element that depends
.btn__icon {
font-size: 1em;
}
.btn__icon--small {
font-size: 0.5em
}
<a href="#" class="btn">
<i class="btn__icon--small"></i>
</a>
.navigation__link--active {
background-color: red;
}
<nav class="navigation">
<ul class="navitgation__list">
<li class="navigation__list-item--active">
<a href="#" class="navigation__link">
</li>
</ul>
</nav>
The modifier changes the style of a block or element. Separated from the block with "--"
.navigation__link--transparant {
background: transparant;
}
Block (context)
Element
Modifier
.nav ul {
margin: 0;
padding: 0;
list-style: none;
}
.nav ul ul {
padding-left: 1em;
}
.nav ul li {
float: left;
}
.nav ul li a {
font-weight: 600;
color: #000000;
background: #ccc;
display: inline-block;
padding: 0.5em;
}
.nav ul li ul li a {
background: #000000;
color: #cccccc;
}
<nav class="nav">
<ul>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li>
<a href="#">link</a>
<ul>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
</ul>
</li>
</ul>
</nav>
When you start with writing CSS, you get used to nesting to give context. This was very bad for maintainability and readability.
.nav .list,
.nav .subnav {
margin: 0;
padding: 0;
list-style: none;
}
.nav .list .subnav {
padding-left: 1em;
}
.nav .list .item {
float: left;
}
.nav .list .item a {
font-weight: 600;
color: #000000;
background: #ccc;
display: inline-block;
padding: 0.5em;
}
.nav .list .subnav .item a {
background: #000000;
color: #cccccc;
}
<nav class="nav">
<ul class="list">
<li class="item"><a href="#">link</a></li>
<li class="item"><a href="#">link</a></li>
<li class="item"><a href="#">link</a></li>
<li class="item">
<a href="#">link</a>
<ul class="subnav">
<li class="item"><a href="#">link</a></li>
<li class="item"><a href="#">link</a></li>
</ul>
</li>
</ul>
</nav>
Then you become better. You start with giving more elements classes for readability and maintainability.
.list--reset {
margin: 0;
padding: 0;
list-style: none;
}
.navigation__sub-list {
padding-left: 1em;
}
.navigation__item {
float: left;
}
.navigation__link {
font-weight: 600;
color: #000000;
background: #ccc;
display: inline-block;
padding: 0.5em;
}
.navigation__sub-list .navigation__link {
background: #000000;
color: #cccccc;
}
<nav class="navigation">
<ul class="navigation__list list--reset">
<li class="navigation__item"><a href="#" class="navigation__link">link</a></li>
<li class="navigation__item"><a href="#" class="navigation__link">link</a></li>
<li class="navigation__item"><a href="#" class="navigation__link">link</a></li>
<li class="navigation__item">
<a href="#" class="navigation__link">link</a>
<ul class="navigation__sub-list list--reset">
<li class="navigation__item"><a href="#" class="navigation__link">link</a></li>
<li class="navigation__item"><a href="#" class="navigation__link">link</a></li>
</ul>
</li>
</ul>
</nav>
Someone tells you to checkout BEM, your gonna love it! It is gonna give readability, structure and maintainability.
.list--reset {
margin: 0;
padding: 0;
list-style: none;
}
.navigation__sub-list {
padding-left: 1em;
}
.navigation__item {
float: left;
}
.navigation__link {
font-weight: 600;
color: #000000;
background: #ccc;
display: inline-block;
padding: 0.5em;
}
.navigation__sub-list .navigation__link {
background: #000000;
color: #cccccc;
}
.nav ul {
margin: 0;
padding: 0;
list-style: none;
}
.nav ul ul {
padding-left: 1em;
}
.nav ul li {
float: left;
}
.nav ul li a {
font-weight: 600;
color: #000000;
background: #ccc;
display: inline-block;
padding: 0.5em;
}
.nav ul li ul li a {
background: #000000;
color: #cccccc;
}
.list--reset {
margin: 0;
padding: 0;
list-style: none;
}
.navigation__sub-list {
padding-left: 1em;
}
.navigation__item {
float: left;
}
.navigation__link {
font-weight: 600;
color: #000000;
background: #ccc;
display: inline-block;
padding: 0.5em;
}
.navigation__sub-list .navigation__link {
background: #000000;
color: #cccccc;
}
.nav ul {
margin: 0;
padding: 0;
list-style: none;
}
.nav ul ul {
padding-left: 1em;
}
.nav ul li {
float: left;
}
.nav ul li a {
font-weight: 600;
color: #000000;
background: #ccc;
display: inline-block;
padding: 0.5em;
}
.nav ul li ul li a {
background: #000000;
color: #cccccc;
}
1. Helps to write self defining context class selectors.
2. A class is most of the time not depended on the parent element or class.
3. Non-developers can read the code and tell where it is about!
// Block
$module: 'navigation';
.#{$module} {
// Element
&__item {
border-top: 1px solid #ccc;
}
// Modifier
&--sub {
margin-left: 15px;
.#{$module}__link {
font-style: italic;
}
}
}
.navigation__item {
border-top: 1px solid #ccc;
}
.navigation--sub {
margin-left: 15px;
}
.navigation--sub .navigation__link {
font-style: italic;
}