Skip to content

[extend-rule]  #1855

@jonathantneal

Description

@jonathantneal

As a CSS author, I want to re-use styles from other rules. I don’t want to (and often can’t) do this in HTML by stringing classnames together (the Atomic CSS strategy).

I caught a glimpse of a solution to this problem behind a flag in Chrome with the @apply feature. Its author, @tabatkins has rightly pointed out that this solution is problematic, and it has since been abandoned.

In its place, I propose we bring in a simplified version of the Sass @extend rule.

The @extend rule allows authors to declare that certain elements, such as everything matching .serious-error, must act as if they had the necessary features to match another selector, such as .error. So that:

.error {
  border: thick dotted red;
  color: red;
}

strong {
  font-weight: bolder;
}

.serious-error {
  @extend .error, strong;
}

Is equivalent to:

.error {
  border: thick dotted red;
  color: red;
}

strong {
  font-weight: bolder;
}

.serious-error {
  border: thick dotted red;
  color: red;
  font-weight: bolder;
}

A straight-forward thing about the Sass @extend rule is that styles pulled in from the strong selector are now weighted by the .serious-error selector. This means I don’t have to think about whether some other, higher-weighted selector is actually blocking the styles I am trying to pull in.

Unfortunately, the Sass version of @extend has sometimes been discouraged because it re-orders rules in order to group any extended selectors together and reduce the final output code. I recommend we drop that part of Sass extend, and instead treat the extend rule as plain simple substitution.

If possible, I would also like to see us bring in the Sass companion to the extend rule; the placeholder selector. These are simple selectors which do not match elements. So that:

%media-block {
  overflow: auto;
}

%media-block > img {
  float: left;
}

.image-post {
  @extend %media-block;
}

is equivalent to:

.image-post {
  overflow: auto;
}

.image-post > img {
  float: left;
}

Here is a link to a specification which covers this, originally by Tab Atkins: https://jonathantneal.github.io/specs/css-extend-rule/

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions