RSS FeedTwitterMastodonBlueskyShare IconHeart IconGithub IconArrow IconClock IconGUI Challenges IconHome IconNote IconBlog IconCSS IconJS IconHTML IconShows IconOpen Source Software IconSpeaking IconTools IconShuffle IconNext IconPrevious IconCalendar IconCalendar Edit IconNotebook IconObservable Notebooks IconSlash IconGoogle G 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.

8 mentions #

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

Join the conversation on

@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 ????????‍????