RSS FeedTwitterMastodonBlueskyShare IconHeart IconGithub IconArrow IconClock IconGUI Challenges IconHome IconNote IconBlog IconCSS IconJS IconHTML IconShows IconGit IconSpeaking IconTools IconShuffle IconNext IconPrevious IconCalendar IconCalendar Edit Icon
a code example is shown where &[class*='--github'] is the crucial key to simulating a BEM modifier class
A series of images of an avatar doing a bunch of skateboard tricks.1 min read

BEM with native CSS nesting

css

Vladyslav Zubko has a compromise (and probably a deep love for Haddaway); they write BEM with native CSS nesting and thank substring matching selectors for the rad tactics.

How #

They propose this un-bem'ed wetness:

.tag-list__tag {
  --background-color: var(--color-red-200);
  background-color: hsl(var(--background-color) / 30%);
}

.tag-list__tag--github {
  --background-color: var(--color-gray-100);
}

to become this in native CSS:

.tag-list__tag {
  --background-color: var(--color-red-200);
  background-color: hsl(var(--background-color) / 30%);

  &[class*='--github'] {
    --background-color: var(--color-gray-100);
  }
}

Seems legit.

If BEM is your passion, keep calm and substring on.

Mentions #

Join the conversation on

18 likes
8 reposts
  • Apple Annie :prami_pride:
  • Cory :prami_pride_demi:
  • Ironorchid
  • Christian Puffer
  • Vladyslav Zubko
  • Roni Laukkarinen
  • Goncalo Tojeiro
  • Chromium for Developers

@argyleink One of the main ideas behind constructing complex BEM selectors is to keep equal specificity. Otherwise, you won’t be able to redefine them. It’s not the case anymore:

.tag-list__tag--github
0, 1, 0

.tag-list__tag[class*='--github']
0, 2, 0

https://en.bem.info/methodology/css/#combined-selectors

CSS / Methodology / BEM
Vadim MakeevVadim Makeev

@argyleink what good timing. I literally went down this exact same path today on a new client project.

For a few years now I’d been relying on shadow DOM to give me the encapsulating I was looking for because I had such bad memories of global styling historically but figured that so much had changed that I’d just keep everything vanilla HTML/CSS and see what it was like with modern CSS.

MarkMark

@argyleink I like to think of the Shadow DOM’s styling APIs as native BEM (that’s actually encapsulated):

```css

my-block::part(element):state(modifier) {
/* Targeting an element’s part that matches a certain state */
/* I forget if this works today, but I recall seeing a WPT or something saying that it should. */
}

my-block:state(modifier)::part(element) {
/* Targeting a part of an element that matches a certain state (of the element) */
}
```

inb4 shadow DOM styling issues: I know

Nathan KnowlerNathan Knowler

@pepelsbey @argyleink Another thing: tight coupling of all the elements and modifiers with its block, allowing (in theory) mixing multiple blocks/elements on the same HTML element.

Without a namespace, the modifier loses its relation to the block/element, and `[class*='--github']` in this case could match something different (though, in this case, the conflict is unlikely).

Roma KomarovRoma Komarov

@pepelsbey @argyleink

For specificity you could use `:where([class…])` there, but then you kinda lose on the compactness.

But could be something like

.foo {
:where(&) {
&[class…] {…}
}
}

basically, wrap all the modifiers with an extra level of nesting. But then those attribute selectors are not the most optimal ones, so I am not sure if it is worth it.

Roma KomarovRoma Komarov

@pepelsbey @argyleink

…but at that point, why not use just `&:where(.--github)` or something — no reason to keep the block name in the HTML anyway.

Roma KomarovRoma Komarov

@argyleink I’ve felt like I’ve moved past using BEM for a while now, but I appreciate what’s going on to make this work.

Will Browar ????????‍????Will Browar ????????‍????

Crawl the CSS Webring