Making collections of items filterable is a common way to make data more accessible to users on the web. Many ecommerce platforms allow for products to be searched, then filtered by specifications such as price, brand, rating, etc. This allows customers to find the products that they want quickly which ultimately boosts sales.
Filtering functionality can be developed using several techniques:
Server side via query strings
One classic way of building filter functionality is by setting the filter categories to be anchor tags that contain query strings. When the user clicks on a filter, the page is re-requested with new url parameters (eg
/products?min-rating=4). The server then reads the parameter and responds with items matching the given filter. This strategy is solid and dependable, but requires an additional page reload which is beginning to feel dated. As a real world example, WordPress’s ubiquitous Woocommerce plugin uses this technique for product categories.
You may not of thought it possible, but CSS actually has the firepower to emulate this behaviour as well. The rest of this post is dedicated to showing how. Here’s the demo:
In this example, I’m grabbing some base styles from Bootstrap and extending them with SCSS. Here’s the key details that make this work:
A radio input is created for each category. By using a common name attribute, these inputs are grouped and only one can be active at a time.
Bootstrap’s tab components are used to display each filter category. Instead of containing an anchor tag, each tab contains a label.
Each label is linked to an associated radio input by setting its for attribute to an input id. Now when a label is clicked, its input will become active.
~ selector can be used to select sibling elements that appear after another. When combined with the
:checked selector, it becomes possible to target a given element (the labels and the grid item itself) when a radio button is selected.
Since the labels are being used as buttons and we don’t want to display the radio buttons, those are hidden via
display: none; (but they are still being toggled when labels are clicked)
By setting the input id attribute, label for attribute, and item class consistently, styling can be automated via a scss @each loop.
A basic animation can be setup so that items fade in when they go from hidden to shown.