Fun with Stateful CSS: Tabs

22 October 2013

In this series, we’ve covered how to use form inputs and some clever CSS selectors to toggle between states of a form and show a modal window. Now, let’s apply the same principles to create a simple—and JavaScript-less!—collection of tabs.

As you may have come to expect, the HTML is fairly straightforward, though a tad more complex than last time:

  <input type="radio" id="panel-1" name="panels" checked>
  <input type="radio" id="panel-2" name="panels">
  <input type="radio" id="panel-3" name="panels">

  <ol class="tabs">
    <li><label class="button" for="panel-1">One</label></li>
    <li><label class="button" for="panel-2">Two</label></li>
    <li><label class="button" for="panel-3">Three</label></li>
  </ol>

  <div class="panel panel-1">Panel one contents.</div>
  <div class="panel panel-2">Panel two contents.</div>
  <div class="panel panel-3">Panel three contents.</div>

Instead of a single “yes/no” checkbox, we now have three radio buttons to represent state: one for each “panel” of the collection. Next is an ordered list containing the label elements you might expect (to review, these allow us to “toggle” the state of the input elements), and then three div elements that contain each panel’s contents. As always, we’ll hide the input elements with CSS, but still select based on their “checked” state (with the :checked pseudoselector) to determine what tab to show. We’ll also hide all of the panels by default unless one of the associated radio buttons is selected:

  /* Hide all panels by default */
  .panel-1,
  .panel-2,
  .panel-3 {
    display: none;
  }

  /* Show a panel when its associated radio button is selected */
  #panel-1:checked ~ .panel-1,
  #panel-2:checked ~ .panel-2,
  #panel-3:checked ~ .panel-3 {
    display: block;
  }

  /* Also hide all of the radio buttons */
  input[type=radio] {
    display: none;
  }

In this way, we can migrate away from a simple boolean state (with a checkbox) to a potentially infinite number of states with radio buttons.

See the Pen Fun with Stateful CSS: Tabs by Tim G. Thomas (@TimGThomas) on CodePen

That concludes this round of fun with stateful CSS! Thanks for reading!

Comments