The reason for this behavior is that @extends
are processed in the order they are encountered in the Sass file, grouping all selectors where they are used together at that point (@extends
tends to be a bit greedy), and if you include the @extends
placeholder more than once, it will result in duplicate outputs.
Let's walk through the process:
- Firstly, ios.sass is loaded, defining
$width
and including %child
.
- Sass encounters the placeholder due to the inclusion, collects all instances of the placeholder within the code, groups them with their respective selectors, and applies the current value of width.
- Then, android.sass is loaded, resetting
$width
to a new value and including %child
again.
- Sass repeats the grouping process each time an
@extends
is encountered, resulting in duplicate groupings with different $width
values.
This explains why you see both selectors grouped and repeated twice with varying $width
values in the output.
Solution:
To resolve this issue, using a mixin would be ideal. When a mixin is called, it is evaluated immediately, and the resulting styles are directly injected into the selector.
@mixin custom-width($width-in: 1000px) {
width: $width-in;
}
.ios .child {
@include custom-width(111px);
}
.android .child {
@include custom-width(999px);
}
Now, considering the mixin example:
- The mixin is defined but not applied until called like a function.
- ios.sass loads and defines a selector.
- Sass interprets the mixin call with a parameter, executes the mixin, and inserts the calculated width value into the selector.
- android.sass loads...
- Sass processes another mixin call by injecting a new width value into the corresponding selector.
Note that I have set a default value of 1000px
in my mixin definition, which will be used if @include custom-width();
is utilized without a specific parameter.