A component-based approach used in the BEM methodology also determines the way that BEM projects are organized in a file system. In BEM, it's not just the interface that is divided into independent components, i.e. blocks, but the implementation of blocks is also divided into independent parts, namely files.
Below on this page you will find:
In a BEM project, the code is broken down into small independent parts, to make working with individual blocks easier. Before they are sent to the browser, the files are assembled and optimized. That way we separate the human-manipulated code from the code that is sent to the browser.
In the file system, the codebase of BEM project is organized according to the following principles:
A file set for a block (e.g., input.css
, input.js
) is determined by the technologies that make up the implementation of the block.
Why?
Why?
Block files are grouped together based on common naming rules. For convenience, they can be grouped into a block directory.
Why?
The final implementation of a block can be split into redefinition levels.
Why?
For every block, there's a directory in the file system. The directory is named after the block.
blocks/
input/ # input block directory
button/ # button block directory
A block implementation is divided into separate files known as technology files. The files all have the same name as the block. The extension of each file corresponds to its technology.
blocks/
input/
input.css # input block implementation in CSS
input.js # input block implementation in JavaScript
button/
button.css
button.js
button.png
Names of files and directories for BEM entities are based on the naming convention:
block__elem.extension
(input__box.css
).block_mod_val.extension
(input_type_search.css
) or block_mod.extension
(input_disabled.css
). Values of boolean modifiers are not included.block__elem_mod_val.extension
(input__clear_size_large.css
) or block__elem_mod.extension
(input__clear_visible.css
).Modifiers and elements are stored in separate files and are grouped into accordingly named block subdirectories.
blocks/
input/
_type/ # type modifier directory
input_type_search.css # Implementation of modifier type
# with value search in CSS technology
__box/ # box element directory
input__box.css
input.css
input.js
button/
button.css
button.js
button.png
If there are modifiers that differ in value (e.g., popup_target_anchor.extension
and popup_target_position.extension
), the shared code can be stored in a separate file (popup_target.extension
) with no modifier value included in the name.
blocks/
popup/
_target/
popup_target.css # Common code of modifier target
popup_target_anchor.css # Modifier target with value anchor
popup_target_position.css # Modifier target with value position
_visible/
popup_visible.css # Boolean modifier visible
popup.css
popup.js
The implementation of a block can be divided into redefinition levels.
Let's take a few examples:
A library can be linked to a project as a separate level. Blocks can be modified (extended or redefined) at another project level. During the build process the original block implementation will be linked from the library level and the redefined one from the project level.
Such an arrangement allows us to preserve changes made to the blocks if the library gets updated — the library source code will be updated while the specific implementation of the project blocks will remain the same because it is stored at a different level.
library.blocks/
button/
button.css # CSS implementation in the linked library (height 20px)
project.blocks/
button/
button.css # Redefinition of CSS implementation (height 24px)
A project is divided into platforms (mobile
and desktop
) and into respective redefinition levels in the file system. The common
level contains the implementation of blocks that is common to both platforms. The desktop
and mobile
levels contain platform-specific block implementations.
Let's look at an example:
common.blocks/
button/
button.css # Generic CSS implementation of the button
desktop.blocks/
button/
button.css # Desktop platform-specific button features
mobile.blocks/
button/
button.css # Mobile platform-specific button features
During the build process, all the generic CSS rules for the button will be included in the desktop.css
file from the common
level, and the redefined rules from the desktop
level.
@import(common.blocks/button/button.css); /* Generic CSS rules */
@import(desktop.blocks/button/button.css); /* Desktop platform-specific */
The mobile.css
file will include the generic CSS rules for the button from the common
level and the redefined rules from the mobile
level.
@import(common.blocks/button/button.css); /* Generic CSS rules */
@import(mobile.blocks/button/button.css); /* Mobile platform-specific */