W3C home > Mailing lists > Public > www-style@w3.org > July 2014

Re: [Proposal] A property selector

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Wed, 23 Jul 2014 11:20:37 -0700
Message-ID: <CAAWBYDDoL4rZP96dA-qFZGHW2M5OKV=hmMTpDQVkHnhCs-LAQA@mail.gmail.com>
To: Michaël Rouges <michael.rouges@gmail.com>
Cc: www-style list <www-style@w3.org>
On Wed, Jul 23, 2014 at 10:49 AM, Michaël Rouges
<michael.rouges@gmail.com> wrote:
> Hi all,
>
> At work, I found a funny and usefull idea missing in CSS.
>
> I'm surely not the first, maybe proposed or planned but, if not...
>
> The goal is to have a selector that matches on CSS properties (or property
> values).
>
> It usefull to make custom stylesheets (like one by user, overloading a
> default stylesheet), to easily add/change some properties on a lot of
> elements with common property/properties.
>
> But where is all his power is in Javascript, since it allows to do much more
> than add style! :P
>
> I let you to think on its capabilities and on a syntax proposal. ;)

Unfortunately, this isn't possible to do.  It suffers from basic
circularity problems.  For example:

div {
  display: block;
}
div:property(display:block) {
  display: inline;
}

Since the first rule sets the div to display:block, then this selector
will match and set it to display:inline in the second rule.  But that
means the selector doesn't match anymore, so it goes back to being
display:block.  But that means the selector matches again, so it goes
back to being display:inline. Etc.

Many people then try to avoid this by saying you can't set a property
that's used in the selector, so the above would be invalid and safe.
But that doesn't actually stop the problem:

div {
  display: block;
  color: black;
}
div:property(display:block) {
  color: red;
}
div:property(color:red) {
  display: inline;
}

This has the same problem, just with a larger loop. If it's block, it
turns red. If its red, it becomes an inline. But as an inline, it's no
longer a block, so it's no longer red. But if it's no longer red, it's
back to being a block. But that means it's red... etc.  You can have
an arbitrarily-long chain of selectors and values that participate in
a loop like this, and you can't even detect the loop statically,
because you need to apply the rules to a document to see which rules
combine on a single element.

I have a proposal for solving this in more limited cases
<https://tabatkins.github.io/specs/css-toggle-states/#checked-problems>,
but that won't work here, since it would add *all* properties the list
of selector-affecting properties, preventing you from using any
properties at all in a rule containing a :property() selector.  This
obviously isn't very useful for CSS. ^_^

That said, there are use-cases for making it easier for *JS* to figure
out what elements have what properties, such as using custom
properties <http://dev.w3.org/csswg/css-variables/#defining-variables>
and using JS to actually make them have an effect.  I plan to figure
out something for this in the nearish future, so keep an eye out for
either a Level 2 of Variables, or an update to the Extensions spec
<http://dev.w3.org/csswg/css-extensions/> covering more advanced
custom properties handling.

~TJ
Received on Wednesday, 23 July 2014 18:21:24 UTC

This archive was generated by hypermail 2.3.1 : Monday, 2 May 2016 14:39:23 UTC