Functional CSS Tabs Revisited by Chris Coyier

HTML Structure

A wrapper for the whole group, then each tab is a div that contains the radio button (for the functionality), a label (the tab), and a content div.

<div class="tabs">

   <div class="tab">
       <input type="radio" id="tab-1" name="tab-group-1" checked>
       <label for="tab-1">Tab One</label>

       <div class="content">
           stuff
       </div>
   </div>

   <div class="tab">
       <input type="radio" id="tab-2" name="tab-group-1">
       <label for="tab-2">Tab Two</label>

       <div class="content">
           stuff
       </div>
   </div>

    <div class="tab">
       <input type="radio" id="tab-3" name="tab-group-1">
       <label for="tab-3">Tab Three</label>

       <div class="content">
           stuff
       </div>
   </div>

</div>

CSS Layout

Basically:

  1. Hide the radio buttons (we don't need to see them, we just need them to be checked or unchecked).
  2. Float the tabs so the labels fall into a row-of-links structure.
  3. Absolutely position the content areas exactly on top of each other.
  4. When a radio button is :checked, make the adjacent content area sit on top with z-index (visually revealing it and hiding the others).
.tabs {
  position: relative;
  min-height: 200px; /* This part sucks */
  clear: both;
  margin: 25px 0;
}
.tab {
  float: left;
}
.tab label {
  background: #eee;
  padding: 10px;
  border: 1px solid #ccc;
  margin-left: -1px;
  position: relative;
  left: 1px;
}
.tab [type=radio] {
  display: none;
}
.content {
  position: absolute;
  top: 28px;
  left: 0;
  background: white;
  right: 0;
  bottom: 0;
  padding: 20px;
  border: 1px solid #ccc;
}
[type=radio]:checked ~ label {
  background: white;
  border-bottom: 1px solid white;
  z-index: 2;
}
[type=radio]:checked ~ label ~ .content {
  z-index: 1;
}

JavaScript

There isn't any, captain!

Why this way is awesome

  • It doesn't use :target so no page-jump-suck and back-button-hijacking.
  • It's accessible. The weird radio buttons are hidden with display: none so screen readers won't see them and be confused (presumably) and none of the actual content is hidden with display: none;
  • It works in Safari 5.1+, Chrome 13+, Firefox 3.6+, Opera 10+, and IE 9+. Maybe a little deeper on Chrome, Firefox, and Opera, but Safari and IE are definitely correct.

Why this way isn't awesome

  • It requires a set height to the tabbed area which sucks. I feel like there may be a way to fix this though I just haven't quite gotten it yet.
  • The radio button thing is a bit hacky.
  • It doesn't have the deepest browser support (IE 9 is kinda a lot to ask). If you need deeper go JavaScript.

View Demo   Download Files

 

Via CSS-Tricks

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <b> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <object> <img> <embed> <p> <br> <h1> <h2> <h3> <h4> <h5> <h6> <table> <th> <tr> <td> <hr> <sup> <blockquote> <span> <iframe><pre>
  • Lines and paragraphs break automatically.

More information about formatting options

Theme designed by Chic Workshop