Element Filtering Using CSS3 Negation Pseudo-Class
I was going to title this post, “I was bored at work today so here’s some CSS” but that didn’t seem very descriptive. And for those that don’t want to scroll down to find the link to the demo: Here you go.
Essentially, I was trying to filter content based on data attribute and the negation pseudo-class. And it works well using a combination of :not(s) pseudo-class and the general sibling combinator.
a[data-filter="red"]:focus ~ div:not([data-filter="red"]) works by selecting all divs that do not have a data-filter attribute equal to exactly “red”. These divs must also be a sibling of an in focus <a> element that has a data-filter attribute equal to “red”. If these requirements are met then all other divs have their values zeroed out.
I used the :focus pseudo-selector instead of :target because the buttons are being used to navigate to another section of the page (or another page for that matter) and if you’re just using an anchor to trigger a state change then I don’t really want to pollute the users history with a bunch of fragment identifiers that are essentially linking to the same page.
If you want user to be able to have an interaction with the filtered elements beyond just clicking a link you will need to the use the :target pseudo-class. You can see the same example using :target here: http://jsfiddle.net/joshvogt/AHcjs/. On this one, I’ve added add a :hover state that only applies to filtered elements.
One thing I couldn’t figure out: if you wrap the <a> elements in another element the selector breaks and I couldn’t figure out one that would work. Bonus points to anyone that can figure that out (Sorry, I don’t actually have any bonus points to hand out).
View the demo here: jsfiddle.net/joshvogt/UybPY/