How to compose multiple classes into a single semantically-named class?

sass

Solution

Is this just not something Sass was designed to do?

Sass does support this use case.

What you need is extending.

Have `navbar`, `navbar-default` and `navbar-fixed-top` classes defined as you would with a non-semantic approach:

 .navbar { display: table; }
 .navbar-default { background-color: deeppink; }
 .navbar-fixed-top { position: fixed; top: 0; left: 0; width: 100%; }

Below, extend your `header__navbar` class with those:

.header__navbar {
  @extend .navbar;
  @extend .navbar-default;
  @extend .navbar-fixed-top;
}

Once you get rid of non-semantic classes in your HTML markup completely, you no longer need them in your CSS. So turn them into placeholder selectors aka silent selectors. To do so, replace the `.` with `%` both in the rules where they are defined and in `@extend` directives that use them. E. g.:

 %navbar { display: table; }
 %navbar-default { background-color: deeppink; }
 %navbar-fixed-top { position: fixed; top: 0; left: 0; width: 100%; }

.header__navbar {
  @extend %navbar;
  @extend %navbar-default;
  @extend %navbar-fixed-top;
}

Problem

I've been reading up on Block-Element-Modifier naming conventions, semantically-named style rules, etc. and I'd like to replace multiple class names in my html with a single, semantic class name. Can't seem to make it happen, though. Example: I'd like to replace my Bootstrap navbar `<nav class="navbar navbar-default navbar-fixed-top" role="navigation">` with `<nav class="header__navbar" role="navigation">` I know I could use jQuery to do this procedurally, but I'd prefer not to. I've tried several approaches using variable names, #{} interpolation syntax, mixins, and @extend, etc. but just get syntax errors or invalid results. Is this just not something Sass was designed to do?

Original source