Mehul Chachada
Mehul Chachada

Reputation: 583

How to display list on button hover?

I am trying to display the list on button hover, but what happens is, whenever I hover near the button area, text gets displayed.

.header_nav {
  width: 800px;
  height: 400px;
}
.header_nav ul {
  list-style: none;
}
.header_nav ul ul {
  display: none;
}
.header_nav ul ul #nav_button:hover>ul {
  display: block;
}
.header_nav ul ul li >ul {
  display: none;
}
.header_nav ul li:hover >ul {
  display: block;
}
<nav class="header_nav">
  <ul>
    <li>
      <input type="button" value="Button 1" name="nav_button" id="nav_button">
      <ul>
        <li>Locations</li>
        <li>
          Mumbai
          <ul>
            <li>Txt 1</li>
            <li>Txt 2s</li>
            <li>Txt 3</li>
          </ul>
        </li>
        <li>Delhi</li>
        <li>Banglore</li>
        <li>Nagpur</li>
      </ul>
    </li>
  </ul>
</nav>

JS FIDDLE : https://jsfiddle.net/fhv7drst/

Upvotes: 3

Views: 5774

Answers (3)

geeksal
geeksal

Reputation: 5016

As pointed by @Rahul Arora indeed it is because of li as block element.

But if for some reason you still want to keep it as block element, you can keep it by making it as inline-block. I also recommend removing margin (see your given example by inspect element, it is to the write of ul) and padding which is assigned by browser as default.

Here is the code:

  .header_nav
    {
      width:800px;
      height:400px;
    }
    .header_nav ul 
    {
      list-style:none;

      //displaying ul & all its child as inline block until overriden by other rules
      display:inline-block;
     
     //removing default margin and padding
      margin:0;
      padding:0;
    }
    .header_nav ul ul
    {
      display:none;
    }
    .header_nav ul ul #nav_button:hover>ul
    {
     display:block;
    }
    .header_nav ul ul li >ul
    {
      display:none;
    }
    .header_nav ul li:hover >ul
    {
     display:block;
    }
 <nav class="header_nav">
                 <ul>
                    <li> 
                    <input type="button" value="Button 1" name="nav_button" id="nav_button">
                        <ul>
                             <li>Locations</li>
                            <li> 
                            Mumbai
                             <ul>
                                <li>Txt 1</li>
                                <li>Txt 2s</li>
                                <li>Txt 3</li>
                            </ul>
                            </li>
                             
                            <li>Delhi</li>
                            <li>Banglore</li>
                            <li>Nagpur</li>
                         </ul>
                         
                     </li>
                    </ul>
             </nav>

Upvotes: 2

TheThirdMan
TheThirdMan

Reputation: 1522

The reason is that your li element is a block element, which means that it will automatically try to span the entire width available. In your case, this is the 800px provided by the topmost element.

You have two solutions readily available - one is to make the list element an inline-block element (or simply an inline element, though I'd prefer inline-block here, as block is how it started) to prevent it spaning the whole width:

.header_nav ul li {
    display: inline-block;
}

You could also trigger the display change on the unordered list when hovering over the button directly, not when hovering over it's parent list item:

.header_nav #nav_button:hover + ul {
   display: block;
}

This is likely the better solution, as it doesn't mess with the display types more than you need to, and you more accurately describing what you want to happen - show the list when the button is hovered.

Upvotes: 2

Rahul Arora
Rahul Arora

Reputation: 4533

It is because your li element was block element.

I changed it to inline and it started working as per your requirements

HTML:

 <li class="parentElement"> 
                    <input type="button" value="Button 1" name="nav_button" id="nav_button">

CSS:

 li.parentElement{
    display: inline;
  }

here is the working fiddle

https://jsfiddle.net/m73p8pea/

Upvotes: 7

Related Questions