HTML Tab Interface Using Only CSS

HTML tab interface using only CSS

It is possible with html and css for most modern browsers using the border-radius property (not supported by internet explorer 8 and below).

css

li {-moz-border-radius: 12px 12px 0 0; /* FF1+ */
-webkit-border-radius: 12px 12px 0 0; /* Saf3-4 */
border-radius: 12px 12px 0 0; /* Opera 10.5, IE9, Saf5, Chrome */
border:1px solid black;
display:inline;
list-style-type:none;
padding:5px;
}
li:hover {background:black;}
li a {text-decoration:none; color:black;}
li a:hover {color:white;}

html

<ul>
<li><a href="#tab1">tab 1</a></li>
<li><a href="#tab2">tab 2</a></li>
<li><a href="#tab3">tab 3</a></li>
</ul>

To support internet explorer you can use css3pie but you have to keep in mind that it uses javascript.

You can find more information about border-radius at: http://www.w3.org/TR/css3-background/#the-border-radius

Example: http://jsbin.com/idiza5/2

How can I make tabs with only CSS?

An easy way to implement CSS-only tabs is to use radio buttons!

The key is to style labels that are attached to a respective button. The radio buttons themselves are hidden, with a little absolute positioning, off the side of the screen.

The basic html structure is:

div#holder
input[type="radio"]
div.content-holder
label
div.tab-content (all your tab content goes here)
input[type="radio"]
... keep repeating

The key is in the selectors. We are going to style the input[type="radio"] buttons with

input[type="radio"] {
position: absolute;
left: -100%;
top: -100%;
height: 0;
display: none;
}

This hoists them off the side of the screen, as mentioned above. But how do we click them then? Fortunately, if you target a label, it can click the input for you!

<label for="radioInputId1">tab title</label>

