Recently, WhatIsLove Dev wrote a fantastic article explaining how to write BEM modifiers in pure CSS, similar to Sass. In the example the technique consists in using attribute selectors and parent selectors to make the block + modifier relationship:
.tag-list__tag {
--background-color: var(--color-red-200);
padding-block: 2px;
padding-inline: 6px;
background-color: hsl(var(--background-color) / 30%);
&[class*='--html'] {
--background-color: var(--color-green-100);
}
&[class*='--github'] {
--background-color: var(--color-gray-100);
}
&[class*='--ts'] {
--background-color: var(--color-blue-200);
}
}
To apply a modifier, declare the base and modifier classes on the same element:
<aside class="aside box">
<span class="aside__border aside__border--top">
<!-- omitido -->
</span>
</aside>
I thought
"It would be sick if I could just write the modified class, right? After all, the prefix of the modifier class is the base class (block)."
Suffix and Prefix
The idea is simple: the suffix refers to the base class, and the prefix to its modifiers. The attribute selector supports string start and end searching, so just nest the suffix inside the prefix.
Given a class .card
with modifiers .card--brand
and .card--grey
:
:where([class^="card"]) {
&[class*="--grey"] {}
&[class*="--brand"] {}
}
- ([class^="card"]) - Captures the element's prefix (block)
- &[class="--grey"] - Captures the element's suffix (element/modifier)
Downsides of the Technique
- Attribute selectors are costly in terms of performance because they perform a substring search through the element tree.
- In addition to class name collisions, there will be suffix collisions as well, doubling the need for careful naming.
Check out this CodePen to play around:
Top comments (0)