CSS3 checkbox hack with fallback

CSS3 checkbox hack with fallback

Wednesday, March 30, 2016

When building responsive websites, it's common to have menus collapse on smaller screens. The CSS3 checkbox hack allows for menus to be collapsed and expanded without using JS. But there's one problem; it breaks if the :checked pseudo class isn't supported.

I ran into this problem myself, and tried to fix it using various other hacks. But fixing a hack with another one is never a good idea. Finally I accepted defeat and focused on an alternative solution, a fallback.

When using the CSS3 checkbox hack, collapsing and expanding is triggered using the :checked pseudo class. When checked the menu is expanded, when unchecked it's not. The initial state of the menu will be collapsed, making it impossible to expand if the :checked pseudo class isn't supported.

A fallback is made possible by reversing this condition. The condition can be reversed in two ways; setting the initial state of the controlling checkbox as checked and collapsing using :checked, or by using the :not() selector.

Setting the checkbox to checked and collapsing on :checked works; but the initial state of the menu will always be expanded, even if the :checked pseudo class is supported. And that's not what I wanted.

header input {
   display: none;
}
header input[type=checkbox]:not(:checked) + nav {
   display: none;
}
header input[type=checkbox]:checked + nav {
   display: block;
}
<header>
   <label for="toggle" onclick="">Menu</label>
   <input type="checkbox" id="toggle" />
   <nav>
      <ul>
         <li><a href="#">Menu item 1</a></li>
         <li><a href="#">Menu item 2</a></li>
         <li><a href="#">Menu item 3</a></li>
      </ul>
   </nav>
</header>

Using the :not() selector and keeping the default setup of the CSS3 checkbox hack, on the other hand, will allow for the menu to be collapsed and expandable if supported, and expanded otherwise.