Search code examples
cssfrontendbem

BEM CSS with common styles


I have a bit of confusion when it comes to using global styles. Consider the following:

Say I have a stylesheet that defines how buttons should be made:

/* Button.CSS */
button {
  background-color: #CCC;
}

button.Blue {
  background-color: #00F;
  color: #FFF;
}

Button.Blue.Hollow {
  background-color: none;
  border: 1px solid #00F;
  color: #00F;
}

and then you use the button in the template with your standard BEM notation (I'll use the Block__Element--Modifier notation)

<!-- index.html -->
<ul class="Widget">
  <li class="Widget__Item">
    <button class="Widget__Button"></button>
  </li>
  <li class="Widget__Item">
    <button class="Widget__Button Blue"></button>
  </li>
  <li class="Widget__Item">
    <button class="Widget__Button Blue Hollow"></button>
  </li>
</ul>

Is that the acceptable practice to mix classes like that? I feel like i'm violating some rule of encapsulated block styling.


Solution

  • I feel like i'm violating some rule of encapsulated block styling.

    Indeed. Button should be a block, not an element. Blue and Hollow are modifiers.

    With the Block__Element--Modifier syntax, your code should be:

    .Button {
      background-color: #CCC;
    }
    .Button--Blue {
      background-color: #00F;
      color: #FFF;
    }
    .Button--BlueHollow {
      background-color: none;
      border: 1px solid #00F;
      color: #00F;
    }
    
    <ul class="Widget">
      <li class="Widget__Item">
        <button class="Button"></button>
      </li>
      <li class="Widget__Item">
        <button class="Button Button--Blue"></button>
      </li>
      <li class="Widget__Item">
        <button class="Button Button--Blue Button--BlueHollow"></button>
      </li>
    </ul>
    

    Alternatively, you can use a MyBlock-myElement.myModifier syntax (closer to your way):

    .Button {
      background-color: #CCC;
    }
    .Button.blue {
      background-color: #00F;
      color: #FFF;
    }
    .Button.blue.hollow {
      background-color: none;
      border: 1px solid #00F;
      color: #00F;
    }
    
    <ul class="Widget">
      <li class="Widget-item">
        <button class="Button"></button>
      </li>
      <li class="Widget-item">
        <button class="Button blue"></button>
      </li>
      <li class="Widget-item">
        <button class="Button blue hollow"></button>
      </li>
    </ul>