After having to look this up a couple of times now, I figured I’d share my approach. While you currently can’t technically style previous sibling elements, I’ve figured out a pretty handy workaround.
Suppose you have a progress bar with steps that you want to style. You want the active step to be highlighted and all the steps before it as well (to denote that those steps are completed). Prettying up the active step is easy, but how do you handle the previous steps? You actually style the previous steps by styling the following steps.
Let me show you what I mean….
First, let’s get our step navigation built and styled.
The HTML is simply an unordered list with five list items – the first of which has an “active” class. The line between them is actually one solid line that goes behind all of the steps, added using the CSS “:before” pseudo-element and positioning it in place.
Now that the HTML and basic CSS are in place, we can think about how to style the active and completed steps.
You could change the active class of these steps in many different ways, but I’m going to keep it simple for this example.
When you click on one of the steps, the “active” class is removed from all of them and then re-added to the one that was clicked.
Again, you could change this class position in many, many different ways, but I’m trying to keep it simple.
Here’s the real secret to this whole process: you actually need to style the steps following the “active” step, not the previous ones.
Using the “~” sibling selector, we can style all the elements after the “active” element. All we need to do is style ALL of the elements as though they’re active, and then go back and style all the elements after the “active” one as though they are the normal state.
This is exactly what I did (although a bit more complex) with my CSS-only star rating pen.