Search code examples
javascripthtmlcsstabsmousehover

Javascript+Css, request solution: mouseover hover displays div, stays active until mouseoff/click closes


Okay, so: I am trying to put an infobox-sort of thing on my page. The basic idea is as follows:

  • person mouses over brown curved-cornered tab. Tab changes color to white, becomes square, and box of info about that tab appears.

  • as long as mouse remains over that tab or over related box of info, tab remains white and square, and related box of info remains open.

  • person mouses off of tab and related box. Box closes, tab returns to brown and curvy.

So far, I have managed to make the brown tabs turn white if hovered, and the box of info appears. it remains white and the info stays open. However, I cannot figure out two things:

- how to make the corner tabs change their shape on mouseover and then revert once moused off -- have only managed through various tests to make it either permanently brown/round, or white/square, no switching.

- how to make the infobox and tab color/shape revert to normal brown/curvy/invisible once moused off.

I have been using the w3school How-tos and some stackoverflow threads to get this far, but I've hit a wall and I don't remember enough javascript to figure out what I've got wrong. I hope I'm providing enough information for assistance.

If possible, I need a solution in CSS/Javascript. Most possible solutions I've seen are in jquery, which I'm even more baffled by. However, if there is an easier solution to all my problems that I have somehow missed, I am very open to learning it.

For reference, here is my code:

the css of my page:

/* Style the containment unit*/
.tabcontainer {
    clear: both;
    border-top: 1px solid #BB8571;
    margin-top: 10px;
    -webkit-box-shadow: inset 0px 8px 5px -3px rgba(0,0,0,0.1);
    -moz-box-shadow: inset 0px 8px 5px -3px rgba(0,0,0,0.1);
    box-shadow: inset 0px 8px 5px -3px rgba(0,0,0,0.1);
    min-height:200px;

}

/* Style the tabs*/
.tabcontainer button {
    display:block;
    width:20%;
    float:left;
    text-align:center;
    padding: 1em;
    -webkit-box-shadow: inset 0px 8px 5px -3px rgba(0,0,0,0.1);
    -moz-box-shadow: inset 0px 8px 5px -3px rgba(0,0,0,0.1);
    box-shadow: inset 0px 8px 5px -3px rgba(0,0,0,0.1);
    font-family: "Century Gothic", Verdana, Geneva, sans-serif;
    letter-spacing: 0.2em;
    border: none;
    outline: none;

}

.tabcontainer button:nth-child(even) {background:#d7b8ac;}
.tabcontainer button:nth-child(odd) {background:#f4dac3;}

/* Change background color of tabs on hover and maintain change while active */
.tabcontainer button:hover, .tabcontainer button.active {
    background-color:#fff;
}

/*specific corner tab styling*/
.tabcontainer button:nth-child(1) {
    -webkit-border-bottom-left-radius: 25px;
    -moz-border-radius-bottomleft: 25px;
    border-bottom-left-radius: 25px;
}

.tabcontainer button:nth-child(5) {
    -webkit-border-bottom-right-radius: 25px;
    -moz-border-radius-bottomright: 25px;
    border-bottom-right-radius: 25px;
    }

/* Style the infoboxes */
.tabcontent {
    display:none;
    background-color:tan;
    padding:2em 1em 1em;
    height:170px;
    -webkit-border-bottom-left-radius: 25px;
    -moz-border-radius-bottomleft: 25px;
    border-bottom-left-radius: 25px;
    -webkit-border-bottom-right-radius: 25px;
    -moz-border-radius-bottomright: 25px;
    border-bottom-right-radius: 25px;
    -webkit-box-shadow: inset 0px -5px 5px 3px rgba(0,0,0,0.1);
    -moz-box-shadow: inset 0px -5px 5px 3px rgba(0,0,0,0.1);
    box-shadow: inset 0px -5px 5px 3px rgba(0,0,0,0.1);
}

the html of my page:

<div class="tabcontainer"> <!––wraps around both tabs and info boxes-->

 <!––below: bar of button tabs--> 

<button class="tablinks" id="t1" onmouseover="infoBox(event, 'b1')">b1</button>
      <button class="tablinks" id="t2" onmouseover="infoBox(event, 'b2')">b2</button>
      <button class="tablinks" id="t3" onmouseover="infoBox(event, 'b3')">b3</button>
      <button class="tablinks" id="t4" onmouseover="infoBox(event, 'b4')">b4</button>
      <button class="tablinks" id="t5" onmouseover="infoBox(event, 'b5')">b5</button>

<!––below: five infoboxes with generic contents-->

<div id="b1" class="tabcontent">
  <h3>London</h3>
  <p>London is the capital city of England.</p>
</div>

<div id="b2" class="tabcontent">
  <h3>Paris</h3>
  <p>Paris is the capital of France.</p> 
</div>

<div id="b3" class="tabcontent">
  <h3>LA</h3>
  <p>Tokyo is the capital of Japan.</p>
</div>

<div id="b4" class="tabcontent">
  <h3>NYC</h3>
  <p>Tokyo is the capital of Japan.</p>
</div>

<div id="b5" class="tabcontent">
  <h3>Tokyo</h3>
  <p>Tokyo is the capital of Japan.</p>
</div>

</div>

and the javascript of my page, which as you can see is heavily notated as I try to figure out how the heck it works.

//start infoBox function to open infobox of a tab, concerning event and affected 'tab id'
function infoBox(event, tabID) {
//declare variables of i=data, tabcontent=blurb, tablinks=buttons
    var i, tabcontent, tablinks;
// find variable=tabcontent as anything with class 'tabcontent'
    tabcontent = document.getElementsByClassName("tabcontent");
// hide variables of tabcontents   
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }
// find variable=tablinks as anything with class 'tablinks'    
    tablinks = document.getElementsByClassName("tablinks");
// remove active status of tablinks   
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }
// show the current onmouseover tab
    document.getElementById(tabID).style.display = "block";
// related named target of event infobox, activate and show   
    event.currentTarget.className += " active";
}

