Why does SASS modify chained selectors of the same name when using extend?

Viewed 103

Given the following HTML / SASS code:

<div class="a">hello</div>

%color {
    color: blue;
}
.a {
  color: red;
}
.a.a {
  @extend %color;
}

I was expecting the resulting color to be blue (due to the more specific .a.a selector1) with output something like this:

.a.a {
   color: blue;
}
.a {
   color: red;
}

But actually, the resulting color is red, with SASS output:

.a {
  color: blue;
}

.a {
  color: red;
}

I find this quite counter-intuitive!

Why does SASS refactor my .a.a selector to .a?

Just in case you don't believe me, here's a codepen demo (click view compiled css to see the CSS output)

NOTE:

This 'refactoring' of the selector only occurs to the declarations within the extend.

So in the following SASS:

%color {
    color: blue;
}
.a.a {
  @extend %color;
  position: relative;
}

The output is:

.a {
  color: blue;
}

.a.a {
  position: relative;
}

(Codepen demo)


1See the spec:

Note: Repeated occurrences of the same simple selector are allowed and do increase specificity.

1 Answers

By the looks of it, the result depends on the parsing engine. If you use DartSass v1.6.2 (default on sassmeister.com), it outputs your expected result:

.a.a {
  color: blue;
}

.a {
  color: red;
}

Check on sassmeister.com (you can also switch parsing engines there).

LibSass v3.5.2 creates the result you complained about:

.a {
  color: blue;
}

.a {
  color: red;
}
Related