Hereby I propose a new type of selector, one that is based on used property values.
Examples:
There is plenty of ways to select an element based on source (like class selectors, ID selector, attribute selectors, etc.) and structure (siblings, children, descendants). There is plenty of ways to specify values for CSS properties. But there is no way to select an element if the used value of some of its CSS properties matches a given criterion.
Image you want the set the top margin for the first block element. The :first-child selector matches any child.
*:first-child { margin-top: 2em; }
Another selector might be:
*:nth-child(1 of :matches(div,p,aside,…)) { … }
The problem here is that one has to enumerate a quite large list of supposedly block elements. No major implements the ‘of’ qualifier for :nth-child and :nth-last-child, so one would actually have to write a long list of full selectors. The main problem, however, is that the display property is not restricted to any element: display:block may be applied to any inline element while display:inline may be applied to any block element. In addition, some other properties force display to a predefined value (e.g. float forces display to block). A quite simple solution would be:
*:nth-child(1 of :style(display:block)) { … }
Example #2: Imagine you want a table cell to display text vertically but only if the cell is not wide enough to display the text horizontally. This would be quite easy to achieve with a selector like this:
td:style(width < 2.5ch) { writing-mode: sideways-lr; }
A selector like this would match an element only if the used value of the width property (no matter if its fixed in previous declaration or is calculated automatically) is less than 2.5ch converted to pixels. A more sophisticated rule might use a combination of checks, e.g.
:style(height > 1px and width < 2.5ch) { … }
:style(1px < width < 2.5ch) { … }
- Operators <, >, <=, >=, = and <> would be applicable to properties that calculate to numbers like ‘width’ does;
- For properties whose values are strings the same operators as for the attribute selector would apply;
- For properties whose values are selected from a closed set of keywords, the only syntax allowed would be e.g. :style(display:block) and :not(:style(:block)).