You might not need Javascript for that: Filtering

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.


Javascript filters have become more and more popular, and can be implemented in a few different ways. Javascript filters can be built by either sending all the data initially and storing it (in Javascript as a variable, in the DOM, etc), or by sending additional requests for data to the server via AJAX. The former technique can be workable for small amounts of data, but is inappropriate for large amounts of data. For example, Amazon wouldn’t send all the data for a product search up front because there is just too much of it.

The mechanics of changing data can be handled in different ways as well. Javascript libraries that allow state to be managed easily like React, Vue, and Angular make these operations simple. On the other hand, doing this with jQuery (or without any framework), while certainly manageable, is more difficult because the developer needs to add and remove appropriate items from the DOM manually.


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.

The ~ 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.

That the just of it. Although this technique is totally unsuitable for complex situations and is probably more complicated than a Javascript solution, its cool to see that this can be done without it.