Creating Content Tabs with Pure CSS

As CSS3 has started gaining more popularity and more browsers are starting to support it, many common interactions that you would expect from a website that were created using JavaScript are now being replaced by pure CSS solutions. Today I’ll show you how to create an animated content tab using only CSS.

Disclaimer: The purpose of this post is to show you the possibilities of CSS3. The content may or may not be practical to use in real life.

Creating Content Tabs with Pure CSS


Creating Content Tabs with Pure CSS

HTML:

<ul class="tabs">
        <li>
          <input type="radio" checked name="tabs" id="tab1">
          <label for="tab1">tab 1</label>
          <div id="tab-content1" class="tab-content animated fadeIn">
	...
          </div>
        </li>
        <li>
          <input type="radio" name="tabs" id="tab2">
          <label for="tab2">tab 2</label>
          <div id="tab-content2" class="tab-content animated fadeIn">
            ...
          </div>
        </li>
        <li>
          <input type="radio" name="tabs" id="tab3">
          <label for="tab3">tab 3</label>
          <div id="tab-content3" class="tab-content animated fadeIn">
            ...
          </div>
        </li>
</ul>

CSS:

body, html {
          height: 100%;
          margin: 0;
          -webkit-font-smoothing: antialiased;
          font-weight: 100;
          background: #aadfeb;
          text-align: center;
          font-family: helvetica;
      }
      
      .tabs input[type=radio] {
          position: absolute;
          top: -9999px;
          left: -9999px;
      }
      .tabs {
        width: 650px;
        float: none;
        list-style: none;
        position: relative;
        padding: 0;
        margin: 75px auto;
      }
      .tabs li{
        float: left;
      }
      .tabs label {
          display: block;
          padding: 10px 20px;
          border-radius: 2px 2px 0 0;
          color: #08C;
          font-size: 24px;
          font-weight: normal;
          font-family: 'Lily Script One', helveti;
          background: rgba(255,255,255,0.2);
          cursor: pointer;
          position: relative;
          top: 3px;
          -webkit-transition: all 0.2s ease-in-out;
          -moz-transition: all 0.2s ease-in-out;
          -o-transition: all 0.2s ease-in-out;
          transition: all 0.2s ease-in-out;
      }
      .tabs label:hover {
        background: rgba(255,255,255,0.5);
        top: 0;
      }
      
      [id^=tab]:checked + label {
        background: #08C;
        color: white;
        top: 0;
      }
      
      [id^=tab]:checked ~ [id^=tab-content] {
          display: block;
      }
      .tab-content{
        z-index: 2;
        display: none;
        text-align: left;
        width: 100%;
        font-size: 20px;
        line-height: 140%;
        padding-top: 10px;
        background: #08C;
        padding: 15px;
        color: white;
        position: absolute;
        top: 53px;
        left: 0;
        box-sizing: border-box;
        -webkit-animation-duration: 0.5s;
        -o-animation-duration: 0.5s;
        -moz-animation-duration: 0.5s;
        animation-duration: 0.5s;
      }

First off, in order to replicate the functionality of JavaScript, we need to find a way to let the CSS know that the user has clicked the button. With JavaScript, we can simply add a class name on click but since we are not going to use JavaScript, we need to hack our way through this. What I did is I used a hidden radio button which is linked to a label tag through rel attribute. The label will act as a button and when you click the label, the label will trigger a “checked” attribute of that linked radio button. Now we can target our styles with a :checked selector.

From the HTML markup, you can see that I have the radio button, the label and the container at the same level. There’s a reason for this. With the help of an awesome CSS sibling combinator (~) we can have one selector triggering another same-level selector without even having it nested together. This allows us to have any radio button with a check triggering any container to appear so that it replicates the behavior of a normal content tab created with JavaScript.

In the demo, I have also included a CSS animation library created by Dan Eden to add some animation effects when the tab content appears.

Conclusion

Now you have a beautiful animated tab content for your website without even touching any JavaScript. Let me know what you think about this approach in the comments below.

Opinions expressed in this article are those of the author and not necessarily those of Onextrapixel.