Blocks — logically and functionally independent, reusable page components. The same blocks can be used in different projects. To prevent these projects from looking identical, blocks can be modified using:
None of these methods for changing a block require you to:
- Copy the block code to make changes.
- Change the original implementation of the block.
- Create a new block based on an existing one.
- Use a modifier to change one specific instance of a block. Setting or removing a modifier should only affect the modified block and have no relationship to the surrounding blocks.
- Use a mix to:
- Place one block inside another block.
- Apply the same style to several different blocks on a page, instead of applying group selectors.
- Use redefinition levels to simultaneously change all the blocks with the same name in the project.
- Use context to define the block style in advance when you don't know what the content of a nested block will be.
The block is changed by setting or removing a modifier containing code that describes the changes. You can add an unlimited number of modifiers to the block at once.
The modifier can define the block's:
Let's use a popup
block as an example for how to change a block using a modifier.
HTML implementation:
<!-- Popup block -->
<div class="popup"> ...</div>
The theme
modifier with the value sun
sets a yellow background for the popup window.
HTML implementation:
<!-- Popup with the "theme" modifier set to "sun"-->
<div class="popup popup_theme_sun"> ...</div>
The direction
modifier determines which way the popup window opens.
For example, the direction
modifier with the value right
opens the popup window to the right.
HTML implementation:
<!-- Popup block -->
<div class="popup popup_direction_right"> ...</div>
The has-tail
modifier with the true
value adds to the popup
block a new element — ”tail“. This modifier also adds offsets to the block to create space for the tail.
Information about when and how to use a boolean modifier.
HTML implementation:
<!-- Popup block -->
<div class="popup popup_has-tail"> ...</div>
The disabled
modifier switches the button
block, which opens the popup window, to the ”disabled“ state. In other words, it turns off the popup window so it can't be shown.
HTML implementation:
<!-- The "button" block with the "disabled" modifier -->
<div class="button button_disabled"> ...</div>
You can add any number of modifiers to a block. For example:
theme
with the valuesun
has-tail
with the valuetrue
HTML implementation:
<!-- Popup block -->
<div class="popup popup_theme_sun popup_has-tail"> ...</div>
The popup window opens at the bottom and has a yellow background and a tail:
The block is changed by placing additional BEM entities on the same DOM node as the block. Mixes allow you to combine the behavior and style of multiple entities without duplicating code.
In the BEM methodology, a block's position on the page is set in the parent block. This allows the blocks to be independent and reusable.
More information about external geometry and positioning.
The example shows a header
block from an integrated library. By default, the header
block doesn't know anything about the position of blocks that are nested in it. To add the logo
, search
, and user
blocks to the header, you need to define the offsets for each nested block:
The header and the nested logo
, search
, and user
blocks must remain independent. For this reason, the position of the nested blocks is set in elements of the header
block that are mixed with the blocks.
HTML implementation:
<!-- "header" block -->
<header class="header">
<div class="logo header__logo"> ...</div>
<div class="search header__search"> ...</div>
<div class="user header__user"> ...</div>
</header>
The styles of the nested logo
, search
, and user
blocks haven't changed, and still don't contain any offsets. The blocks remain independent and can be reused anywhere.
Mixes are used to keep styles consistent in a set of different HTML elements on the page.
Information about why BEM doesn't use global modifiers.
In the example, the text inside the article
and copyright
blocks needs to have the same color and font. To do this, you can mix the text
block, which has styles defining the text color and font, with the article
and copyright
blocks.
HTML implementation:
<article class="article text"> ...</article>
<footer class="footer">
<div class="copyright text"> ...</div>
</footer>
CSS implementation:
.text {
font-family: Arial, sans-serif;
font-size: 14px;
color: #000;
}
Changes are made to the block by combining the block properties from different redefinition levels. Blocks can be extended and redefined. Changes to a block are defined on a separate level and applied during assembly.
More information about how redefinition levels work.
Universal blocks from the library should look different in different projects. All you need to do is connect the library to the project as a separate level, and describe the block changes on a different redefinition level.
Original implementation of the button
block in the library:
To change the button color, redefine the CSS rules for the button
block on the project level (project.blocks
).
File structure with the new rules for the button (button.css
) on the project.blocks
level:
project/
library.blocks/
button/
button.css # original CSS implementation of the button in the library
project.blocks/
button/
button.css # redefinition on the project level
As a result, rules from both redefinition levels will be applied to the button
block:
@import "library.blocks/button/button.css"; /* Original CSS rules from the library level */
@import "project.blocks/button/button.css"; /* Properties from the project.blocks level */
New appearance of the button:
The block is changed by placing one block inside another one. The rules of the parent block cascade down to the nested blocks.
Important You should use context to change the appearance or behavior of a block only when you can't use mixes. Using context to make changes restricts the independence of the blocks.
The most common case for using context to stylize a block is the implementation of blocks for comments in blogs or forums in any CMS.
For example, you can predefine the rules for the main tags that users can apply:
.comments p {
font-family: Arial, sans-serif;
text-align: center;
}