Codeskill

Learn to code, step by step

Avoiding specificity wars in compiled output

The CSS SCSS leaves behind: specificity, selector depth, and mixin duplication. The goal is compiled output that other developers (and future you) can override without !important.

Nesting raises specificity

Each nested level adds to the selector weight:

.sidebar {
  .nav {
    a {
      color: $color-text;
    }
  }
}

Compiles to .sidebar .nav a – three elements worth of specificity. One nested rule is fine. Four levels deep is a habit that hurts.

Prefer:

.sidebar-nav-link {
  color: $color-text;
}

Or nest with & on the same class block without chaining tags:

.sidebar-nav {
  &__link {
    color: $color-text;

    &:hover {
      color: var(--color-brand);
    }
  }
}

@extend can bundle selectors

@extend groups selectors sharing the same rules:

%visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
}

.skip-link {
  @extend %visually-hidden;
}

.sr-only {
  @extend %visually-hidden;
}

Compiled CSS lists both classes in one rule. That saves bytes but can create unexpected selector combinations if you extend across components. Use placeholders sparingly; prefer mixins for small snippets unless byte size is critical.

Mixin duplication and bundle size

Every @include copies CSS. A grid mixin included in twenty components outputs twenty copies. Options:

  • Extract a shared class (utility or component).
  • Use custom properties for varying values instead of mixins that only change one property.
  • Generate utilities once with @each instead of per-component includes.

BEM-ish naming without religion

Block-Element-Modifier keeps selectors flat:

.card { }
.card__title { }
.card__body { }
.card--featured { }

You do not need strict BEM everywhere. You do need one convention documented so specificity stays predictable.

Inspect compiled CSS

After compile, open the CSS file. Search for long selectors, repeated mixin output, and rogue !important. Source maps (next tooling tutorial) map compiled lines back to SCSS – use them when debugging cascade issues.

Try it

  • Compile a component with deep nesting and note the selector weight in DevTools.
  • Flatten it with BEM-style classes and compare.
  • Find one large mixin included more than five times – refactor to a class or loop.
PreviousModern CSS features from SCSS