Chain selectors together while maintaining existing order using parentheses


#1

We can already select for scenarios where multiple elements, IDs, or classes are used to filter, e.g.:

div + div {
    background: #000;
}

or

.apples > .oranges {
    text-decoration: none;
}

We can also already select for situations where we want only an element that is the last of its type, or is the last child, etc.:

.apples:nth-of-type(2n) {
    border: 1px solid black;
}

or

.oranges:last-child {
    font-size: 2em;
}

What we don’t have, and what I think we could really use, is a way to combine these two in order to select for situations where we want more complicated filtering. This would be especially useful for situations where mixed classes are used.

My suggestion is to chain selectors together, a la the mathematical order of operations, using parentheses. Take for example the following two code snippets:

div + div:last-of-type {
    color: red;
}

and

(div + div):last-of-type {
    color: red;
}

or

(div + div):last-child {
    color: red;
}

The first snippet of CSS above would apply the red color only in instances where there is a div that is a last-child of its parent, where that div is also preceded by another div. The second and third snippet of CSS above would apply to both divs, assuming one of them is the last-of-type or last-child, and assuming that that last div has a preceding immediate sibling that is also a div.

This differs from nth-of-type and nth-child in that you can have dynamic pages where divs or other elements are inserted/shown based on different criteria, and still have CSS alter the appearance conditionally. Dynamicity is important to consider here; it’s why we can’t just “add another class”.


#2

If I’m understanding what you intend correctly, you can do this with existing selectors in the draft:

div:last-of-type, div:has(+div:last-of-type) { ... }

etc.


#3

It’s my understanding that the :has() pseudo selector will not be included in CSS Selectors Level 4.


#4

It’s in level 4, just not in the Fast profile.

Rephrasing something doesn’t change its speed, though, so most things that can be done with :has() would be equally excluded from the Fast profile.


#5

Unless the various web browsers disagree that :has() is too slow to implement, then it will only be accessible in the DOM for JavaScript and similar languages, not for CSS.