Then we style the actual labels (I'm going to leave out the aesthetic styling for brevity):

input[type="radio"] + div.content-holder > label {
display: inline-block;
float: left;
height: 35px;
width: 33%; /* or whatever width you want */
}

Now our labels should look like "tabs" at the top of the div#holder. But what about all that content? Well, we want it to all be hidden by default, so we can target it with the following selector:

input[type="radio"] + div.content-holder > div.tab-content {
display: none;
position: absolute;
top: 65px; /* this depends on your label height */
width: 100%;
}

The above CSS is the minimal CSS required to get it working. Everything other than display: none; is what you will see when the div is actually displayed. But this shows nothing in the tabs, so… now what?

input[type="radio"]:checked + div.content-holder > div.tab-content {
display: block;
}

The reason the above works is because of the :checked pseudo-class. Since the labels are attached to a specific radio button, they trigger :checked on click. This automatically turns all the other radio buttons off. Because we have have wrapped everything within a div.content-holder, we can use the next sibling CSS selector, +, to make sure we only target a specific tab. (Try using ~ and see what happens!)

Here's a fiddle, for those of you who don't like stack snippets, and here's a stack snippet, for those of you who do:

#holder {  border: solid 1px black;  display: block;  height: 500px;  position: relative;  width: 600px;}p {  margin: 5px 0 0 5px;}input[type="radio"] {  display: none;  height: 0;  left: -100%;  position: absolute;  top: -100%;}input[type="radio"] + div.content-holder > label {  background-color: #7BE;  border-radius: 2px;  color: #333;  display: inline-block;  float: left;  height: 35px;  margin: 5px 0 0 2px;  padding: 15px 0 0 0;  text-align: center;  width: 33%;}input[type="radio"] + div.content-holder > div {  display: none;  position: absolute;  text-align: center;  top: 65px;  width: 100%;}input[type="radio"]:checked + div.content-holder > div {  display: block;}input[type="radio"]:checked + div.content-holder > label {  background-color: #B1CF6F;}img {  left: 0;  margin: 15px auto auto auto;  position: absolute;  right: 0;}
<div id="holder">  <input type="radio" name="tabs" value="1" id="check1" checked>  <div class="content-holder">    <label for="check1">one</label>    <div class="tab-content">      <p>All my content for the first tab goes here.</p>    </div>  </div>  <input type="radio" name="tabs" value="2" id="check2">  <div class="content-holder">    <label for="check2">two</label>    <div class="tab-content">      <h2>You can put whatever you want in your tabs!</h2>      <p>Any content, anywhere!</p>      <p>        Remember, though, they're absolutely positioned.        This means they position themselves relative to        their parent, div#holder, which is relatively positioned      </p>    </div>  </div>  <input type="radio" name="tabs" value="3" id="check3">  <div class="content-holder">    <label for="check3">three</label>    <div class="tab-content">      <p>        And maybe I want a picture of a nice cat in my third tab!      </p>      <img src="http://i.stack.imgur.com/Bgaea.jpg">    </div>  </div></div>

Tab system with pure CSS, anchor avoids the propagation to label

When you use input:checked, :target is not efficient cause this event is not triggered at all.

You need to put your input ahead in the flow so you can use the selector ~ to select any sibblings and their children following in the flow of the document:

example

a {  text-decoration: none;}.tabs {  position: relative;}input {  display: none;}.tabs .tab label {  text-decoration: none;  border: 1px solid black;  padding: 2px;  display: inline-block;  top: 2px;  position: relative;  cursor: pointer;}#check1:checked ~ .tabs label[for="check1"],#check2:checked ~ .tabs label[for="check2"],#check3:checked ~ .tabs label[for="check3"] {  background-color: white;  border-bottom: 0;  padding: 4px 2px;  top: 1px;}.contents {  border: 1px solid black;  background-color: white;}.contents .content {  display: none;  padding: 20px;}#check1:checked ~ .contents #tab1,#check2:checked ~ .contents #tab2,#check3:checked ~ .contents #tab3 {  display: block;}
<!-- begin hidden inputs for CSS tabs purpose --><input type="radio" name="ch" id="check1"><input type="radio" name="ch" id="check2"><input type="radio" name="ch" id="check3"><!-- End hidden inputs for CSS tabs purpose --><div class="tabs">  <span class="tab">    <label for="check1">      Tab 1    </label>  </span>  <span class="tab">    <label for="check2">      Tab 2    </label>  </span>  <span class="tab">    <label for="check3">      Tab 3    </label>  </span></div><div class="contents">  <div class="content" id="tab1">Contenido 1</div>  <div class="content" id="tab2"><strong>Contenido 2</strong>  </div>  <div class="content" id="tab3"><em>Contenido 3</em>  </div></div>

How to link to specific tab using w3c tab style

The :target pseudoclass might be the right choice for you.

The :target CSS pseudo-class represents a unique element (the target element) with an id matching the URL's fragment.

You can use it like following:

.tabcontent{  display:none;}.tabcontent:target{  display:block;}
<div class="tabbedbox">    <div class="tab">        <button class="tablinks" id="tab1">First</button>        <button class="tablinks" id="tab2">Second</button>        <button class="tablinks" id="tab3">Third</button>    </div>    <div id="First" class="tabcontent">       First Tab Text    </div>    <div id="Second" class="tabcontent">       Second Tab Text    </div>    <div id="Third" class="tabcontent">      Third Tab Text    </div></div><br><a href="#First">goto first tab content via #First hash</a>

Pure HTML and CSS tabs displaying incorrectly in firefox

If you hide the inputs, seems to behave the same in firefox and chrome. You don't need the inputs to be on the page, so you can hide them with display: none;

#tabscontainer {  display: -webkit-box;  display: -ms-flexbox;  display: -webkit-flex;  display: flex;  -webkit-box-orient: horizontal;  -webkit-box-direction: normal;  -webkit-flex-direction: row;  -ms-flex-direction: row;  flex-direction: row;  -webkit-flex-wrap: wrap;  -ms-flex-wrap: wrap;  flex-wrap: wrap;  position: relative;  margin-top: 0.35em;  margin-right: none;  padding: 0;  height: calc(100% - 0.35em);  width: 100%;}

/* Style the radio group that corresponds to the tabs */
#tabscontainer > [name="radiogroupfortabs"] { display: none;}

/* Set Flexbox ordering of radio items within the #tabscontainer. A unique rule has to be created for each tab. */
#tabscontainer > #radiofortab1 { -webkit-box-ordinal-group: 2; -webkit-order: 1; -ms-flex-order: 1; order: 1;}
#tabscontainer > #radiofortab2 { -webkit-box-ordinal-group: 3; -webkit-order: 2; -ms-flex-order: 2; order: 2;}
#tabscontainer > #radiofortab3 { -webkit-box-ordinal-group: 4; -webkit-order: 3; -ms-flex-order: 3; order: 3;}
#tabscontainer > #radiofortab4 { -webkit-box-ordinal-group: 5; -webkit-order: 4; -ms-flex-order: 4; order: 4;}

/* Style all radio group LABELS (by class) to look like tabs. */
#tabscontainer > [id^="tab-label"] { max-height: 18px; margin: 4px 2px 0 0; display: inline-block; padding: 5px 11px; border-width: 0.5px 0.5px 0.5px 0.5px; border-style: solid; border-color: dimgrey; background-color: lightgrey; -webkit-transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;}

/* Style unselected tabs (INPUT element's label) when the pointer hovers over them. Could use the background-image attribute here instead of colors in order to give the tab any appearance. */
#tabscontainer > [id^="tab-label"]:hover { background: #99ccff;}

/* Style all of the content DIVs including setting DISPLAY to None to start with.*/
#tabscontainer > [id^="tab-content"] { -webkit-box-ordinal-group: 999; -webkit-order: 999; -ms-flex-order: 999; order: 999; /*Set to a high value*/ display: none; z-index: 2; width: 100%; height: calc(100% - 2.3em); overflow: hidden; border: 0.5px solid dimgrey; background: white; margin-top: -3px;}

/* Style the currently selected tab (checked INPUT element's label)*/
#tabscontainer > [name="radiogroupfortabs"]:checked + [id^="tab-label"] { z-index: 4; /*brings to front*/ margin-top: 0px; padding-top: 9px; background-color: white; border-color: dimgrey dimgrey white dimgrey; line-height: 1em; font-weight: bold;}

/* Display the content DIV that corresponds to the selected tab (because of the limitations of CSS selectors, this could not be done with a single rule. A unique rule has to be created for each tab/tab content within the tab set.) */
#tabscontainer > #radiofortab1:checked ~ #tab-content1 { display: block;}
#tabscontainer > #radiofortab2:checked ~ #tab-content2 { display: block;}
#tabscontainer > #radiofortab3:checked ~ #tab-content3 { display: block;}
#tabscontainer > #radiofortab4:checked ~ #tab-content4 { display: block;}
<div id="lower-control-pane" class="row">  <hr id="tabs-rule" />  <div id="tabscontainer">    <!-- tab 1 -->    <input type="radio" name="radiogroupfortabs" id="radiofortab1" checked/>    <label id="tab-label1" for="radiofortab1">Workspace Status</label>    <div id="tab-content1">      <h2>Workspace Status</h2>      <p>test context for first tab component</p>    </div>    <!-- tab 2 -->    <input type="radio" name="radiogroupfortabs" id="radiofortab2" />    <label id="tab-label2" for="radiofortab2">Notes</label>    <div id="tab-content2">      <h2>Notes</h2>      <p>second tab test content</p>    </div>    <!-- tab 3 -->    <input type="radio" name="radiogroupfortabs" id="radiofortab3" />    <label id="tab-label3" for="radiofortab3">Global Names</label>    <div id="tab-content3">      <global-names-component (internalEditRequest)=globalNameEditRequest($event)></global-names-component>    </div>    <!-- tab 4 -->    <input type="radio" name="radiogroupfortabs" id="radiofortab4" />    <label id="tab-label4" for="radiofortab4">Log</label>    <div id="tab-content4">      <log-component></log-component>    </div>  </div></div>


Related Topics



Leave a reply



Submit