sass
sass copied to clipboard
automatic reordering of child selectors causes issues with cascading
I know it was a design choice to put nested rules below the parent rule, regardless of source ordering, and I vaguely remember it being about reducing bloat. However, to me it doesn't follow the principle of least surprise: I would expect it to follow the ordering I chose. In cases like
.parent {
margin: 1em 0;
.child { padding: 1em; }
color: red;
}
My expected output would be
.parent { margin: 1em 0; }
.parent .child { padding: 1em; }
.parent { color: red; }
which duplicates the .parent selector, I know. But I feel like that should be my choice, so I can order my selectors in a predictable fashion. It can cause cascade surprises, especially when I'm doing something like this:
@mixin reset-link-styles {
&, &:visited, &:hover, &:active {
text-decoration: none;
color: inherit;
// etc...
}
}
.class {
@include reset-link-styles;
color: red;
}
Which unexpectedly puts the reset below the color: red, nullifying that declaration.
I've also noticed that it still reorders even when the child selector isn't preceded by any styles pertaining to the parent class, as in:
.class1 {
.class2 { color: green; }
color: red;
}
Even though .class2 isn't at risk of breaking .class1 in half, it still gets output afterwards.
I realise that this is a subtle issue that requires careful thought, so I'm not expecting anyone to say "oh, we'll change that right away sir" -- just wanted to post my thoughts and inspire some conversation. I've got a workaround for the reset example -- putting all the styles that should appear afterwards in their own & selector:
.class {
@include reset-link-styles;
& { color: red; }
}
but it feels finicky.
My inclination would be to dispense with optimisation and leave that responsibility to users, but I realise I'm just one user among many, some of whom might appreciate this feature!
If I had the decision to make over again from the beginning, I'd probably have it follow your expected semantics. At this point, though, there's a lot of Sass out there whose behavior this could potentially change in subtle and difficult-to-track-down ways. I don't know that the benefit is worth that level of backwards incompatibility.
That said, if we did decide this was important, we do have room for some breaking changes in 4.0. We could also warn about it earlier than that and even make sass-convert re-order peoples' source to preserve the old behavior. @chriseppstein, what do you think?
@nex3 I think the proposed behavior is more in line with the way we handle directive bubbling and would make sass more consistent. There are some theoretical changes to cascade resolution if we made this change. We can detect this (same property used by a selector with the same specificity) and deprecate it. Honestly, I don't think it will affect that many users. They can either move the property or repeat the selector during the deprecation phase.
I think it's a good change to make, but I also don't consider it high-priority. this behavior has been in place since day one and we haven't gotten many complaints.
@nex3 and @chriseppstein Thanks for the consideration -- I can imagine that it's a difficult issue now that this is out in the wild. I figured that a number of people would be relying on the current behaviour (either intentionally or unintentionally). I thought of suggesting a compiler option, but that doesn't feel right because a Sass file should always compile down to the same CSS file (compression settings notwithstanding).
Anyhow, if nothing ever happens on this front, I'll be okay. I've got other ways to skin this cat; e.g., the above pattern where I wrap the remaining stuff in an & { } selector.
Okay, I'll mark this as planned. I agree that this isn't too impactful, but it would be nice to get it in for 4.0 just because that's a good site for breaking changes. I won't block the release on it, though.
Wow, thanks!
(By the way, when on earth do you guys find time to work on Sass? I presume you both have other sources of employment, although I'm sure Sass garners you wads of money :wink:)
Google has a concept of "20% time" when employees can work on projects in line with the company's goals but unrelated to their normal job. That's how I do it; every Friday is my Sass day.
Ah, now it all makes sense. Must be fun; I've always wanted to have a job with 20% time. Instead I just try to incorporate whatever fun and interesting things I can into our projects in a useful way. Like writing our Sass theme library :smiley: