This tutorial shows you how to let viewers filter your collection by category with just CSS and HTML, no JS needed! Maybe you have a gallery of art or pictures that can be filtered into groups. Maybe a collection of gifs? List of songs or books?
You can do this easily with a little JS, as shown in my JavaScript Cheat Sheet, but you may not be comfortable with JS.
Fortunately with HTML radio buttons and some CSS you can do this without JS, though it is a little more verbose. Heres my example, using HTML colors as the collection, that the viewer can sort by broad color category!
Select a button to sort HTML colors by group! (automatically updates)
Sooo, how do you do this?
class=""
<span style="background: mediumorchid;" class="pink purple"></span>
style=""
) is not important, thats just the color for my items, you will probably have an image or something that does not need individual styling<label>
<input type="radio" id="pink" name="color">
pink
</label>
input
element with the attribute type="radio"
id=""
attribute, which I made the same as the category labelname="example"
! This is to link them as a part of the same group, and so that the viewer can only click one at a time.
<label>
<input type="radio" id="all" name="color">
all
</label>
So that was just the HTML, the buttons won't actually do any filtering yet, the user can only click on them.
.collection:has(input:checked) span {
display: none;}
.collection
is my class given to the container holding my collection of items:has
is a relatively new CSS selector that is very handy! Its been easy to select an element within an element, but difficult to select an element that contains another until :has:checked
)span
with "img", "li", etc depending on what your collection of items is.collection:has(#all:checked) span {
display: inline-block;}
display: none;
is replaced with display: inline-block;
input
is also replaced with the id selector #all
(which you may have a different id for), which makes it so that all of the items are displayed only when the radio button with the #all
id has been checked.collection:has(#pink:checked) span[class~="pink"] {
display: inline-block;}
[class="pink"]
would only select elements that have just "pink" as its singular class, it would not select elements that have other classes along with "pink"; the ~
infront of the equals sign allows it to select elements with any class attribute as long as "pink" is in there.Yay! Your filter buttons work! Wait, you want to change how they look?
This stuff isn't necessary, but if you'd like to customize the radio buttons to your page's theme, this will help.
If you just want to change the select color, you can use accent-color: purple;
but its a little more complicated if you want to overide the default browser styling.
Remember that the input
is just the little dot or box, label
will style the whole button.
To style the little checkbox, first remove its default styling: input { appearance: none;}
. You can then give it a border, width, height, background, etc. A normal border will make it square, use border-radius: 50%;
to make it a circle (if the width and height are the same).
You'll then want to give it a different style for when its selected input:checked {}
, likely by giving it a background color.
If you want to change the label style when the input is checked, use label:has(input:checked) {}
You may also want to style the button on hover; you can use label:hover input
to style the checkbox when the label is hovered over, and label:hover
to style the label itself. To override the checked styling on hover, use: label:has(input:checked):hover
.
Thats all, have fun with your new found CSS power! Radio buttons and :has are really powerful tools that are behind some CSS hacks, such as page tabs and CSS only dark/light mode buttons! I will update my theme tutorial on how to do that.