1

I am creating tabs using CSS only. The way it works is, there are 3 radio buttons, and a label for each radio button. The tab contents are set to display: none. When a tab gets selected, then that tab contents become display: block

Since there were white spaces separating the labels (tabs) I added a div around the input/label elements and used the Flexbox technique.

Now that I added the div around the inputs/labels, the tab contents never show, they never become display: block.

How can I make the tab contents show when a tab gets selected?

Here's the relevant code:

.tab1:checked ~ .tab1,
.tab2:checked ~ .tab2,
.tab3:checked ~ .tab3 {
  display: block;
}

Working, but with white space
JSFiddle

.tab {
  background-color: yellow;
  display: inline-block;
  width: calc(100% / 3);
  height: 50px;
  outline: 1px green solid;
}
.tabContent,
input {
  display: none;
}
.tab1:checked ~ .tab1,
.tab2:checked ~ .tab2,
.tab3:checked ~ .tab3 {
  display: block;
}
<div id="overallDiv">
  <input type="radio" name="tabGroup1" id="rad1" class="tab1" checked="checked" />
  <label for="rad1" class="tab">Fisrt Tab</label>

  <input type="radio" name="tabGroup1" id="rad2" class="tab2" />
  <label for="rad2" class="tab">Second Tab</label>

  <input type="radio" name="tabGroup1" id="rad3" class="tab3" />
  <label for="rad3" class="tab">Third Tab</label>

  <div class="tabContent tab1" id="first">
    First Tab
  </div>
  <div class="tabContent tab2" id="second">
    Second Tab
  </div>
  <div class="tabContent tab3" id="third">
    Third Tab
  </div>
</div>

Not Working, but now white spaces
JSFiddle

.tab {
  background-color: yellow;
  display: inline-block;
  width: calc(100% / 3);
  height: 50px;
  outline: 1px green solid;
}
.tabContent,
input {
  display: none;
}
.tab1:checked ~ .tab1,
.tab2:checked ~ .tab2,
.tab3:checked ~ .tab3 {
  display: block;
}
<div id="overallDiv">
  <div id="tabWrapper" style="display: flex;">
    <input type="radio" name="tabGroup1" id="rad1" class="tab1" checked="checked" />
    <label for="rad1" class="tab">Fisrt Tab</label>

    <input type="radio" name="tabGroup1" id="rad2" class="tab2" />
    <label for="rad2" class="tab">Second Tab</label>

    <input type="radio" name="tabGroup1" id="rad3" class="tab3" />
    <label for="rad3" class="tab">Third Tab</label>
  </div>

  <div class="tabContent tab1" id="first">
    First Tab
  </div>
  <div class="tabContent tab2" id="second">
    Second Tab
  </div>
  <div class="tabContent tab3" id="third">
    Third Tab
  </div>
</div>
Community
  • 1
  • 1
Jessica
  • 9,379
  • 14
  • 65
  • 136
  • add `float: left` to your `.tab` style – Anthony Dec 01 '15 at 22:31
  • `float` isn't meant for layout. See this answer: http://stackoverflow.com/a/15177860/4861207 If you don't want to read the whole thing, just read the part about float. – Jessica Dec 02 '15 at 00:24
  • Thanks. I never knew. I posted an answer. I hope it helps. – Anthony Dec 02 '15 at 02:52
  • Possible duplicate of [How to remove the space between inline-block elements?](http://stackoverflow.com/questions/5078239/how-to-remove-the-space-between-inline-block-elements) – Asons Dec 02 '15 at 19:52

2 Answers2

1

As inline element have a space margin, your div becomes a little bigger than 33% and therefore doesn't fit in 1 row.

To your Working, but with white space sample I added margin-right: -4px; re-ordered your html a little to take that space out, but this can be done using other hacks, floats and flex. (for floats/flex, see below)

The trick in this case is to make the inline elements stop and start tag to be on the same line like this: </label><label

Note: These margin space issues has already been solved before

.tab {
  background-color: yellow;
  display: inline-block;
  width: calc(100% / 3);
  height: 50px;
  outline: 1px green solid;
}
.tabContent,
input {
  display: none;
}
.tab1:checked ~ .tab1,
.tab2:checked ~ .tab2,
.tab3:checked ~ .tab3 {
  display: block;
}
<div id="overallDiv">
  <input type="radio" name="tabGroup1" id="rad1" class="tab1" checked="checked" />
  <input type="radio" name="tabGroup1" id="rad2" class="tab2" />
  <input type="radio" name="tabGroup1" id="rad3" class="tab3" />
  <label for="rad1" class="tab">First Tab
  </label><label for="rad2" class="tab">Second Tab
  </label><label for="rad3" class="tab">Third Tab
  </label>

  <div class="tabContent tab1" id="first">
    First Tab
  </div>
  <div class="tabContent tab2" id="second">
    Second Tab
  </div>
  <div class="tabContent tab3" id="third">
    Third Tab
  </div>
</div>

As requested a flex version.

#overallDiv {
  display: flex;
  flex-wrap: wrap;
}
.tab {
  background-color: yellow;
  width: calc(100% / 3);
  height: 50px;
  outline: 1px green solid;
}
.tabContent,
input {
  display: none;
}
.tabContent {
  width: 100%;
}
.tab1:checked ~ .tab1,
.tab2:checked ~ .tab2,
.tab3:checked ~ .tab3 {
  display: block;
}
<div id="overallDiv">
    <input type="radio" name="tabGroup1" id="rad1" class="tab1" checked="checked" />
    <label for="rad1" class="tab">Fisrt Tab</label>

    <input type="radio" name="tabGroup1" id="rad2" class="tab2" />
    <label for="rad2" class="tab">Second Tab</label>

    <input type="radio" name="tabGroup1" id="rad3" class="tab3" />
    <label for="rad3" class="tab">Third Tab</label>

  <div class="tabContent tab1" id="first">
    First Tab
  </div>
  <div class="tabContent tab2" id="second">
    Second Tab
  </div>
  <div class="tabContent tab3" id="third">
    Third Tab
  </div>
