@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:
@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.
@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) */ } ```
@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).
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.