- From: François REMY <francois.remy.dev@outlook.com>
- Date: Sat, 31 Jan 2015 13:56:32 +0100
- To: "'Tab Atkins Jr.'" <jackalmage@gmail.com>, <public-houdini@w3.org>
± De : Tab Atkins Jr. [mailto:jackalmage@gmail.com] ± ± Several years ago, the Sass preprocessor adding the @extend rule, which lets ± you declare that one selector "extends" another base selector, so that any ± rules that apply to elements matched by the base selector also apply to ± elements matched by the extending selector. ± ± For example, you can "extend" a .error class with a .serious-error class, easily ± applying all the basic .error styling to your .serious-error elements as well. ± This lets you avoid duplicating anything - you don't need to put class="error ± serious-error" in your HTML, or ".error:hover, .serious-error:hover" in your ± CSS selectors, or manually copy over the .error styling into .serious-error ± ruels. ± ± In August 2012, dbaron suggested something extremely similar ± <https://lists.w3.org/Archives/Public/www-style/2012Aug/0363.html>, ± based on a discussion with Yehuda Katz and Nicole Sullivan (Nicole provided ± the original inspiration for @extend in Sass). I pointed out that this was just ± @extend with a different, slightly more awkward, syntax. ± ± In January 2013, Philip Walton also proposed something extremely similar ± <https://lists.w3.org/Archives/Public/www-style/2013Jan/0241.html>, ± and I again pointed out that this was just @extend with a more awkward ± syntax. ± ± I finally got together with Chris Eppstein, one of the primary maintainers of ± Sass, and banged out a spec for @extend as a CSS feature. Natalie ± Weizenbaum, the creator and primary maintainer of Sass, has reviewed it ± and found it acceptable, so I now present it to the group for review: ± <http://tabatkins.github.io/specs/css-extend-rule/> ± ± This proposal adds the @extend rule, based on the semantics defined by ± Sass. It also adds the "placeholder selector", which is similar to a class ± selector, but no aspect of the DOM can cause an element to match it. ± Experience with Sass shows that this is extraordinarily useful in practice, as it ± lets you safely design styles without having to worry about accidentally ± clashing with an existing classname, and then just @extend elements into ± matching it. ± ± To be precise, the semantics of @extend is that it causes elements to act as if ± they have whatever additional features are necessary to match the ± extending selector. For example, in the following rule: ± ± ``` ± .serious-error { ± @extend .error; ± font-weight: bold; ± } ± ``` ± ± Any element matching .serious-error is treated as if it also has the .error class ± (as that's what's required in order to match the .error selector). All selectors ± in the document that mention .error now potentially apply to .serious-error ± elements as well. ± ± There are more examples in the document, so I won't reproduce them here. ± ± The @extend rule has been one of the most popular and useful features in ± Sass since its introduction. It can only be imperfectly implemented in Sass via ± selector rewriting (a naive implementation runs into combinatorial ± explosions; Sass uses heuristics to tell which selectors are "most likely" to be ± important and only exports those).. ± We can implement it perfectly in the browser by actually affecting matching, ± and bring this super-popular tool to millions of authors using plain CSS. ± ± Thoughts? Hi Tab, I fully understands this first draft is only a "flex-basis" for discussion, but given it's what I have at hand, I'll comment on the document itself more than on the idea; I'll read the minutes of the next Houdini meetings for ideological matters ^_^ So. I had a look at the specification, but I remained hungry for more after reading it. I know it's not always the role of a specification to tell the "imperative story" of the things it defines, but in this particular case I wasn't satisfied with the "functional story". As a starter, I would have loved to see a selector matching algorithm which is conforming this specification; I'm interested in particular in how we can implement this in a single-phase matching, if that's possible. My thoughts is that you can't perform this in a single matching phase and will first need to match rules containing @extend rules, modify the "matchable dom" and repeat until no more additional changes is made to the matchable dom. This means that selector matching now needs to be performed top-down as selector matching for an ancestor may affect what rules match one if its children as a result of the mutated matchable dom; this may harm the parallelization of matching. That being said, maybe some other characteristics of css matching already do so; that's why I would have liked to see this discussed. I also wonder what might be the performance impact (but I guess only a prototype might inform us). My second thought is this simply isn't going to be easy to create a consistent matchable dom using @extend. I have some examples: :not(.open) { @extend .open } .open { @extend :not(.open) } .a { @extend .b } .b { @extend :not(.a) } <div> <e1/> <e2/> </div> :not(button) + e2 { @extend button } :nth-last-child(2 of button, e1) { @extend button } It may also be hard to manage security restrictions: a:visited { @extend button } It's maybe possible to resolve those cases in a sensible way, but it may be harder than it looks at first sight when reading the spec. Happy discussions in Sydney, François
Received on Saturday, 31 January 2015 12:57:11 UTC