- From: Brian Kardell <bkardell@gmail.com>
- Date: Fri, 5 Apr 2013 19:05:53 -0400
- To: Simon Sapin <simon.sapin@exyr.org>
- Cc: "www-style@w3.org" <www-style@w3.org>
[snip] > :allof() is AND, which is just juxtaposition. In case more than one of > :allof()’s arguments contain a combinator, :matches() comes to the rescue: > > :allof(.foo, .bar) → .foo.bar > :allof(.foo, ol li) → ol li.foo > :allof(.foo .bar, ol li) → .foo .bar:matches(ol li) > > Finally, :oneof() is XOR, which can be expressed as a combination of AND, > OR, and NOT. > > :oneof(.foo, .bar) → .foo:not(.bar), .bar:not(.foo) > > It gets messy with more XOR arguments, but it’s still doable. > > > So, only :oneof() is arguably useful, but is there really an use case for > XOR in selectors to begin with? > > -- > Simon Sapin Let me make a couple of points (some of them restated from post and article): - These are only significant (useful/necessary) if all of them can take complex selectors - Lots of things are currently solved today by modifying the markup or DOM via for presentation purposes and that is less than ideal, it's not the vision. To reach that vision, we need nice semantic markup (global and local semantics) and rich selector capabilities. - :matches and :not are already in there and they probably map to two of these, but neither takes complex selectors yet. - I think pseudos that use well-established mathematical or CS terms is intuitive. As a rule, the examples I've seen are too simplistic to add much benefit anyway.. Here is the example for where the current implementation of :matches (simple selectors) benefits used in David Barron's original blog post[1]: /* 3 deep (or more) unordered lists use a square */ ol ol ul, ol ul ul, ol menu ul, ol dir ul, ol ol menu, ol ul menu, ol menu menu, ol dir menu, ol ol dir, ol ul dir, ol menu dir, ol dir dir, ul ol ul, ul ul ul, ul menu ul, ul dir ul, ul ol menu, ul ul menu, ul menu menu, ul dir menu, ul ol dir, ul ul dir, ul menu dir, ul dir dir, menu ol ul, menu ul ul, menu menu ul, menu dir ul, menu ol menu, menu ul menu, menu menu menu, menu dir menu, menu ol dir, menu ul dir, menu menu dir, menu dir dir, dir ol ul, dir ul ul, dir menu ul, dir dir ul, dir ol menu, dir ul menu, dir menu menu, dir dir menu, dir ol dir, dir ul dir, dir menu dir, dir dir dir { list-style-type: square; } The current :matches is just sugar, but that's not a bad thing - it makes rules considerably more readable and therefore maintainable... It is much easier to reason about something like: :-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) :-moz-any(ul, menu, dir) { list-style-type: square; } Than it is the expanded form (above). So let's not immediately think "sugar is unnecessary" or bad - in fact, there is a benefit to the above in that in theory all you need to do is write the unwinding/expansion and then the underlying support is already in the browser, and there is a benefit that it is easier to write software to reason about that as well - you could potentially speed things up by knowing where the logical forks are. Given support for complex selectors, however, things change even in the overly simplistic examples. You gave: .foo .bar:matches(ol li) We can currently say li.bar, but we cannot actually express the above today: The relationship of .foo and ol is unknown. Is ol a descendent of .foo or vice versa? This allows you to express wholly new things. What is currently called matches would be _extremely_ powerful. So powerful, that with just complex :matches and :not you might be right that (most) everything we need would be there. As I mentioned above, we need something reasonably rich to show the value, so let's use my examples... I called it "anyof", but it could be: /* Style the cars that are foreign and used or domestic, new and effiecient. */ .cars div:matches(.foreign .used, .domestic .new .efficient) p { color: blue; } When I read this, I am personally unsure whether the things inside are AND'ed or OR'ed since the break is inside parens. Ok, that is probably teachable... Flip to my :allof - you could desugar that to: cars div:matches(.new .quality):matches(domestic .performance) p { color: red; } And my noneof example: /* Style the efficient cars that are neither domestic and used nor foreign and new. */ .efficient:not(.domestic .used):not(foreign .new) p { color: green; } What would (or would we always disallow) this do? Would it be true if one was not, or would they all have to be not? The later seems in keeping with what :matches is proposed to do so I'd suggest that: /* Style the efficient cars that are neither domestic and used nor foreign and new. */ .efficient:not(.domestic .used, foreign .new) p { color: green; } As far as I can tell, there is currently no way to write my "oneof" example - I have wanted it in the past myself. Maybe that is enough and maybe it is intuitive enough - I find it easier to reason about using set or predicate sorts of language which don't leave the "what does that mean" sorts of questions I mentioned above, but maybe that isn't a good enough case. All of this is a bit of a chicken and egg problem we have here (I'm glad someone in Lea's border-corners thread mentioned this): People work around these limitations today - but they do so by modifying the DOM itself by either changing markup or through JavaScript - or they just use an image or something and lose the data - because they have no other choice - and given new powers, smart people will do new things. [1] - http://dbaron.org/log/20100424-any -- Brian Kardell :: @briankardell :: hitchjs.com
Received on Friday, 5 April 2013 23:06:25 UTC