Modular CSS / BEM Methodology Flashcards
What does modular CSS means?
Modular CSS means breaking the page up into its component parts. These parts should be reusable in multiple contexts, and they shouldn’t directly depend upon one another. The end goal is that changes to one part of your CSS will not produce unexpected effects in another.
Source: Keith J. Grant (2018). CSS in Depth. Manning Publications.
What is the problem with context dependent selectors like .page-header .dropdown
?
With modular CSS, such selector is strictly forbidden. Because it leads to many problems down the road:
- Where do you place the code on the header styles or on the dropdown styles.
- This approach increases the selector’s specificity. To overwrite it we will need to increase the specificity even more.
- It is not reusable if you later need the same styles outside of the header or somwhere else you will need to add a new selector to the CSS ruleset. A better selector would have been
.dropdown--dark
for example. - Such practice leads to very long selectors tightly coupled to a specific place on a specific page.
- Rules become hard to find as individual elements are targeted by pieces of code in multiple disparate parts of the stylesheet.
- It becomes more and more difficult to understand the organization of the stylesheet and how it’s doing what it does to the page.
- Even the tiniest changes to the page can break a huge portion of its styling. Deleting old code becomes unsafe because nobody knows what it does and whether it’s still important.
Never use descendant selectors to alter a module based on its location in the page.
Source: Keith J. Grant (2018). CSS in Depth. Manning Publications.
How can you write a module’s variant styles?
You could use --
or _
if you are using BEM.
For example:
.button { /* . . . */ } .button--error { /* . . . */ } .button--success { /* . . . */ }
Source: Keith J. Grant (2018). CSS in Depth. Manning Publications.
What is BEM?
BEM (Block, Element, Modifier) is a component-based approach to web development. The idea behind it is to divide the user interface into independent blocks. This makes interface development easy and fast even with a complex UI, and it allows reuse of existing code without copying and pasting.
Source bem.info
What is a BEM Block?
A functionally independent page component that can be reused. In HTML, blocks are represented by the class attribute.
Features:
- The block name describes its purpose (“What is it?” — menu or button), not its state (“What does it look like?” — red or big).
- The block shouldn’t influence its environment, meaning you shouldn’t set the external geometry (
margin
) or positioning for the block. - You also shouldn’t use CSS tag or ID selectors when using BEM.
- Blocks can be nested inside other blocks
This ensures the necessary independence for reusing blocks or moving them from place to place.
Source bem.info
What is a BEM Element?
A composite part of a block that can’t be used separately from it.
Features:
- The element name describes its purpose (“What is this?” — item, text, etc.), not its state (“What type, or what does it look like?” — red, big, etc.).
- The structure of an element’s full name is
block-name
_
_
element-name
. The element name is separated from the block name with a double underscore (_
_
).
Source bem.info
When should I create a block or an element?
Create a block
If a section of code might be reused and it doesn’t depend on other page components being implemented.
Create an element
If a section of code can’t be used separately without the parent entity (the block).
The exception is elements that must be divided into smaller parts – subelements – in order to simplify development. In the BEM methodology, you can’t create elements of elements. In a case like this, instead of creating an element, you need to create a service block.
Source bem.info
What is a BEM modifier?
An entity that defines the appearance, state, or behavior of a block or element.
Features:
- The modifier name describes its appearance (“What size?” or “Which theme?” and so on — size_s or theme_islands), its state (“How is it different from the others?” — disabled, focused, etc.) and its behavior (“How does it behave?” or “How does it respond to the user?” — such as directions_left-top).
- The modifier name is separated from the block or element name by a single underscore (
_
).
Source bem.info
Types of BEM modifiers
Boolean
- Used when only the presence or absence of the modifier is important, and its value is irrelevant. For example,
disabled
. If a Boolean modifier is present, its value is assumed to betrue
. - The structure of the modifier’s full name follows the pattern:
block-name_modifier-name block-name\_\_element-name_modifier-name
Key-value
- Used when the modifier value is important. For example, “a menu with the islands design theme”:
menu_theme_islands
. - The structure of the modifier’s full name follows the pattern:
block-name_modifier-name_modifier-value block-name\_\_element-name_modifier-name_modifier-value
Source bem.info
What is a BEM mix?
A technique for using different BEM entities on a single DOM node.
Mixes allow you to:
- Combine the behavior and styles of multiple entities without duplicating code.
- Create a semantically new UI components based on existing ones.
Example:
<!-- `header` block --> <div class="header"> <!-- The `search-form` block is mixed with the `search-form` element from the `header` block --> <div class="search-form header\_\_search-form"></div> </div>
In this example, we combined the behavior and styles of the search-form
block and the search-form element from the header block. This approach allows us to set the external geometry and positioning in the header
_
_search-form
element, while the search-form
block itself remains universal.
Source bem.info
BEM naming rules
block-name\_\_element-name_modifier-name_modifier-value
- Names are written in lowercase Latin letters.
- Words are separated by a hyphen (
-
). - The block name defines the namespace for its elements and modifiers.
- The element name is separated from the block name by a double underscore (
_
_
). - The modifier name is separated from the block or element name by a single underscore (
_
). - The modifier value is separated from the modifier name by a single underscore (
_
). - For
boolean
modifiers, the value is not included in the name.
Source bem.info
BEM Single Responsability principle
Every CSS ruleset must have a single responsibility. In other words, It should do one job well and one job only.
Example:
Correct - Defines external geometry i.e. how the element positions in the block
.header\_\_button { margin: 30px; position: relative; }
Incorrect - Defines external geometry, typography and cosmetics
.header\_\_button { font-family: Arial, sans-serif; position: relative; border: 1px solid black; margin: 30px; color: #ececec }
Single responsibility selectors give the code more flexibility.
Source bem.info
BEM Open/closed principle
Any HTML element on a page should be open for extension by modifiers, but closed for changes. You should develop new CSS implementations without needing to change existing ones.
Source bem.info
BEM DRY(“don’t repeat yourself”) principle
DRY (“don’t repeat yourself”) is a software development principle aimed at reducing repetitions in code.
In relation to the BEM methodology, the essence of this principle is that each BEM entity must have a single, unambiguous representation within the system.
Example
Don’t do this:
.button { font-family: Arial, sans-serif; text-align: center; color: #000; background: #fff; } .btn { font-family: Arial, sans-serif; text-align: center; color: #000; background: rgba(255, 0, 0, 0.4); }
Its better to do create modifier selectors for the button element
.button { font-family: Arial, sans-serif; text-align: center; } .button_theme_islands { color: #000; background: #fff; } .button_theme_simple { color: #000; background: rgba(255, 0, 0, 0.4); }
Note: The above is also a good example of the Single Responsability principle
Source bem.info
BEM Composition instead of inheritance principle
Inheritance is a mechanism for defining a new CSS class based on an existing one (a parent or base class). The derived class can add its own properties, as well as use the parent properties.
New CSS implementations are formed in BEM by combining existing ones. This keeps the code uncoupled and flexible.