Solution

  • tl;dr

    You need also function to remove the info tabs on mouseout. They won't automagically "un-onmouseover" themselves :-) And while doing that, also remove .active class;

    Working code:

    function infoBox(event, tabID) {
    //declare variables of i=data, tabcontent=blurb, tablinks=buttons
        var i, tabcontent, tablinks;
    // find variable=tabcontent as anything with class 'tabcontent'
        tabcontent = document.getElementsByClassName("tabcontent");
    // hide variables of tabcontents   
        for (i = 0; i < tabcontent.length; i++) {
            tabcontent[i].style.display = "none";
        }
    // find variable=tablinks as anything with class 'tablinks'    
        tablinks = document.getElementsByClassName("tablinks");
    // remove active status of tablinks   
        for (i = 0; i < tablinks.length; i++) {
            tablinks[i].className = tablinks[i].className.replace(" active", "");
        }
    // show the current onmouseover tab
        document.getElementById(tabID).style.display = "block";
    // related named target of event infobox, activate and show   
        event.currentTarget.className += " active";
    }
    
    function closeInfoBox() {
    	var tabcontent = document.getElementsByClassName("tabcontent");
        // hide tabcontents   
        for (i = 0; i < tabcontent.length; i++) {
            tabcontent[i].style.display = "none";
        }
        // remove also active class
        var tablinks = document.getElementsByClassName("tablinks");
        for (i = 0; i < tablinks.length; i++) {
            tablinks[i].className = tablinks[i].className.replace(" active", "");
        }
    }
    .tabcontainer {
        clear: both;
        border-top: 1px solid #BB8571;
        margin-top: 10px;
        -webkit-box-shadow: inset 0px 8px 5px -3px rgba(0,0,0,0.1);
        -moz-box-shadow: inset 0px 8px 5px -3px rgba(0,0,0,0.1);
        box-shadow: inset 0px 8px 5px -3px rgba(0,0,0,0.1);
        min-height:200px;
    
    }
    
    /* Style the tabs*/
    .tabcontainer button {
        display:block;
        width:20%;
        float:left;
        text-align:center;
        padding: 1em;
        -webkit-box-shadow: inset 0px 8px 5px -3px rgba(0,0,0,0.1);
        -moz-box-shadow: inset 0px 8px 5px -3px rgba(0,0,0,0.1);
        box-shadow: inset 0px 8px 5px -3px rgba(0,0,0,0.1);
        font-family: "Century Gothic", Verdana, Geneva, sans-serif;
        letter-spacing: 0.2em;
        border: 1px solid grey;
        outline: none;
        border-bottom-left-radius: 10px;
        border-bottom-right-radius: 10px;
        transition: all .5s;
    
    }
    
    .tabcontainer button:nth-child(even) {background:#d7b8ac;}
    .tabcontainer button:nth-child(odd) {background:#f4dac3;}
    
    /* Change background color of tabs on hover and maintain change while active */
    .tabcontainer button:hover, .tabcontainer button.active {
        background-color:#fff;
        border-bottom-left-radius: 0px;
        border-bottom-right-radius: 0px;
    }
    
    /*specific corner tab styling*/
    .tabcontainer button:nth-child(1) {
        -webkit-border-bottom-left-radius: 25px;
        -moz-border-radius-bottomleft: 25px;
        border-bottom-left-radius: 25px;
    }
    
    .tabcontainer button:nth-child(5) {
        -webkit-border-bottom-right-radius: 25px;
        -moz-border-radius-bottomright: 25px;
        border-bottom-right-radius: 25px;
        }
    
    /* Style the infoboxes */
    .tabcontent {
        display:none;
        background-color:tan;
        padding:2em 1em 1em;
        height:170px;
        -webkit-border-bottom-left-radius: 25px;
        -moz-border-radius-bottomleft: 25px;
        border-bottom-left-radius: 25px;
        -webkit-border-bottom-right-radius: 25px;
        -moz-border-radius-bottomright: 25px;
        border-bottom-right-radius: 25px;
        -webkit-box-shadow: inset 0px -5px 5px 3px rgba(0,0,0,0.1);
        -moz-box-shadow: inset 0px -5px 5px 3px rgba(0,0,0,0.1);
        box-shadow: inset 0px -5px 5px 3px rgba(0,0,0,0.1);
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Document</title>
    </head>
    <body>
      <div class="tabcontainer"> <!––wraps around both tabs and info boxes-->
    
     <!––below: bar of button tabs--> 
    
    <button class="tablinks" id="t1" onmouseover="infoBox(event, 'b1')" >b1</button>
          <button class="tablinks" id="t2" onmouseover="infoBox(event, 'b2')" >b2</button>
          <button class="tablinks" id="t3" onmouseover="infoBox(event, 'b3')" >b3</button>
          <button class="tablinks" id="t4" onmouseover="infoBox(event, 'b4')" >b4</button>
          <button class="tablinks" id="t5" onmouseover="infoBox(event, 'b5')" >b5</button>
    
    <div id="b1" class="tabcontent" onmouseleave="closeInfoBox()">
      <h3>London</h3>
      <p>London is the capital city of England.</p>
    </div>
    
    <div id="b2" class="tabcontent" onmouseleave="closeInfoBox()">
      <h3>Paris</h3>
      <p>Paris is the capital of France.</p> 
    </div>
    
    <div id="b3" class="tabcontent" onmouseleave="closeInfoBox()">
      <h3>LA</h3>
      <p>Tokyo is the capital of Japan.</p>
    </div>
    
    <div id="b4" class="tabcontent" onmouseleave="closeInfoBox()">
      <h3>NYC</h3>
      <p>Tokyo is the capital of Japan.</p>
    </div>
    
    <div id="b5" class="tabcontent" onmouseleave="closeInfoBox()">
      <h3>Tokyo</h3>
      <p>Tokyo is the capital of Japan.</p>
    </div>
    
    </div>
    </body>
    </html>