W3C home > Mailing lists > Public > www-style@w3.org > August 2012

Re: Thinking about mixins as a new type of selector

From: Chris Eppstein <chris@eppsteins.net>
Date: Wed, 15 Aug 2012 19:45:51 -0700
Message-ID: <CANyEp6VVGiusOvZYJ-3Fibb6Qc1h6o44L=XsWY1G0YPD2a1KMg@mail.gmail.com>
To: Brian Kardell <bkardell@gmail.com>
Cc: "Tab Atkins Jr." <jackalmage@gmail.com>, www-style@w3.org, "L. David Baron" <dbaron@dbaron.org>
One thing to note is that in Sass 3.2 (released last week) we have
introduced a new feature for use with @extend called placeholder selectors.

A placeholder selector is like a class, but it would not become part of the
generated CSS (or in a native implementation, cannot be used to match
against the document). We denote a placeholder selector with %.

Near as I can tell, this is exactly what the $ syntax proposed by David is
doing. (hard to tell -- I keep thinking it's a shell variable :P)

Keep in mind, that sass's extend also allows more than extending a simple
selector, we also allow compound selectors, however you cannot extend a
complex selector.

Also extends can be chained, so if A extends B, and B extends C, A will
implicitly extend C.

I think extend is such a simple concept and that it matches the ethos and
structure of CSS very well. But it is exceedingly difficult to implement
@extend in a preprocessor and there a number of cases where we have to
result to heuristics because the formally correct output is impractically
long.

One potential issue that an in-browser implementation can resolve (and Sass
cannot) is what should be the specificity and precedence of extending
selectors. Sass must rewrite selectors and as a result, the specificity
must be that of the extending selector and precedence must be that of the
extended selector. But in-browser, it could be decided that the extended
selector's precedence AND specificity would be used -- I think this may be
much more natural -- it warrants further thought at least.

I'm very pleased to see the WG discussing this. Please feel free to contact
me off list if you need help understanding our implementation or want to
understand our design decisions.

Chris Eppstein

On Wed, Aug 15, 2012 at 5:38 PM, Brian Kardell <bkardell@gmail.com> wrote:

>
> On Aug 15, 2012 8:18 PM, "Tab Atkins Jr." <jackalmage@gmail.com> wrote:
> >
> > I asked David for some more details about how his proposal worked in
> > some corner cases.  With that information, it's clear that this
> > proposal is exactly equivalent to SASS's @extend, just with a more
> > explicit (and I think less convenient) syntax.
> >
> > Here's a few examples to illustrate this, taken from SASS's own
> reference files.
> >
> > Example 1
> > =========
> > SASS:
> > .error {
> >   border: 1px #f00;
> >   background-color: #fdd;
> > }
> > .error.intrusion {
> >   background-image: url("/image/hacked.png");
> > }
> > .seriousError {
> >   @extend .error;
> >   border-width: 3px;
> > }
> >
> > CSS:
> > @matches $error .error;
> > $error {
> >   border: 1px #f00;
> >   background-color: #fdd;
> > }
> > $error.intrusion {
> >   background-image: url("/image/hacked.png");
> > }
> > @matches $error .seriousError;
> > .seriousError {
> >   border-width: 3px;
> > }
> >
> >
> > Example 2
> > =========
> > SASS:
> > .error {
> >   border: 1px #f00;
> >   background-color: #fdd;
> > }
> > .attention {
> >   font-size: 3em;
> >   background-color: #ff0;
> > }
> > .seriousError {
> >   @extend .error;
> >   @extend .attention;
> >   border-width: 3px;
> > }
> >
> > CSS:
> > @matches $error .error;
> > $error {
> >   border: 1px #f00;
> >   background-color: #fdd;
> > }
> > @matches $attention .attention;
> > $attention {
> >   font-size: 3em;
> >   background-color: #ff0;
> > }
> > @matches $error .seriousError;
> > @matches $attention .seriousError;
> > .seriousError {
> >   border-width: 3px;
> > }
> >
> >
> > Example 3
> > =========
> > SASS:
> > .error {
> >   border: 1px #f00;
> >   background-color: #fdd;
> > }
> > .seriousError {
> >   @extend .error;
> >   border-width: 3px;
> > }
> > .criticalError {
> >   @extend .seriousError;
> >   position: fixed;
> >   top: 10%;
> >   bottom: 10%;
> >   left: 10%;
> >   right: 10%;
> > }
> >
> > CSS:
> > @matches $error .error;
> > $error {
> >   border: 1px #f00;
> >   background-color: #fdd;
> > }
> > @matches $error $seriousError;
> > @matches $seriousError .seriousError;
> > $seriousError {
> >   border-width: 3px;
> > }
> > @matches $seriousError .criticalError;
> > .criticalError {
> >   position: fixed;
> >   top: 10%;
> >   bottom: 10%;
> >   left: 10%;
> >   right: 10%;
> > }
> >
> >
> > Example 4
> > =========
> > SASS:
> > #admin .tabbar a {font-weight: bold}
> > #demo .overview .fakelink {@extend a}
> >
> > CSS:
> > @matches $link a;
> > #admin .tabbar $link {font-weight: bold}
> > @matches $link #demo .overview .fakelink;
> >
> > Equivalent Vanilla:
> > #admin .tabbar a,
> > :matches(#admin .tabbar .fakelink):matches(#demo .overview .fakelink) {
> >   font-weight: bold;
> > }
> >
> >
> > (Technically, David's proposal is more powerful. SASS "cheats" in
> > example 4 and actually doesn't quite generate the same thing, to avoid
> > having to generate a combinatorial explosion of selectors.  Similarly,
> > SASS avoids extending things across @media boundaries, so that it
> > doesn't have to duplicate a lot of style, which isn't a problem for a
> > native system.  These are both just implementation difficulties
> > because SASS isn't native; they're not fundamental weaknesses of
> > SASS's @extend.)
> >
> > Overall, I find David's syntax somewhat less convenient than SASS's
> > @extend.  At least in these small examples, it seems like David's
> > syntax moves important information around in a slightly confusing way.
> >  It *may* be better in larger examples, I'm not sure.  It also means
> > that you have to change potentially a lot of code if you later decide
> > you want to extend a particular selector (to change all the instances
> > of the "normal" selector you're using to a variable).
> >
> > I might like a variant of SASS's extend that doesn't nest inside of a
> > declaration block, though, like:
> >
> > .error { ... }
> > .seriousError { ... }
> > @extend .error .seriousError;
> >
> > The first argument would be a compound selector, the second would be a
> > complex selector defined to be equivalent.  I'm not sure if this is
> > easier or harder to read.
> >
> >
> > Anyway, good times.  I approve of motion in this direction.
> >
> > As a final note, this is *not* a replacement for my @mixin suggestion.
> >  This can be used to replace @mixin without any arguments, but Mixins
> > with arguments are powerful and very useful, as SASS demonstrates.
> >
> > ~TJ
> >
>
> Is the SASS/vanilla right in example 4?  If so, can someone explain that?
> I get David's in that example, but how you go from the SASS to that I am
> having trouble following.  Feel free to reply offlist if you think it is
> irrelevant...just wanted to record my confusion and get a correction if
> necessay.
>
Received on Thursday, 16 August 2012 02:46:20 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 17:20:58 GMT