How to change multiple block elements using BEM CSS

Let's say I have the following setup,

.block
  .block__header
  .block__content
  .block__footer

      

Now I want to show the active state of this block. Let's say the box itself gets a green background, and items 2 and 3 should have bold text. As far as I understand the BEM philosophy, child selectors should not be used to keep the specificity as low as possible.

So is this really the way to do it?

.block.block--active
  .block__header
  .block__content.block__content--active
  .block__footer.block__footer--active

      

Update: and how would I write this solution in SASS (very new to it)? This is my setup so far ... if I can use nested selectors, what's the best thing here?

.block {
  &--active {

  }
  &__header {

  }
  &__content {
    // active modifier of content
    &--active {
      font-weight: bold;
    }
    // would be the same as
    .block--active & {
      font-weight: bold;        
    }
    // but can i reference the active block somehow else in sass? 
    // & is a parent selector but i would need the parent of the parent here...
  }
  &__footer {
    &--active {

    }
  }
}

      

+3


source to share


1 answer


BEM's philosophy is to keep the block context free. Low specificity is just good practice, not a golden rule. I give three valid solutions below.

If you are sure that a block cannot be recursively included in itself, a simple cascade can be used:

.block--active {
    background-color: green;
}
.block--active .block__element-2,
.block--active .block__element-3 {
    font-weight: bold;
}

      

If the elements are directly in the block, the child selector is valid:

.block--active {
    background-color: green;
}
.block--active > .block__element-2,
.block--active > .block__element-3 {
    font-weight: bold;
}

      

Or a flat solution (but not DRY):



.block--active {
    background-color: green;
}
.block__element-2--active,
.block__element-3--active {
    font-weight: bold;
}

      


With SCSS, there are several ways to write the first solution. Here's the one I'm using:

.block {
    &--active {
        background-color: green;
    }
    &--active &__element-2,
    &--active &__element-3 {
        font-weight: bold;
    }
}

      

See another solution here .

+1


source







All Articles