</div>

Edit

Here is a "floats" version

#overallDiv {
  clear: left;
}
.tab {
  background-color: yellow;
  float: left;
  width: calc(100% / 3);
  height: 50px;
  outline: 1px green solid;
}
.tabContent,
input {
  display: none;
}
.tab1:checked ~ .tab1,
.tab2:checked ~ .tab2,
.tab3:checked ~ .tab3 {
  display: block;
}
<div id="overallDiv">
  <input type="radio" name="tabGroup1" id="rad1" class="tab1" checked="checked" />
  <label for="rad1" class="tab">First Tab</label>
  
  <input type="radio" name="tabGroup1" id="rad2" class="tab2" />
  <label for="rad2" class="tab">Second Tab</label>
  
  <input type="radio" name="tabGroup1" id="rad3" class="tab3" />
  <label for="rad3" class="tab">Third Tab</label>

  <div class="tabContent tab1" id="first">
    First Tab
  </div>
  <div class="tabContent tab2" id="second">
    Second Tab
  </div>
  <div class="tabContent tab3" id="third">
    Third Tab
  </div>
</div>
Community
  • 1
  • 1
Asons
  • 84,923
  • 12
  • 110
  • 165
  • I like the flex method the best. Is there a way doing that using flex? – Jessica Dec 01 '15 at 22:28
  • @Jessica Added a flex version to my answer. – Asons Dec 01 '15 at 22:42
  • Thanks! The flexbox version is causing me more problems, so I think I'll just go with the margin technique. Will it always be `-4px`? (In different browsers. etc) Is it safe to rely on that? – Jessica Dec 02 '15 at 00:37
  • @Jessica I updated my answer (first sample) with another and more safer way than the margin trick. The margin trick though, is also safe, safer than the `font-size: 0` trick, but one might need to adjust the negative margin value a little based on the font size used. – Asons Dec 02 '15 at 12:23
  • @Jessica Btw, if you want flex, add a new question with the problems you got and post me a comment here and I might be able to assist with that (or someone before me). – Asons Dec 02 '15 at 12:41
  • Thanks! Appreciate it! – Jessica Dec 02 '15 at 17:42
  • How is the margin trick safer than `font-size: 0`? Take a look at solution 3 in the link I posted in my answer. It says to **avoid** the margin trick at all costs. – Anthony Dec 02 '15 at 19:38
  • @Anthony The `font-size: 0` trick has issues on some Andriod versions which margin trick hasn't. **But** you are very right, all those tricks should be avoided at all costs and therefore I changed my answer earlier to a better solution. – Asons Dec 02 '15 at 19:44
  • @Anthony As the question kind of already had a solution (posted links in my anser) which wasn't obvious based on the title, I also made my answer a community wiki to not get any vote credits in the future. – Asons Dec 02 '15 at 19:50
  • 1
    I don't really care about vote credits. I am here to learn. Thanks for the response. – Anthony Dec 02 '15 at 20:13
0

There are a couple of methods to remove whitespace. Here's a good article on a couple of methods https://davidwalsh.name/remove-whitespace-inline-block. If you don't want your html to become messy you could add a font-size of 0 to the parent element, then if you have text in the child elements add a font-size to them. Your CSS would look like this:

parent element:

#overallDiv {
    font-size: 0;
}

child elements:

.tabs {
    font-size: 14px;
}

Here's a jsfiddle.

Anthony
  • 1,439
  • 1
  • 19
  • 36