I spent years trying to make CSS states predictable
by tenphi on 4/23/2026, 12:37:18 PM
https://tenphi.me/blog/why-i-spent-years-trying-to-make-css-states-predictable/
Comments
by: chrismorgan
This sounds interesting, but I’d need to think about it more so I could picture how things fit together as they get more complex <i>and different styles logically overlap</i>. This looks to head in the utility direction possibly too far for that to work nicely. But it may well work better than I’m initially imagining.<p>Unfortunately I can’t give it more attention now, because I should have gone to sleep a couple of hours ago…<p>—⁂—<p>Another approach entirely is to <i>embrace</i> last-declaration-wins, by :where()ing everything:<p><pre><code> :where(.t0) { background: var(--primary-color); } :where(.t0:hover) { background: var(--primary-hover-color); } :where(.t0:active) { background: var(--primary-pressed-color); } :where(.t0[disabled]) { background: var(--surface-color); } </code></pre> I’d be interested to know which approach performs better once you have altogether too many elements and altogether too complex selectors. I suspect the :where() would win, but that the difference would be impossible to detect in any sort of realistic load.
4/23/2026, 6:53:24 PM
by: tenphi
Happy to take questions! I built this because I kept hitting the same wall: CSS state resolution is opaque when states overlap, and extending components means mentally re-deriving the whole selector matrix every time.<p>Some topics I'm curious what people think about:<p>- What’s the one thing this doesn’t cover that you’d expect it to?<p>- Does the syntax feel natural to you, or did you find yourself confused by anything?<p>- I'm looking for edge cases: what kind of complex selector scenario would trip this compiler up or be impossible to express with this model?<p>AMA—happy to answer any questions about the tool, the implementation, or the design choices.
4/23/2026, 1:01:18 PM
by: porsager
Probably because you aren't using Sin
4/23/2026, 7:09:30 PM