• Home
  • blog
  • Quick Tip: CSS Only Dropdowns With The Checkbox Hack

Quick Tip: CSS Only Dropdowns With The Checkbox Hack


In this quick tip, we are going to take a look at a CSS only technique for creating dropdowns. It revolves around the checkbox HTML element and some smart usage of CSS selectors without a single line of JavaScript.

You can see the example in action in our editor. Click the “Edit” button to see the code.  You can download the full source code from the button above.

(Play with our code editor on

The Markup

This is what our HTML structure looks like. Here it’s important to note, that the input element has to come first, before the label and before the ul. You will understand why this is needed later, when we check out the CSS.

<div class="dropdown">
    <input type="checkbox" id="checkbox_toggle">
    <label for="checkbox_toggle">Click to Expand</label>
        <li><a href="#">Link One</a></li>
        <li><a href="#">Link Two</a></li>
        <li><a href="#">Link Three</a></li>
        <li><a href="#">Link Four</a></li>

As you can see, there’s nothing out of the ordinary here, all of elements are in standard, frequently used HTML:

  • The div will serve as a container for the whole thing.
  • The input type=checkbox is needed because of it’s checked/unchecked property. It will be hidden at all times
  • The label will be used to toggle the input and will also serve as the trigger for your dropdown.
  • The ul is simply a list we want to be visible when the dropdown is extended. Can be any other element.

The Checkbox Hack

We only need the checkbox element for its checked state, which we can style using the :checked CSS pseudo selector. Checking and unchecking it is done by clicking the label, which is a basic browser feature. We first hide the checkbox:

    display: none;

We also hide the UL by default – it is the dropdown menu which should only be visible when the dropdown is extended.

    display: none;

And here is the hack. If we combine the :checked selector with the general siblings selector (~) we can change CSS properties of elements that follow the checkbox. This is the reason we needed the checkbox to come in first, before the ul in the DOM tree.

input[type=checkbox]:checked ~ ul {
    display: block

The CSS snippet above will show the unordered list only when the checkbox is checked. Since the possible status of an input of type checkbox is binary, it is perfect for toggling the items between expanded and hidden state.

Hope you enjoyed our quick tip!