Creating Content Tabs with Pure CSS

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

[tut demo=”http://www.onextrapixel.com/examples/pure-css-tab-with-fade-animation/” download=”http://www.onextrapixel.com/examples/pure-css-tab-with-fade-animation/pure-css-tab-with-fade-animation.zip”]

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.

[tut demo=”http://www.onextrapixel.com/examples/pure-css-tab-with-fade-animation/” download=”http://www.onextrapixel.com/examples/pure-css-tab-with-fade-animation/pure-css-tab-with-fade-animation.zip”]

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.

Pete is a Bangkok entrepreneur, a UI designer, and a Ruby on Rails developer. He is the founder of Bucketlistly.com and MyColorscreen.com. Other than his businesses, design and development, he also loves astronomy, indie music, and blogging.

Comments

    • Teeman,
    • July 31, 2013
    / Reply

    Not seeing the rel attribute.

    • Teeman,
    • July 31, 2013
    / Reply

    Also, i’m not seeing where the checked attribute is being added for the last 2 tabs.

    1. / Reply

      From what I can tell, the checked attribute is only required on the first tab as it is what allows the content to be displayed on page load; it isn’t needed on any subsequent tabs.

    • Paul,
    • August 17, 2013
    / Reply

    I thought you said this was created WITHOUT using javascript, yet i see the reference to jquery-1.9.1.js, and another one: modernizr.js. So, if I was to implement this code on my own site, which i would like to do, i’d have to include these libraries, too?

      • guisasso,
      • August 23, 2013
      / Reply

      You can remove those

    • guisasso,
    • August 23, 2013
    / Reply

    This is a beautiful script. I’ve noticed though, that the downloaded version does not work on ie when uploaded to a server. It does work locally. Your demo page online works also. Any ideas?

      • guisasso,
      • September 4, 2013
      / Reply

      I have found out why. It’s because of the compatibility mode on IE. The script is great, and again, beautiful work, but the poor browser support had to make me drop it.

    • Deivid,
    • August 31, 2013
    / Reply

    Hi why Switching tabs causes page to scroll up?

      • Naveen Singh,
      • October 10, 2013
      / Reply

      hey there try reducing the ” tabs input ” top :-9999 px to about -99 or some lesser value and yeah visibility : hidden would work just fine too

    • shashi kant,
    • September 7, 2013
    / Reply

    Thanks it’s amazing. It really helped me.

    • Daniel,
    • October 7, 2013
    / Reply

    Is there any way to use this without the position:absolute method for the tab’s content?

    • Naveen Singh,
    • October 10, 2013
    / Reply

    Change the tabs input { top :-9999; } to some lesser value like -99 or -199 , because keeping the value to -9999 is causing the entire page to scroll on the top.

      • Andrew Himmer,
      • January 29, 2014
      / Reply

      I have used this method before, and styling the inputs as display:none; solves a lot of those issues (particularly the scroll).

        • Hein Behrens,
        • February 13, 2014
        / Reply

        I agree

        .tabs input[type=radio] {

        display: none;

        top: -9999px;

        left: -9999px;

        }

        solved it for me.

    • sheryljayson,
    • October 15, 2013
    / Reply

    Thank you so much. This is great!
    Is there a way to have the content in tab 1 showing when the page first comes up?

    • Aleksandar Janković,
    • October 15, 2013
    / Reply

    How would you add elements to the bottom, underneath the tab-content?

    • rosh3000,
    • October 17, 2013
    / Reply

    Great post, (demos 4 is the winner for me)

    • Joseph Marney,
    • October 22, 2013
    / Reply

    How would one link to a specific tab on the page?

    • Anas Raza,
    • November 1, 2013
    / Reply

    does not work in IE 8 …. only tabs heading are showing no content is showing please help..

    • Fabrício Raimundi,
    • November 7, 2013
    / Reply

    Hello, how do I add elements just below the tabs (on the outside) without setting the height?

    I want to make the height auto and could for example put a footer below the tabs, but the tabs seem floating and no clear I tried worked.

    Thank you!

    • checky,
    • December 23, 2013
    / Reply

    I tried this, and I can’t make it work ‘below’ other elements of my html page. I added tabs at the bottom, and I just can’t ‘force’ it to show full content of my tabs. I tried changing all the properties and the one that is making issue is: .tab-content {position: absolute;} When I remove that I can see the content of tabs, BUT tabs are below ea other, like: tab1-> tab1-content ->tab2 -> tab2-content -> tab3 ->tab3 content and so on. Any chance to get around this? Thanks!

    • Chris,
    • January 9, 2014
    / Reply

    I wish the post author could be more helpful, but any ways there are a lot of other tutorials that could fix the absolute issue.

    • Facebook User,
    • January 23, 2014
    / Reply

    Doesn’t really work in the real world.. I tried adding this to a responsive design but when the screen goes to mobile size, the side floats on top on the nav… need a freaking solution to this.. 2 days trying to fix it :|

    • Jamal Hosseini,
    • March 27, 2014
    / Reply

    Thank you so much for this great job,

    But there is an issue which a visited link will stop animation afterward and once you visit link after that you will not have animation on changing tabs.

    • Reejo Samuel,
    • May 18, 2014
    / Reply

    let me share the emmet code for HTML part of this tutorials

    ul.tabs>li*3>input#tab$[name=tabs type=radio]+label[name=tab$]+div#tab-content$.tab-content.animated.fadeIn

Leave a Reply

Your email address will not be published. Required fields are marked *

Deals

Iconfinder Coupon Code and Review

Iconfinder offers over 1.5 million beautiful icons for creative professionals to use in websites, apps, and printed publications. Whatever your project, you’re sure to find an icon or icon…

WP Engine Coupon

Considered by many to be the best managed hosting for WordPress out there, WP Engine offers superior technology and customer support in order to keep your WordPress sites secure…

InMotion Hosting Coupon Code

InMotion Hosting has been a top rated CNET hosting company for over 14 years so you know you’ll be getting good service and won’t be risking your hosting company…

SiteGround Coupon: 60% OFF

SiteGround offers a number of hosting solutions and services for including shared hosting, cloud hosting, dedicated servers, reseller hosting, enterprise hosting, and WordPress and Joomla specific hosting.