Similar to how you can (ab)use :nth-child()
to create “new” CSS selectors, you can leverage :has()
to create some typical combinators. Brandon McConnell did just that:
-
y:has(+ x)
selects the first precedingy
sibling ofx
: -
y:has(~ x)
selects all precedingy
sibling ofx
: -
x + y, y:has(+ x)
selects the first preceding and first succeedingy
siblings ofx
: -
…
And those are just the simple ones. Selecting “all preceding y
elements up to the third one” for example is possible using y:has(~ * + * + x)
😅
🤔 Not familiar with the CSS :has()
selector? Read up on it right here.
~
To more easily work with that, Brandon also created a (still unpublished?) PostCSS plugin that supports fictitious CSS Selectors which automatically translate to their working counterparts. For example:
x - y
translates toy:has(+ x)
x -- y
translates toy:has(~ x)
x % y
translates tox + y, y:has(+ x)
Here’s a pen with all combinators he came up with:
Oh that’s clever! Perhaps we might one day see these selectors land in CSS itself?
👨🔬 Only Safari Technology Preview 137 supports :has()
at the time of writing, so you’ll need to use that browser to see anything get colored in the “Actually Rendered” rows there.
During his work Brandon noticed a bug in Safari’s implementation in which it selects some non-targeted elements, so you might see some faulty ones.