How To Build Tabs only with CSS

There are several ways to provide navigation on a web site. Tabbed navigation is one of them; menu, sidebar, etc.

The key of implementing tabs without Javascript is to use radio buttons.

  1. We connect radio buttons with labels.
  2. When label is clicked, only one radio button is checked as selected.
  3. Only matching contents of selected radio button is visible.

Let’s code.

1. Code HTML for tab buttons

We will have input tags with type radio and with the same name as tabs by only making id differently, followed by label tags with attribute for matching to the radio input tag id.

<input type="radio" name="tabs" id="tab1" checked />
<label for="tab1">Tab1</label>
<input type="radio" name="tabs" id="tab2" />
<label for="tab2">Tab2</label>
<input type="radio" name="tabs" id="tab3" />
<label for="tab3">Tab3</label>
<input type="radio" name="tabs" id="tab4" />
<label for="tab4">tab4</label>
<input type="radio" name="tabs" id="tab5" />
<label for="tab5">tab5</label>

The above are the index parts. Now we need contents section.

2. Code HTLM for tab contents

<div class="tab content1">Tab1 Contents</div>
<div class="tab content2">Tab2 Contents</div>
<div class="tab content3">Tab3 Contents</div>
<div class="tab content4">Tab4 Contents</div>
<div class="tab content5">Tab5 Contents</div>

Without any stlying, tab indexes and contents will look like this.

Now, it’s time to make it look like a tab.

3. Style Tabs for Tab Features

input { display: none; }                /* hide radio buttons */
input + label { display: inline-block } /* show labels in line */
input ~ .tab { display: none } /* hide contents */
/* show contents only for selected tab */
#tab1:checked ~ .tab.content1,
#tab2:checked ~ .tab.content2,
#tab3:checked ~ .tab.content3,
#tab4:checked ~ .tab.content4,
#tab5:checked ~ .tab.content5 { display: block; }

Now it looks like tabs and their contents. We want better look-and-feel.

4. Lastly, Style for Look-and-Feel

input + label {             /* box with rounded corner */
border: 1px solid #999;
background: #EEE;
padding: 4px 12px;
border-radius: 4px 4px 0 0;
position: relative;
top: 1px;
}
input:checked + label { /* white background for selected tab */
background: #FFF;
border-bottom: 1px solid transparent;
}
input ~ .tab { /* grey line between tab and contents */
border-top: 1px solid #999;
padding: 12px;
}

Here is the working demo.

I believe that the above technique satisfy your very basic tab requirements. However if you want more than the above, you will need Javascript for customized requirements like the following;

  • Keyboard navigation between tabs
  • Accessibility requirements to navigate between tabs and its contents
  • Having disabled status
  • Pre-selected tab status

If you want a fully functioning Javascript tabs, take a look at custom elements made for tabs, https://allenhwkim.github.io/html-custom-elements/#tabs.

Code of above custom element tabs is available at here .

Do you like VanillaJS coding without a framework? If so, you may also like html custom elements.

html-custom-elements is a collection of simple and useful custom elements. It is a lightweight, framework-independent, and works on all modern browsers including IE11.

Happy coding :)