1

I am trying to use this recepee to implement tabs without using JS or JQuery, pure CSS, but I am stuck. The goal is to show different content on click on some label, and change the label style. Now it shows labels as I want, but content of each div somehow shown over the label, not under. Also, I cannot make it change style. Could anybody help? Thanks. Sorry if the question looks stupid - I am just starting with html.

Now it is like that:enter image description here

<div id="menu">
    <label class="collapse" for="1">tab1</label> <input id="1" name="r" type="radio" />
    <div>111111111111111111111</div>
    <label class="collapse" for="2">tab2</label> <input id="2" name="r" type="radio"/>
    <div>2222222222222222222222</div>
    <label class="collapse" for="3">tab3</label> <input id="3" name="r" type="radio" />
    <div>333333333333333333333</div>
</div>

my css:

    #menu {
        padding-left: 20px;
    }

    #menu label {
        height: 30px;
        background-color: #d1ecee;
        width: 75px;
        color: #2cb674;
        font-size: 12px;
        line-height: 30px;
        text-align: center;
        float: left;
        position: relative;
        margin-left: 2px;
    display:block;
        margin-right: 20px;
    }

    #menu label:before {
        content: "";
        position: absolute;
        left: -20px;
        width: 0;
        height: 0;
        border-top: 30px solid #d1ecee;
        border-left: 20px solid transparent;
    display:block;
    }

    #menu label:after {
        content: "";
        position: absolute;
        right: -20px;
        width: 0;
        height: 0;
        border-bottom: 30px solid #d1ecee;
        border-right: 20px solid transparent;

    }

#menu input {
    display: none !important;
}

#menu input+* {
    display: none !important;
}
#menu input:checked+* {
    display: block !important;
}

#menu input:checked+label {
    background-color: #2cb674;
    color: white;
}

#menu input:checked+label:before {
    border-top: 30px solid #2cb674;
}

#menu input:checked+label:after {
    border-bottom: 30px solid #2cb674;
}

UPDATE:

this is the picture I have now due to absolute positioning of target div enter image description here

Community
  • 1
  • 1
Battle_Slug
  • 2,055
  • 1
  • 34
  • 60
  • why you use menu + input in first place? hmm – Szymon Dec 20 '15 at 19:07
  • @SzymonDziewoński It seems it doesn't affect the result. Also I added another part of css I missed before. – Battle_Slug Dec 20 '15 at 19:20
  • 1
    For starters your rules with `#menu +input` will never work. `+` tells CSS to find a sibling. However your inputs are children of #menu, not it's siblings. – tbernard Dec 20 '15 at 19:51
  • Also your `input:checked label` rules will not work since label is a sibling to input, but this is telling CSS to find a label that is a child of input – tbernard Dec 20 '15 at 19:52
  • @tbernard I edited, please see, still doesn't work as needed – Battle_Slug Dec 20 '15 at 20:03
  • you could have a look at the `:focus` psuedo selector too, used in conjunction with `tabindex` in the HTML it can give a selected effect, however, it's more for visual effect rather than interactive elements - there's a few questions on here somewhere – Toni Leigh Dec 21 '15 at 21:34

1 Answers1

1

You have a problem with your sibling selectors. the + sign should select the next sibling element in your HTML, refer to 30 CSS selectors you should know

A more elegant way is to:

  1. hide your radio buttons with opacity and absolute positioning
  2. make the tab content containers absolute positioned to keep them below tab buttons
  3. show the tab content whose radio button is checked
  4. re-arranage the html so the the order is input, label then div

HTML

<div id="menu">

    <!-- Selected by default -->

    <input id="1" name="r" type="radio" checked/>
    <label class="collapse" for="1">tab1</label>
    <div>111111111111111111111</div>

    <input id="2" name="r" type="radio"/>
    <label class="collapse" for="2">tab2</label>
    <div>2222222222222222222222</div>

    <input id="3" name="r" type="radio" />
    <label class="collapse" for="3">tab3</label>
    <div>333333333333333333333</div>
</div>

CSS

#menu {
    padding-left: 20px;
}
#menu label {
    height: 30px;
    background-color: #d1ecee;
    width: 75px;
    color: #2cb674;
    font-size: 12px;
    line-height: 30px;
    text-align: center;
    float: left;
    position: relative;
    margin-left: 2px;
    display:block;
    margin-right: 20px;
}
#menu label:before {
    content: "";
    position: absolute;
    left: -20px;
    width: 0;
    height: 0;
    border-top: 30px solid #d1ecee;
    border-left: 20px solid transparent;
    display:block;
}
#menu label:after {
    content: "";
    position: absolute;
    right: -20px;
    width: 0;
    height: 0;
    border-bottom: 30px solid #d1ecee;
    border-right: 20px solid transparent;
}
#menu input:checked + label {
    background-color: #2cb674;
    color: white;
}
#menu input:checked + label:before {
    border-top: 30px solid #2cb674;
}

#menu input:checked + label:after {
    border-bottom: 30px solid #2cb674;
}

/* Hide radio buttons */
#menu input[type=radio]{
    opacity:0;
    position:absolute;
    left:-200%;
}

/* Hide all tab divs and keep them below the tab buttons */
#menu > div {
    display:none;
    top:5em;
    position:absolute;
    max-width:100%;
}

/* Show the tab whose sibling radio button is checked */
#menu input:checked + label + div{
    display:block;
}

tabs in CSS

This should work just fine

William
  • 740
  • 2
  • 11
  • 18
  • 1
    That's awesome. I tried to put label after input according to some principles, but was still fiddling around. Thanks a lot, I appreciate your help. I learned a lot also. – Battle_Slug Dec 20 '15 at 21:09
  • Unfortunately, the problem I faced: it works if it is the only element on the page, but if I put it inside some div surrounded by other divs, tabs change their styles ok, but related divs are shown in absolute position somewhere on top, covering all other content. If I remove position:absolute; from #menu > div, it completely disrupts the design (( Could you check please? Thanks. Just for the case: content divs are for showing lists of data, so they can be of any size. – Battle_Slug Dec 21 '15 at 04:01
  • could you take a screenshot so I can see what's happening? The reason I used absolute positioning is so that all the divs can stay below the tabs, like a stack of cards – William Dec 21 '15 at 06:07
  • yes, please check in my updated question. – Battle_Slug Dec 21 '15 at 14:45