1

I'm an old hand with CSS, but have recently decided to take the plunge and begin using BEM. For the most part, I understand the value of using such a flat system, avoiding overly specific selectors etc...

My question is, is the following approach correct. It works, technically, but also seems fragile:

.badge {
  /* additional declarations */
  background: rgba(0, 0, 0, 0.2);
}
.badge--error {
  background: red;
}
.badge--success {
  background: green;
}

This works fine, because of the cascading nature of CSS. So the default background is overwritten by the modifier successfully. But if I put the modifier before the initial declaration, the modifier is ignored (because of the equal specificity).

Are there any issues with writing BEM this way? Is it considered bad practice to declare a default value of something like a background within the block, if it's to be overwritten with modifiers? Should the default background in this instance, live in a .badge--default modifier? Or have I written this in a true BEM fashion, and BEM actually relies on CSS' cascading in order to remain flat?

DanMad
  • 1,643
  • 4
  • 23
  • 58
  • Exactly, you're not supposed to use extensions, modifiers, *before* the main *Block*. There's nothing fragile. it's the way CSS specificity works. Globals go on top of your CSS, overrides go toward the bottom. In today's world if you use a CSS preprocessor, it helps you to better structure you model. See the SCSS part in https://stackoverflow.com/a/20811902/383904 – Roko C. Buljan Sep 02 '18 at 09:24
  • 1
    Thanks @RokoC.Buljan, this comment (and the link provided) answer my question. – DanMad Sep 02 '18 at 09:28
  • You're very welcome – Roko C. Buljan Sep 02 '18 at 09:29

1 Answers1

2

You could make use of CSS variables

.badge {
  background: var(--background);
}

.badge--error {
  --background: var(--error);
}

.badge--success {
  --background: var(--success);
}


:root {
  --background: yellow;
  --error: red;
  --success: green;
}
<div class="badge">
  a badge
</div>

<div class="badge badge--success">
  a badge success
</div>

<div class="badge badge--error">
  a badge error
</div>

<div class="badge" style="--background: purple">
  a badge random
</div>

I don't see why a modifier could not modify just a background if it is(n't) set in the initial element.

For BEM I can recommend using a CSS preprocessor like SASS since it make it quite easy to nest elements there is less change of declaring some modifier before the initial declaration. Because of the nesting your CSS becomes much more organised. It is also easier to import different components so each component can live in its own file.

With SASS you can do:

.badge {
  &--error {}
  &--success {}
}
SuperDJ
  • 7,488
  • 11
  • 40
  • 74
  • Thanks for this. I deliberately removed any reference from Sass/SCSS as I was trying to focus on BEM and ascertain whether properties that were to be overwritten with a modifier should live within/or separately to the original block. Will definitely use Sass to save time, though ;) – DanMad Sep 02 '18 at 09:32