26

While linting the following SASS statements, I get @extend must be used with a %placeholder warning.

.reg-text {
  color: #202226;
  font-family: $font-page;
  font-size: 17px;
  line-height: 25px;
}

.reg-text-header {
  @extend .reg-text;
  font-weight: 600;
}

What does warning mean and how do I fix it. Afaik, .extend exists for the purpose of extending classes.

AngryHacker
  • 59,598
  • 102
  • 325
  • 594
  • That looks like perfectly legal use of `@extend`: are you sure you are not using some kind of linting option that enforces use of `%placeholders` in conjunction with `@extend`? See: https://github.com/brackets-userland/brackets-sass-lint/blob/master/node_modules/sass-lint/docs/rules/placeholder-in-extend.md or https://github.com/brigade/scss-lint/blob/master/lib/scss_lint/linter/README.md#placeholderinextend—my guess is that your compiler is using one of these linters. – Terry Jan 08 '19 at 01:14
  • @Terry I am looking at the default [linting options](https://github.com/sasstools/sass-lint/blob/master/lib/config/sass-lint.yml). Feature `placeholder-in-extend` is turned on. I can certainly turn it off, but I'd like to know the reasoning behind why they think it's a bad thing. – AngryHacker Jan 08 '19 at 01:38
  • 2
    That’s because if you’re not using placeholders you actually create a new class and the compiler has to comma separate all possible combinations of it. See: http://thesassway.com/intermediate/understanding-placeholder-selectors – Terry Jan 08 '19 at 01:40
  • https://github.com/stylelint-scss/stylelint-scss/blob/master/src/rules/at-extend-no-missing-placeholder/README.md – deamon Apr 06 '23 at 13:29

1 Answers1

29

This is referring to an opinion that using @extend with normal CSS selectors is a bad idea.

I personally agree with this opinion, but it is an opinion nonetheless. Using @extend with any sort of selector is what the Sass spec allows, so I would possibly get in touch with the maintainers of your linter and request that the terminology in your error explains this.

If you use @extend to extend the definition of a selector, every time the selector is extended is is compiled to CSS that includes a reference of the selector for every time the @extend keyword is used.

If, however, you use @extend with placeholder selectors starting with % (A.K.A. "Silent Classes"), the functionality is much more in line with best practices. First off, any unused placeholder selectors are not even rendered to the final CSS (great for building reusable design libraries).

For example, if you have a block of reusable content within a CSS selector, consider converting it to use a placeholder selector instead:

.reg-text {
    color: #202226;
    font-family: $font-page;
    font-size: 17px;
    line-height: 25px;
}

.reg-text-header {
    @extend .reg-text; // this is inefficient and causes specificity issues!
    font-weight: 600;
}

// Instead, do this:

%reg-text {
    color: #202226;
    font-family: $font-page;
    font-size: 17px;
    line-height: 25px;
}

div.your-actual-selector-on-the-page .reg-text {
    @extend %reg-text;
}

div.your-actual-selector-on-the-page .reg-text-header {
    @extend %reg-text; // This compiles much neater and doesn't get in the way of specificity.
    font-weight: 600;
}

Greg
  • 21,235
  • 17
  • 84
  • 107