Thereās nothing wrong with using id
ās per se. #
selector is just a tool.
The real questions are:
- is your code easy to reason about (how much time a new developer needs to be familiar with the codebase)?
- how much time it takes to introduce a new feature (does the development time grows with each new feature)?
- how much time and effort it takes to change something (does changing one thing often breaks something else in the code)?
- can multiple people work on the codebase without conflicts?
Thereās no way of building a successful web project without a good system or methodology.
Letās look at an example:
We want all paragraph text to be blue except the last one which should be red.
<p>first</p>
<p>second</p>
<p>third</p>
The simplest way to do it is add id to the last paragraph:
<style>
p {
color: blue;
}
#last {
color: red;
}
</style>
<p>first</p>
<p>second</p>
<p id="last">third</p>
It works. Letās say we want to change color of the text of each paragraph to green when hovered over. Seems simple:
<style>
p {
color: blue;
}
#last {
color: red;
}
p:hover {
color: green;
}
</style>
<p>first</p>
<p>second</p>
<p id="last">third</p>
Bummer. The last paragraph is still red when hovering over it. id
selector has greater specificity than class + pseudoclass. Letās fix it:
<style>
p {
color: blue;
}
#last {
color: red;
}
p:hover {
color: green;
}
#last:hover {
color: green;
}
</style>
<p>first</p>
<p>second</p>
<p id="last">third</p>
Now it works. But thereās another requirement: The text color should be yellow instead of green when hovering over. Easy:
<style>
p {
color: blue;
}
#last {
color: red;
}
p:hover {
color: yellow;
}
#last:hover {
color: green;
}
</style>
<p>first</p>
<p>second</p>
<p id="last">third</p>
Bummer. Last paragraph is still green. The rule for hovering is in two places: one for p
and one for #last
. We need to change the latter as well:
<style>
p {
color: blue;
}
#last {
color: red;
}
p:hover {
color: yellow;
}
#last:hover {
color: yellow;
}
</style>
<p>first</p>
<p>second</p>
<p id="last">third</p>
Conclusion: Weāve had 3 elements and two new requirements. In both implementations we had to do some debugging to make it work. What if there were hundreds of elements to look after? This way of coding does not scale and is counter-productive.
Letās use BEM methodology instead:
<style>
:root {
--color-primary: blue;
--color-complement: green;
--color-emphasis: red;
}
.discussion__opinion {
color: var(--color-primary);
}
.discussion__opinion:hover {
color: var(--color-complement);
}
.discussion__opinion--significant {
color: var(--color-emphasis);
}
</style>
<div class="discussion">
<p class="discussion__opinion">first</p>
<p class="discussion__opinion">second</p>
<p class="discussion__opinion discussion__opinion--significant">third</p>
</div>
Thereās initial overhead related with giving a class to each html element, but now their roles are clear. Because we use only single classes as selectors, we can be pretty confident that our code will work as expected when introducing new features as each selector has equal specificity. By using CSS variables, changing the existing styles is a matter of modifying one line of code. And naming convention that clearly separates different parts of the project makes collaboration easy.
Should you use BEM? Not necessarily, but you certainly should get familiar and use some well-established methodology even in a simple project to develop good habits. And if you get stuck, people will be more willing to help you when your code is easy to read, especially if theyāre acquainted with the methodology you use.