Building a Style Switcher with Pure CSS Using :checked

A few years ago, web developers were unable to implement and build so many things using CSS only and without relying on JavaScript. But today CSS is mature enough that it is capable of doing powerful things without writing a single line of JavaScript. You might have also read a couple of articles about “CSS only approaches” that demonstrates the power of CSS.

When it comes to CSS-only approaches, we can’t ignore the :checked pseudo-class selector, which I’m going to use in this post. Of course, I am not the first one to write about this technique, and there have been other more extensive discussions regarding using form elements as JavaScript replacements. For example this Adobe article by Louis Lazaris and this great slideshow by Ryan Seddon.

Using :checked

In short, the :checked pseudo-class selector represents (selects) any radio or checkbox element that is checked or selected. The user can change the state of these elements by checking a checkbox or selecting a different value in a set of radio buttons.

--ADVERTISEMENT--

Before we dive deeper, take a look at the final demo to get a sense of what we will be building throughout this tutorial:

Building the Settings Box

In the demo, you should have noticed the gear icon and how, when clicked, a box with some options appears. Before we go on explaining the HTML and CSS that makes up that box, take a look at the following code:

Since we are only interested in showing the labels, the above code is used to hide the checkboxes and radio buttons. Moreover, all the labels have a class of settings-box-element with a z-index property just to make sure the labels will stay on top of any other elements on the page.

Now we can break down the code that makes up the settings box. Let’s start with the gear button. Here is the HTML:

<!-- the gear icon that opens the box when you click on it -->
<input id="settings-btn" class="settings-btn" type="checkbox">
<label for="settings-btn" class="settings-box-element"></label>

If you have read an article or two about using form elements as JavaScript replacements, then you should already know that we need to use input and label elements together, so that if one of the two was removed, nothing would work. So we have a checkbox input with an id="settings-btn" and a label with a for attribute that matches the id value. I’ve also added a class of settings-btn to use for our CSS hook.

In the CSS, the label is given a position: fixed declaration with the appropriate direction properties/values (top and right).

The box is a single div element with classes “buttons-wrapper” and “settings-box-element”. As I said earlier, the latter class is mainly used to give the elements a z-index value. The “buttons-wrapper” is used to style the div element. And as you can see, the div was given a width of 200px and a height of 240px to accommodate the 5 buttons you see in the demo. Also, the div is given a position value of fixed and the appropriate right and top properties. The only thing you need to keep in mind here is that the right property should have the same value as the width but in the negative (in order to make it disappear from the viewport).

Lets now take a look at the code for the remaining markup, that is, the 5 buttons. The comments denote the background styles that they control:

Notice that the first checkbox was given the “checked” attribute. That is because we want it to be the one highlighted by default.

Every input field has an id and every label has a for attribute that matches the id for one of the input fields. And as you may or may not know, the secret behind such a technique is the for attribute, because when a label with a for attribute is clicked, the element that is associated with that particular label will be selected/checked and this therefore allows us to use the :checked selector.

All the above labels have a class of “layout-buttons”. This class is used to give the buttons the default and the common styles such as width, padding, borders, etc. The other classes are used to add the unique styles to each. And as you saw for the gear icon and the white box, the position property is used with the value fixed and the appropriate top and right properties. Note that the top value for every label is 45px greater than the one before it; this is to make the buttons stack above each other nicely and without overlaps. Note also that the right property value is the same as the width of the buttons but in negative.

The above CSS is used to change the default styles of the label associated with the selected radio button (we have 4 radio buttons). I used the adjacent sibling selector to target every label that is preceded by an input field of type “radio”. So as you can see, the background and border properties were given the value #e83737 (a reddish color) and the color property the value #fff. Nothing really fancy or complex.

Notice in the above code that I positioned every element of the settings box independently where I could just wrap them all inside a div or section element and position this one single element, therefore making things simpler. This is done simply because you can’t select a parent element, only a sibling.

So in this case, all the main content is wrapped inside a div with class="main-wrapper". And as you will see later, to be able to change the styles for this div, we will need to select that div by writing something similar to this:

When the user clicks on the gear icon, the checkbox with id="settings-btn" will be selected, and here comes the magic. Once the gear icon is clicked, the following will happen:

Using the adjacent sibling selector (+), the label that comes immediately after that checkbox will be selected and then moved 200 pixels from the right of the viewport.

Using the general sibling selector ~, the elements with classes “buttons-wrapper” and “layout-buttons” will be selected and then moved so that they are 0 pixels and 30 pixels, respectively, from the right of the viewport.

Both the adjacent sibling selector and the general sibling selector are indispensable here as this technique will not work without them.

You can see that in the HTML we have 4 input elements of type="radio" and 4 labels. When any of the labels is clicked, the input that is associated with that particular label will be selected and therefore matched by the :checked pseudo-class. Then, depending on which label is clicked, one of the above four styles will be applied to the main wrapper.

In this case, we tell the browser to select the element with class="content" and set it to display: none” when the user clicks on the associated label, therefore selecting the checkbox.

Conclusion

There are many other things you can do using this selector technique and the limit is your own creativity. If this technique is new to you, I hope this article can serve as a starting point for you to experiment with other possibilities.