- From: Matt Mastracci <matthew@mastracci.com>
- Date: Wed, 4 Feb 2015 09:58:46 -0700
- To: www-style list <www-style@w3.org>
Thinking more about the CSS extensions draft and custom selectors... I think we need to be very careful about allowing any turing-complete language to have its hooks in CSS rules -- most of what the spec already shows can already be done using DOM mutation observers and temporary classes. If someone wants to prototype selectors in JS, I believe that it can be done through that channel. I spent some time thinking/searching for some use cases for selectors not covered. My conclusion is that for these to be useful, the :has() selector *really* needs to be made fast, or included in the spec with the caveat that overuse will cause perf issues. 1) Selecting a label by input type ---------------------------------- http://stackoverflow.com/questions/13031926/select-label-by-input-type /* A selector that bolds the label for the associated focused input */ form input:focused /label-for/ label { font-weight: bold; } /* I’m inventing an “attribute capturing” := syntax here, bike-shedding welcome */ @custom-selector $a /--label-for/ $b $a[$id := “id”] /--root/ $b[for=$id]; @custom-selector $a /--root/ $b :root:has($a) $b; Output equivalent: form input:focused[$id := “id”] /--root/ label[for=$id] :root:has(form input:focused[$id := “id”]) label[for=$id] { … } 2) Selecting a parent node of a subject --------------------------------------- /* If a div has more than 10 siblings, show an overflow */ div.container:--n-children-of(10,.item) .overflow { display: block !important; } /* Shrink the font size when there are 5 or more items */ div.container .item:--n-siblings-of(5,.item) { font-size: smaller; } @custom-selector $subject:--n-siblings-of($n,$s) $subject:nth-child(1 of $s):nth-last-child($n of $s), $subject:nth-child(1 of $s):nth-last-child($n of $s) ~ $subject:nth-child(n of $s) @custom-selector $subject:--n-children-of($n,$s) $subject:has(> :nth-child(1 of $s):nth-last-child($n of $s)); Output expansions: div.container:--n-children-of(10,.item) .overflow div.container:has(> :nth-child(1 of .item):nth-last-child(10 of .item)) .overflow { … } div.container .item:--n-siblings-of(5,.item) div.container .item:nth-child(1 of .item):nth-last-child(10 of .item):—self-of-sibling() div.container :matches(.item:nth-child(1 of .item):nth-last-child(10 of .item), .item:nth-child(1 of .item):nth-last-child(10 of .item) ~ .item:nth-child(n of .item)) { … } 3) Previous/any sibling combinators ----------------------------------- input /any-sibling/ label { float: left; } @custom-selector $a /--parent/ $b $b:has(> $a); @custom-selector $a /--previous-sibling/ $b $a /--parent/ * > $b:has(+ $a); @custom-selector $a /--any-sibling/ $b $a + $b, $a /--previous-sibling/ $b Output expansion: input + label, input /--previous-sibling/ label input + label, input /--parent/ * > label:has(+ input) input + label, *:has(> input) > label:has(+ input) (OR) @custom-selector $a /--any-sibling/ $b $a /--parent/ * > $b Output expansion: *:has(input) > label 4) Self or sibling ------------------ /* Make all columns a checkmark until the end of the row */ .row .col:hover:—self-or-sibling-matching(.col) .check-img { background-image: url(checked.png) } @custom-selector $subject:-—self-or-sibling-matching($s) $subject, $subject ~ $s Output expansion: .row .col:hover:—self-or-sibling-matching(.col) .check-img .row :matches(.col:hover, .col:hover ~ .col) .check-img Matt.
Received on Wednesday, 4 February 2015 16:59:18 UTC