0

I'm having a hard time understanding how to properly write scss with BEM naming conventions.

Here I have some HTML:

<div class="SomeBlock">
   <div class="SomeBlock__someElement">text</div>
</div>

<div class="SomeBlock">
   <div class="SomeBlock__someElement--greenBG">text</div>
</div>

<div class="SomeBlock">
   <div class="SomeBlock__someElement--orangeBG">text</div>
</div>

And the follow scss:

.SomeBlock {
   margin: 10px 0 0 0;
   color: white;
   width: 100px;
   height: 50px;
   background: red;

   &__someElement {
      background: blue;
      text-align: center;

      &--greenBG {
         background: green;
      }

      &--orangeBG {
         background: orange;
      }
   }
}

What I would expect to happen is to have 3 different blocks, all identical but with different colored backgrounds, and this is what happens excepted the text is not centered as I would expect it to be since my element style has text-align: center;

What am I misunderstanding? I've read some tutorials on scss with BEM, but I still do not understand.

dippas
  • 58,591
  • 15
  • 114
  • 126
Chirpizard
  • 291
  • 3
  • 17

3 Answers3

2

Be careful when you reference parent selectors using & in Sass because it does not do what you think it does.

In normal nesting in SCSS, this:

a {
  b {
    /* styling */
  }
}

generates a b { /* styling */ }.

However, when you reference parent selectors using &, this:

a {
  &__b {
    /* styling */
  }
}

turns into: a__b { /* styling */ } // note that this is one class.

What BEM advocates is the use of a systematic way of naming classes to style your document, but manually writing out BEM is a nightmare. Sass parent selector referencing using & makes writing out BEM easy, but you still have to remember that you're only generating class names and not actually nesting when using the & in Sass.

What this all means is that in your case, you'll need to add each of the following classes for your various CSS rules to apply:

<div class="SomeBlock SomeBlock__someElement SomeBlock__someElement--greenBG">text</div>
timolawl
  • 5,434
  • 13
  • 29
1

This is the best way to name classes accordingly to BEM methodology:

/* Block component */

.btn {}

/* Element that depends upon the block */

.btn__price {}

/* Modifier that changes the style of the block */

.btn--orange {} .btn--big {}

Take a look at BEM 101 from CSS Tricks

So I would use it single classes to simplify.

.someblock {
  margin: 10px 0 0 0;
  color: white;
  width: 100px;
  height: 50px;
  background: red;
}
.some__element {
  background: blue;
  text-align: center;
}
.green--bg {
  background: green;
}
.orange--bg {
  background: orange;
}
<div class="someblock">
  <div class="someblock some__element">text</div>
</div>

<div class="someblock">
  <div class="someblock some__element green--bg">text</div>
</div>

<div class="someblock">
  <div class="someblock some__element orange--bg">text</div>
</div>
dippas
  • 58,591
  • 15
  • 114
  • 126
1

Actually, you were a bit closer in using BEM accurately than @dippas. I would modify your code like this:

<div class="some-block">
   <div class="some-block__some-element">text</div>
</div>

<div class="some-block">
   <div class="some-block__some-element some-block__some-element--green-bg">text</div>
</div>

<div class="some-block">
   <div class="some-block__some-element--orange-bg">text</div>
</div>

scss

.some-block {
   margin: 10px 0 0 0;
   color: white;
   width: 100px;
   height: 50px;
   background: red;

   &__some-element {
      background: blue;
      text-align: center;

      &--green-bg {
         background: green;
      }

      &--orange-bg {
         background: orange;
      }
   }
}

Here's simplified outputted css to put things in perspective.

.some-block {
   /* block styles */
}
.some-block__some-element {
   /* element styles */
}
.some-block__some-element--green-bg {
  /* element mod styles */
}

As a general rule, whenever you want to use a modifier you'll need to remember to add the element class an additional time with the modifier. So for your element you have a base class of '.some-block__some-element'. You'll need to add this to all the elements that need this class. Then use that same class and add it again to the element with the modifier. In your example, since you only added that base class to the first occurrence of the three elements, css will naturally only style that one with background: blue, and text-align: center.

Additionally, although you can technically get away with using uppercase class names, I would recommend using lowercase class names and separating multiword names with a single hyphen instead of using upper camel casing.

Sat
  • 170
  • 15