🐛 This article previously wrongly assumed that the browser would somehow know that .bar happens to be an article element. That assumption was incorrect and this post has been adjusted to no longer contain this error. Thanks to @simevidas for pointing this out.
To solve my problem, I’d be needing something like a :nth-of-class selector. Unfortunately no such selector exists nor is it currently proposed. What is proposed though, in the upcoming CSS Level 4 Selectors specification (aka “not CSS4” 😜), is an extension to the nth-child/nth-last-child pseudo selectors: the ability to add an extra "of S" part into those selectors.
The :nth-child(An+B [of S]?) pseudo-class notation represents elements that are among An+Bth elements from the list composed of their inclusive siblings that match the selector list S. If S is omitted, it defaults to *|*.
Given that, our wanted :nth-of-classselector becomes a reality:
// Seven different types of CSS attribute selectors
// This attribute exists on the element
// This attribute has a specific value of cool
// This attribute value contains the word cool somewhere in it
// This attribute value contains the word cool in a space-separated list
// This attribute value starts with the word cool
// This attribute value starts with cool in a dash-separated list
// This attribute value ends with the word cool
I found this very impressive, well done whoever worked on that, and so I thought I would take a look at how exactly they did it.
The code starts off with a basic set of radio buttons. Using the :checked and :valid attribute selectors (along with some combinators) the right/wrong answers are highlighted once an answer has been given. Changing your answer is also prevented that way. Using CCS Counters – one of CSS’s under-utilised features – the score is kept.
⚠️ Do note that you’re leaking the correctness of answers through your markup this way … so don’t you go making exams with these!
I’ve put all the code together in the pen embedded at the top of this post.
One of the selectors in CSS Level 4 is :is(). It is the successor to :any() and :matches()(which are supplanted by :is()):
The :is() CSS pseudo-class function takes a selector list as its argument, and selects any element that can be selected by one of the selectors in that list. This is useful for writing large selectors in a more compact form.
Early March the first draft for the CSS Nesting Module was published. The draft outlines a future mechanism by which we’ll be able to nest CSS selectors natively (e.g. in pure CSS, without the use of any preprocessors)
This module describes support for nesting a style rule within another style rule, allowing the inner rule’s selector to reference the elements matched by the outer rule. This feature allows related styles to be aggregated into a single structure within the CSS document, improving readability and maintainability.
Using the & selector (read this as “the nesting selector”), you can refer to the elements matched by the parent rule:
With those extra data-* attributes in place, we can now make good use of [attribute~=value] selectors:
Say we want to select all items that are greater than 8. To do so we select all items where [data-val-gt] contains the value 8. → In CSS: [data-val-gt~=8].
Say we want to select all items that are less than or equal 4. To do so we select all items where [data-val-lte] contains the value 4. → In CSS: [data-val-lte~=4].
Say we want to select all items that are between 5 and 9. To do so we select all items where [data-val-gt] contains the value 5 and [data-val-lt] contains the value 9. → In CSS: [data-val-gt~=5][data-val-lt~=9].