ffxsam
ffxsam

Reputation: 27713

BEM and inheriting properties of other classes

I'm running into a bit of an issue with BEM. I have the following:

<ul className="AppHeader__subnav-links">
  <li className="AppHeader__subnav-link--active">Details</li>
  <li className="AppHeader__subnav-link">Conditions</li>
  <li className="AppHeader__subnav-link">Actions</li>
  <li className="AppHeader__subnav-link">Assets</li>
</ul>

The idea is that the active link will have an underline beneath it. But the problem is that since BEM classes are all “standalone,” and do not cascade, the AppHeader__subnav-link--active does not inherit anything from AppHeader__subnav-link (obviously). Is there a better way for me to structure this? Or do I just have to resort to doing the following:

&__subnav-link {
  // properties

  &--active {
    @extend .AppHeader__subnav-link;
    // properties
  }
}

Upvotes: 0

Views: 230

Answers (1)

zzzzBov
zzzzBov

Reputation: 179046

BEM requires that the modifier is added in addition to the base class.

A corrected version of your markup is:

<ul className="AppHeader__subnav-links">
  <li className="AppHeader__subnav-link AppHeader__subnav-link--active">Details</li>
  <li className="AppHeader__subnav-link">Conditions</li>
  <li className="AppHeader__subnav-link">Actions</li>
  <li className="AppHeader__subnav-link">Assets</li>
</ul>

…since BEM classes are all “standalone,” and do not cascade…

I have to disagree with this statement. BEM classes rely heavily on the cascade for modifiers. It's expected that a base class will be used, and that a modifier will subsequently follow to override the necessary styles for that particular state.

Consider the following CSS:

.widget {
    border-color: gray;
}
.widget--active {
    border-color: black;
}

If the order were interchanged, the modifier would no longer work correctly. BEM relies on the cascade, but attempts to keep specificity low so as to make the most out of it.

Upvotes: 1

Related Questions