Ok, guys, draw your swords, load your weapons, hide kids and women. Let the war begin!
(Somebody enable, please, any tragical song here).
As far as you understand, that will be battle between two concepts of CSS organization SMACSS and BEM.
I know that BEM is more popular one. You know that I perfer SMACSS, but I know that I can be wrong and my choice can be not justified. So, I will try to be as fair as I can. And, maybe, till the end of this article I will change my decision(definitely not, I really like SMACSS logo).
However, I ‘m deeply commited to this theme and created two identical projects with the same layout and the same html(except classNames). The main difference is that one of them I have written via BEM other via SMACSS. That is how I can show and use many screenshots, code parts, numbers and graphs below. Hope you will appreciate it.
Ok, here are my pages:
https://greenxiii.github.io/smacss_bem/smacss.html
https://greenxiii.github.io/smacss_bem/bem.html
and you can see how I coded it here:
https://github.com/greenxiii/smacss_bem
I will judge our warriors via 5 categories:
- File structure
- Clean code
- DRY
- Scalable and Supporting
- Site Speed
File structure
BEM:
The best way to structure file in BEM is to separate all files by blocks.
That means if we have an article block – all article’s styles should be in article.less file. That’s what I have:
But here I had some misunderstanding when started writing with BEM. I used to write with SMACSS and in SMACSS I always had base.less for all my “normal” styles. I don’t really understand where I can write using BEM, in separate blocks or in other file(app.less) and to import it? Not cool, BEM, not cool. But not so critical.
As for me, file structure is more than cool(except app.less). You see at once where you need to write new styles for new element, or block, or modifier.
SMACSS:
In SMACSS we always have the same file structure, its layouts, modules, states, base, theme and it does not depend on your project. Also, I always add variable files here, so in the end I had:
Same story with one added file, but not so magical as in BEM. Base styles we already have in base.less and just added variables.less. In BEM way I wrote base and variables in app.less. Ofcourse I can separate this app.less into base and variable, but where is BEM here?
RESULT:
As for me, BEM structure looks more understandable, if you need to add block – add new file. If you need to edit some element or block – welcome to appropriate file. If you deal with SMACSS – you need to go in module or layout and Ctrl+F here to edit some module and that’s not so convenient. However, if you have a big project with many pages that will be a problem to find appropriate file in BEM, and now we have two options: Ctrl + F in modules.less file(if SMACSS) or Ctrl + F in folder by block name(if BEM).
Clean Code
SMACSS:
SMACSS advises of selectors names are simple. For layouts author recommend to use tags selectors or id’s. For modules – classes. Also, you can meet “.l-classname” for layouts and “.m-classname” for modules, but almost nobody uses it as id’s. So, in the end of SMACSS way we have nice html and nice css. F.E.
.hero-txt {
h1 {
font-size: calc(4.6rem + 1vw);
font-family: ‘Amatic SC’, cursive;
color: @primary-color;
}h6 {
font-weight: 400;
text-transform: lowercase;
}
}
.right-side {
float: right;
a {
display: inline-block;
height: 60px;
line-height: 60px;
padding: 0 20px;
text-transform: uppercase;
text-decoration: none;
font-size: 0.8rem;
color: @main-bg;
cursor: pointer;
}
}
.left-side {
float: left;
.logo {
color: @main-bg;
height: 60px;
line-height: 60px;
font-size: 2rem;
text-transform: uppercase;
font-weight: 600;
cursor: pointer;
}
}<nav>
<div class=”left-side”>
<div class=”logo”>logo</div>
</div>
<div class=”right-side”>
<a href=”#home”>Home</a>
<a href=”#hot”>Hot</a>
<a href=”#news”>News</a>
</div>
</nav>
<div class=”hero” id=”home”>
<div class=”hero-txt”>
<h1>SMACSS vs BEM</h1>
<h6>[war till death]</h6>
</div>
</div>
<section>
<div class=”hot” id=”hot”>
<article>
<img src=”https://images.unsplash.com/photo-1472457769699-93e33412e95d?dpr=1&auto=format&crop=entropy&fit=crop&w=1500&h=1001&q=80&cs=tinysrgb” alt=”hot news image”>
<div class=”desc”>
<div class=”title”>Hot-hot drones sale!</div>
<div class=”txt”>Today, just from 5am till 6pm buy excelent drones by as low price as snoop dog’s car. Just today, come and do it! Right now!</div>
<div class=”read-more”>
<a href=””>
read more
</a>
</div>
</div>
</article>
</div>
</section>
<section>
<h2 id=”news”>Regular news</h2>
</section>
BEM:
In BEM way we need to name our selectors by special BEM-way. If we have block – that will be just “.blockname”, that’s normal. But if we have element inside block we need to name it “.blockname__elementname”.
The same story is for modifier, if we have modifier for block – it will be “.blockname–modifier”, for element it will be “.blockname_elementname–modifier”.
And that makes me feel neither good nor bad at the same time.
It’s good and easy to write styles like this, especially if you use less or sass.
Just like:
.navigation {
width: 100%;
height: 60px;
background: @main-color;
position: fixed;
top: 0;
z-index: 999;
&__right-side {
float: right;
}
&__link {
display: inline-block;
height: 60px;
line-height: 60px;
padding: 0 20px;
text-transform: uppercase;
text-decoration: none;
font-size: 0.8rem;
color: @main-bg;
cursor: pointer;
&:hover, &:active, &:visited {
background-color: lighten(@main-color, 10%);
}
@media (max-width: 400px) {
padding: 0 10px;
}
}}
Also, we have good reading html. To make some changes for element you know for sure what file you need to change. However, look at this html. Look at this BIG class names. Not so good, isn’t it?
<section class=”section”>
<div class=”article–hot” id=”hot”>
<article>
<img class=”article__img” src=”https://images.unsplash.com/photo-1472457769699-93e33412e95d?dpr=1&auto=format&crop=entropy&fit=crop&w=1500&h=1001&q=80&cs=tinysrgb” alt=”hot news image”>
<div class=”article__desc–hot”>
<div class=”article__title”>Hot-hot drones sale!</div>
<div class=”article__txt”>Today, just from 5am till 6pm buy excelent drones by as low price as snoop dog’s car. Just today, come and do it! Right now!</div>
<div class=”article__read-more-box”>
<a class=”article__read-more-link” href=””>
read more
</a>
</div>
</div>
</article>
</div>
</section>
Result:
BEM code is more readable, more clear, but the main BEM problem is html, I see it quite definite. In SMACSS way, html is more clear, it has normal selectors, but it would be more difficult to edit smth than in BEM.
DRY(Don’t Repeat Yourself)
Special for this I made such blocks like Hot News and Regular News in design. The reason is that here we have styles for images and for description that will be good to use in both blocks, but the main view is little different. So, how did I solve it?
SMACSS:
article {
position: relative;
.regular & {
background: @main-color;
}
img {
width: 60%;
display: inline-block;
}
.desc {
background: fade(@main-color, 90%);
width: 40%;
float: right;
.hot & {
width: 50%;
right: 0;
top: 70px;
position: absolute;
padding: 0;
}
}
.title {
font-family: ‘Amatic SC’, cursive;
text-align: center;
font-size: 2.2rem;
text-transform: uppercase;
background: fade(@primary-color, 95%);
color: @main-bg;
padding: 6px 16px;
}
.txt {
color: @main-bg;
padding: 13px 20px 0;
}
.read-more {
text-align: center;
a {
color: @main-bg;
text-decoration: none;
text-transform: uppercase;
padding: 6px 10px;
margin: 20px 0;
border: 1px solid @main-bg;
display: inline-block;
}
}
}
BEM:
.article {
position: relative;
margin: 40px 0;
background: @main-color;
&__img {
width: 60%;
display: inline-block;
@media (max-width: 768px) {
width: 100%;
display: block;
}
}
&__desc {
width: 40%;
float: right;
&–hot {
background: fade(@main-color, 90%);
width: 50%;
right: 0;
top: 70px;
position: absolute;
padding: 0;
@media (max-width: 768px) {
width: 100%;
position: relative;
top: auto;
left: auto;
float: none;
}
}
@media (max-width: 768px) {
width: 100%;
position: relative;
top: auto;
left: auto;
float: none;
}
}
&__title {
font-family: ‘Amatic SC’, cursive;
text-align: center;
font-size: 2.2rem;
text-transform: uppercase;
background: fade(@primary-color, 95%);
color: @main-bg;
padding: 6px 16px;
}
&__txt {
color: @main-bg;
padding: 13px 20px 0;
}
&__read-more-box {
text-align: center;
}
&__read-more-link {
color: @main-bg;
text-decoration: none;
text-transform: uppercase;
padding: 6px 10px;
margin: 20px 0;
border: 1px solid @main-bg;
display: inline-block;
&:hover {
background: @main-bg;
color: @main-color;
cursor: pointer;
}
}
&–hot {
margin: 100px 0;
position: relative;
}
}
RESULT:
In BEM I had to use modifier for this task, that’s cool and understandable from html, but little bit disappointed from styles view. In SMACSS I used such cool less’s thing as “&” to make my module look different in other layout. I think both ways are cool, but both can disappoint you, if you are junior.
Scalable and Supporting
BEM:
Supporting is the main awesome thing that I found in BEM. I can work really prompt with the project that somebody wrote using BEM before me.
SMACSS:
SMACSS is not so good in supporting, but in scalable it’s easier to find modules via Ctrl+F than try to find it in dir-tree.
Result:
As for me BEM is easier to scale and support than SMACSS. SMACSS way is convenient to scale, but our “modules.less” will be really bigger and bigger. However, in BEM you will have more and more blocks files.
Site Speed
This part might be the one, you have been waiting for impatianly. But I don’t know which method is quicker. To test it, you need to create two regular and identical webpages – one via BEM, another one via SMACSS and to compare them. I’m definitely too lazy to do it. But wait…now I writing an article about BEM-SMACSS comparing and I have already two identical webpages. So, what am I waiting for?
To test my pages I use https://www.webpagetest.org . If you dont trust my screenshots, you can test it by yourself.
Summary:
As you can see, these number are not too different. In BEM we have 2.141s for fully loaded time and for SMACSS 2.188s . I repeated tests twice and for first time I had
2.080s, 2.534s, 2.141s for BEM
2.131s, 2.229s, 2.126s for SMACSS.
However, for the second time
0.337s, 0.144s, 0.110s for BEM
0.338s, 0.275s, 0.301s for SMACSS
So, for the second time we have quite better results for BEM, but for the first time the results are almost equal.
Here we can see separate speed for html and css.
129ms and 318ms for BEM
125ms and 239ms for SMACSS
This should mean something, shouldn’t it?
Sorry, but NO. Did you see these numbers? They mean nothing, that 2 or 5 ms can be just testing issue with connection to unsplash(where I get images) or google fonts, but that truly doesn’t mean that SMACSS or BEM is better. Look at these numbers once again, and look at “Bytes in” numbers. Now you understand all the magic.
The end of the story
Thats all, guys. Now you know all the truth about SMACSS and BEM ways. I tried to enumerate all positive and negative issues in both our warriors, so make your own conclusion. What about me, I will use SMACSS as I did it previously. But you have to choose your weapon for fight.