I'm using a BEM approach to writing html + css. With this syntax:
I get confused when I have a block within another block. For instance, in a header, I want the header to be a block that I can reference and the nav and logo to be blocks. I want to reference those nav and logo blocks as being the within the site_header. But, how would I write that? Chaining blocks like block_name__sub_block_name seems quite long.
Does anyone have a typical way they would write this example?
<div class="site_header__logo">
<a class="site_header__logo__link">
<img class="site_header__logo__image">
</a>
</div>
<nav class="site_header__main_nav">
<ul>
<li class="site_header__main_nav__item">
<a class="site_header__main_nav__link">Home</a>
</li>
<li class="site_header__main_nav__item">
<a class="site_header__main_nav__link">About Us</a>
</li>
<li class="site_header__main_nav__item">
<a class="site_header__main_nav__link">Contact Us</a>
</li>
</ul>
</nav>
<div class="site_header__phone">
<p class="site_header__phone__number">
555.555.5555
</p>
</div>
The BEM approach ensures that everyone who participates in the development of a website works with a single codebase and speaks the same language. Using proper naming will prepare you for the changes in design of the website.
BEM names intentionally use double underscores and double hyphens instead of single to separate Block-Element-Modifier. The reason is so that single hyphens can be used as word separators. Class names should be very readable, so abbreviation isn't always desirable unless the abbreviations are universally recognizable.
BEM stands for block, element, and modifier. It's a naming convention that divides the user interface into small, reusable components that will prepare us for the changes in design of our websites. This convention also enhances the cross-site copy/paste feature by helping make elements reusable components.
What is BEM? BEM is a front-end naming method for organizing and naming CSS classes. The Block, Element, Modifier methodology is a popular naming convention for class names in HTML and CSS. It helps to write clean CSS by following some simple rules.
I think the logo, main header, and phone fit in the definition of block
which is given in BEM website as:
A block is an independent entity, a "building block" of an application. A block can be either simple or compound (containing other blocks).
What you have got is three simple blocks (logo, main_nav, and phone) within a compound block (site_header). It is actually very similar to the HEAD compound block that is given as an example on the BEM methodology definitions page.
So I would write it this way:
<div class="logo">
<a class="logo__link">
<img class="logo__image">
</a>
</div>
<nav class="main_nav">
<ul>
<li class="main_nav__item">
<a class="main_nav__link">Home</a>
</li>
<li class="main_nav__item">
<a class="main_nav__link">About Us</a>
</li>
<li class="main_nav__item">
<a class="main_nav__link">Contact Us</a>
</li>
</ul>
</nav>
<div class="phone">
<p class="phone__number">
555.555.5555
</p>
</div>
If you think that "logo" is way too generic as a name and wouldn't represent the other types of logos in the project feel free to give it a different name like "company_logo".
In terms of styling, BEM suggests using block modifiers and element modifiers to represent their different styles. For example if you wanted to have your phone number in bold, then you can create a class modifier for it in CSS and apply it to your HTML as follows:
.phone__number--bold {
font-weight: bold;
}
<div class="phone">
<p class="phone__number phone__number--bold">
555.555.5555
</p>
</div>
Modifiers are the preferred way over styling blocks within other blocks. So don't do this:
.site_header .phone__number {
font-weight: bold;
}
I think there is one exception to this which is when you want to give "location-dependant styles" to the block inside. Let's say that you want to give a left margin to the "logo" block. Instead of creating a modifier like:
.logo--push_20 {
margin-left: 20px;
}
it is better to follow OOCSS second principle - Separate container and content - and leave the job to the container:
.site_header .logo {
margin-left: 20px;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With