6

is it possible to create a tabbed interface using just css, no javascript? I mean to be able to switch the tabs using css/html, without javascript. Maybe with CSS 3.0?

the markup would be something like:

<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>

<div id="tab1"> ...1... </div>
<div id="tab2"> ...2... </div>
<div id="tab3"> ...3... </div>
4
  • 4
    JavaScript-less interactions are nice in theory, but they break the "holy-trinity" of web development. HTML is meant for Content (Model), CSS is meant for Style (View), JavaScript is meant for Interaction (Controller). If you don't want to use JavaScript, HTML and CSS have to take up the slack, which means you'll be changing your markup to change the style. Generally speaking, you should leave the interactions to JavaScript, and plan for graceful degradation with your style sheets. Commented Feb 8, 2011 at 21:32
  • @zzzzBov HTML in my opinion is meant the be the view. The model is where the data lies (in a database?) and the controller is the code that manipulates the data (PHP or ASP on the server, perhaps?) CSS and JavaScript are to provide visual enhancements, but if they are removed, the website should still function - otherwise it would break the HTTP model! Commented Nov 11, 2011 at 14:16
  • @Greg, In the context of the UI, HTML contains the data and is the model. If you're talking about the overarching context of a web application, your database is the model, your controller is a server script and your view is the generated HTML, CSS, & JS. Commented Nov 11, 2011 at 14:20
  • @zzzzBov Then someone like me comes along, who browses with JavaScript off by default (since even large well known sites get compromised) and curses your name forever because your site doesn't work. Which is one of several reasons to adopt progressive enhancement, which this question does. Commented Apr 25, 2013 at 3:04

4 Answers 4

22

:target is generally the preferred way of doing tabs.

You can also be clever with input:radio, or input:checkbox elements.

Using the next-sibling (+) and :checked selectors in clever ways can allow you to do a pure CSS accordion, toggleable lists, or tabs like this.

input {
  position: absolute;
  right: 100%;
}

input:checked+div {
  display: block;
}

div {
  display: none;
}
<label for="one">One</label>
<label for="two">Two</label>
<label for="three">Three</label>

<input type="radio" id="one" name="tab" checked="checked" />
<div>
  First content
</div>
<input type="radio" id="two" name="tab" />
<div>
  Second content
</div>
<input type="radio" id="three" name="tab" />
<div>
  Third content
</div>

View on JSFiddle

Sign up to request clarification or add additional context in comments.

2 Comments

Would this solution be considered "accessible"?
No, ARIA needs to be applied in order to make an accessible tabs interface. It's not possible with CSS alone.
5

In pure CSS3 you can use the :target selector to achieve a "tabbed interface".
Just google "tab css3 :target". Here's a tutorial about it.

Comments

1

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

1 Comment

I don't understand how this became the accepted answer, since it is the only one that doesn't actually answer the question... O_o
1

Here is a super easy code for achieving the functionality

.tabs {
  display: flex;
  flex-direction: column;
}
 
.tabs .tab-labels {
  display: flex;
  gap:3px;
}
 
.tabs input[type="radio"] {
 display: none;
}
 
.tabs label {
  padding: 1em;
  background: #9AA092;
  cursor: pointer;
  width: 33.333%;
}
 
.tab-content {
  padding: 1em;
  display: none;
  background: DodgerBlue;
}
 
/* Show tab content when corresponding radio button is checked */
#tab1:checked ~ #content1,
#tab2:checked ~ #content2,
#tab3:checked ~ #content3 {
  display: block;
}
<div class="tabs">
  <input type="radio" id="tab1" name="tabs" checked>
  <input type="radio" id="tab2" name="tabs">
  <input type="radio" id="tab3" name="tabs">
 
  <div class="tab-labels">
    <label for="tab1">Tab 1</label>
    <label for="tab2">Tab 2</label>
    <label for="tab3">Tab 3</label>
  </div>
  
  <div id="content1" class="tab-content">
    <h2>Tab 1</h2>
    <p>This is the content for Tab 1.</p>
  </div>
  
  <div id="content2" class="tab-content">
    <h2>Tab 2</h2>
    <p>This is the content for Tab 2.</p>
  </div>
  
  <div id="content3" class="tab-content">
    <h2>Tab 3</h2>
    <p>This is the content for Tab 3.</p>
  </div>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.