W3C home > Mailing lists > Public > www-style@w3.org > October 2008

Re: Selector Sugar

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Wed, 15 Oct 2008 10:00:39 -0500
Message-ID: <dd0fbad0810150800p7f83d244g3420a8294fe4871c@mail.gmail.com>
To: Simetrical <simetrical@gmail.com>
Cc: "Brad Kemper" <brkemper.comcast@gmail.com>, "W3C Style List" <www-style@w3.org>, "François REMY" <fremycompany_pub@yahoo.fr>
On Fri, Oct 10, 2008 at 11:07 AM, Simetrical <simetrical@gmail.com> wrote:

> On Thu, Oct 9, 2008 at 11:53 AM, Tab Atkins Jr. <jackalmage@gmail.com>
> wrote:
> > ...with the :any pseudoclass being simple sugar that stands for any of
> the
> > selectors contained within it.  :any should accept arbitrary selectors,
> > separated by commas
>
> Of course you just mean "should accept arbitrary selectors" here --
> "#top-courses, #additional-courses" is already a single valid selector
> that does what you want, no need to specify the commas specially.


Ah, okay.  I wasn't thinking of a comma-separated list of selectors as a
selector itself.  Consider my language suitably altered.  Of course, it
might still be good to specifically call out the "with commas" part to
ensure that it's clear that this is supposed to take multiple things.


> I feel as though this might get complicated if you allow arbitrary
> selectors to go in :any() (which should really be called something
> like :match(), since it would operate on single selectors).  This
> isn't just syntactic sugar, is it?  It really opens up the capability
> to select things that are not currently possible to select.  It
> basically allows arbitrary ANDing of selectors, when currently we only
> have OR.  In other words,
>
> A:match(B):match(C)...
>
> will match anything that matches A and B and C and ... As a practical
> example, consider something like
>
> div span:match(span + span)
>
> which matches a span that has a div ancestor *and* is immediately
> preceded by a span.  I'm pretty sure there's no possible way to do
> this with current CSS selectors, so it's not just semantic sugar.
>
> You might have had somewhat different semantics in mind, though?


Well, that selector wouldn't be worth very much.  As noted down earlier,
it's equivalent to "div span + span", because it matches all "div span" and
also requires that the span be matched by "span + span".  Just putting a
single thing in the :match() shouldn't ever gain you anything.  (To resolve
any lingering confusion, this wouldn't allow you to backdoor the "match if
element has a particular child" or related proposals.)

> since it's basically just performing a simple textual
> > substitution in the selector.
>
> Not if you allow arbitrary selectors to be put in . . . if you just mean
> that
>
> foo :any(a, b, c) bar :any(d, e)
>
> should be substituted for
>
> foo a bar d, foo a bar e, foo b bar d, foo b bar e, foo c bar d, foo c bar
> e


Originally I'd meant just that, but now I realize we can allow the more
advanced syntaxes below.


> then it's not really a pseudo-class, or at least doesn't behave like
> one.  Is "div:any(.a, ::first-line) span" a syntax error?  Is
> "div:any(.a +, .b ~)span"?  Is ":any(strong +, em ~) span" supposed to
> parse the whitespace before "span" as insignificant instead of as a
> descendant selector (which would be a change in the parsing model,
> right?).


"div:any(.a, ::first-line) span" is equivalent to "div.a span,
div::first-line span".
"div:any(.a +, .b ~)span" is a syntax error, because the contents of :any
aren't selectors, they're selector fragments.  Same with ":any(strong +, em
~) span" (though that could be done by ":any( strong + span, em ~ span)" ).

Should div:any(.a, .b) be allowed?  If so, should it be interpreted as
> "div.a, div .b" (whitespace becomes significant!) or "div.a, div.b"?
> If the latter, you would just ban the descendant selector from
> beginning or ending one of the arguments to :any()?


"div:any(.a, .b)" is equivalent to the latter, "div.a, div.b".  There's no
need for special language about the descendant combinator, or any combinator
at all, as you can't start or end a valid selector with a combinator.

What are the semantics of putting :any() in weird places?  Would it
> work inside :not()?  (It should if it's syntactically a pseudo-class.)


I don't see why not, unless :not() itself disagrees (it has some specific
restrictions of its own).  This *would* finally allow something to be
matched that couldn't within the core syntax, because of how logical-not
interacts with logical-and and logical-or.

If you're trying to envision this as a preprocessing sort of
> directive, I'm pretty sure it would require core syntax changes,
> unless you limited it very sharply.


Originally I did, but going over your email I see how it would work as a
true pseudoclass (and that working as a true pseudoclass is much better than
it working as a preprocessor directive).  It simply represents a special
(pseudo-)class that is (pseudo-)applied to any element which is matched by
the expression within the :any().  From there, it works exactly as a
pseudoclass is supposed to.  Treat it exactly the same as you would, say,
:visited.

I do think the first proposal would be nice, though, and likely not
> problematic.  If I understand correctly, at-rules can be added without
> changing the core grammar, as long as they nest braces properly.


Excellent.  I'm not trying to shake up nesting with the @scoped() proposal,
so it would be nice if it was easy to add.

~TJ
Received on Wednesday, 15 October 2008 15:01:20 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 27 April 2009 13:55:15 GMT