The Future State for CSS Selectors

CSS does a lot with its selectors, but there's still a lot more it could do to make things easier for developers. In this guide we'll be looking at some of the main developments coming from the CSS Selectors Specification 4, and how it might make your development life easier.

These are, for the most part, not currently supported by browsers!. For a more comprehensive view of current selectors, read our selectors guide:

CSS Selectors Guide

A complete guide to get you started with CSS Selectors.


Parent Selection. We all want it, and :has tries to solve it. Not supported by any browsers currently mostly due to frequent syntax changes, :has allows both parent and previous sibling selection. Have you ever wanted to select an element, and then navigate back up the DOM to its parent? That's exactly what this element does.

To give an example of this, here is an example. The below CSS will target a p paragraph which has a child span

html Copy
<p> I am targeted by the CSS <span> I am a span </span> </p>
css Copy
p:has(> span) { color: red; }

Similarly, :has() solves the problem of previous sibling selectors. The below will target a p paragraph who's next sibling is a p.

html Copy
<p>I am targeted</p> <p>I am not</p>
css Copy
div:has(:not(h1)) { color: red; }


It's common to write out lots of lines to select certain elements in CSS. Something like this isn't uncommon:

css Copy
div span, section span, h1 span { color: red; }

Surely there is an easier way? Well, :is() IS that easier way. The above can be boiled down to just this:

css Copy
:is(div, section, h1) span { color: red; }

what about :where

:where() is another level 4 selector, the only difference is its specificity is always 0. Specificity in CSS is what determines which styles override which. Having a specifity of zero means where will never make a style more specific, which can be useful in some cases, i.e. for ensuring certain styles don't overwrite other ones.

In the future, this clause may include a number which may let us set the specificity, something people have been using !important for previously.

css Copy
:is(div, section, h1) span { color: red; }

More complex :not

:not() is supported by most browsers, but only for simple selectors. What is a simple selector? It is just a single element. With this update, we will be able to select an element which is not contained within an element. For example, the below will target only divs not contained within a section:

css Copy
div:not(section div) { color: red; }

Grid Column Selection

A number of column selectors are being planned for the next level of CSS selectors. Importantly, these don't just apply to tables, but grids as well. That means we'll finally be able to style specific grid columns or items, which we couldn't do previously.

There are 3 selectors for columns in the new specification:

Syntax Description
E || F Selects a cell F within column E.
nth-col(n) Selects a specific column in a grid or table
nth-last0col(n) Selects a specific column in a grid or table, from the end

As you might expect, we can then combine these to style cells within that column:

css Copy
.grid:nth-col(2n) || .title-cell { color: red; }
Last Updated Wednesday, 10 March 2021
Click to Subscribe Subscribed


Subscribe to stay up to date with our latest posts via email. You can opt out at any time.

Not a valid email