Ways to modify a block
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.
How to choose a block modification method
- 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.
Using a modifier to change a block
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>Changing the block's appearance
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>Changing the block's behavior
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>Changing the block's structure
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>Changing the block's state
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>Adding multiple modifiers
You can add any number of modifiers to a block. For example:
themewith the valuesunhas-tailwith 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:
Using a mix to change a block
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.
Placing a block inside another block
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.
Styling groups of blocks
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;
}Using redefinition levels to change a block
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.
Example
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 levelAs 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:
Using context to change a block
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;
}