Isengardium
Isengardium

Reputation: 115

How to prevent overlapping dropdown menu with borders?

I have a hovering drop down menu, after putting a border on hover, my dropdown menu overlaps with the menu. Tried to add padding but it's even worse. How can you adjust the position of the dropdown, knowing I have a 5px border transparent when not hovering, transforming into a 5px border solid at bottom when hovering?

#nav {
    background-color: #e26a63;
}
#wrap {
    padding-left: 60px;
    height: 100px;
    width: 100%;
    margin: 0 auto;
    display: table-cell; 
    vertical-align: bottom;
}
#nav ul {
    list-style-type: none;
    padding: 0;
    margin: 0;
    position: relative;
    min-width: 200px; 
}
#nav ul li {
    display: inline-block;
    border: 5px solid transparent;
}
#nav ul li:hover {
    background-color: #cb5f59;
    border-bottom: 5px solid #9e4a45;
}
#nav ul li a, visited {
    color: white;
    display: block;
    padding: 15px;
    text-decoration: none;
}
#nav ul li:hover ul {
    display: block;
}
#nav ul ul {
    display: none;
    position: absolute;
    background-color: #e26a63;
    border-top: 0;
    margin-left: -5px;
}
#nav ul ul li {
    display: block;
}
#nav ul ul li a:hover {
    color: white;
}
<div id="nav">
	<div id="wrap">
    	<ul>
        <li><a href="#">Home</a></li><li>
        <a href="#">Study</a></li><li>
        <a href="#">Games</a>
        	<ul>
            	<li><a href="#">Riddles</a></li><li> 
                <a href="#">Flip card game</a></li><li>  
                <a href="#">Spot the mistake</a></li><li> 
                <a href="#">Multiple choice</a></li>            	
            </ul>
          </li><li>
        <a href="#">Read</a></li><li>
        <a href="#">Contact</a></li><li>
        <a href="#">About Us</a></li>
        </ul>
    </div>
</div>

Upvotes: 1

Views: 2755

Answers (4)

Stickers
Stickers

Reputation: 78686

Short answer is to add margin-top: 5px; to #nav ul ul, where 5px is the same value of the bottom border width.

Note the following set of style outputs a trapezoid shape1 bottom border on hover.

#nav ul li { border: 5px solid transparent; }
#nav ul li:hover { border-bottom: 5px solid #9e4a45; }

Change border in first line to border-bottom it will then output a real rectangle shape.

I also reorganized the CSS table layout, make the table to be centered automatically (I guess you wanted that, but it's easy to change if not). And removed the border style in drop down items.

Jsfiddle Example

#nav {
    background-color: #e26a63;
}
#wrap {
    display: table;
    height: 100px;
    margin: 0 auto;
}
#nav ul {
    padding: 0;
    margin: 0;
    display: table-cell; 
    vertical-align: bottom;
}
#nav ul li {
    display: inline-block;
    border-bottom: 5px solid transparent;
}
#nav ul li a {
    display: block;
    padding: 15px;
    text-decoration: none;
    color: white;
}
#nav ul ul {
    display: none;
    position: absolute;
    background-color: #e26a63;
    margin-top: 5px;
}
#nav ul ul li {
    display: block;
    min-width: 200px;
}

/* hover */
#nav ul li:hover {
    background-color: #cb5f59;
    border-bottom-color: #9e4a45;
}
#nav ul li:hover ul {
    display: block;
}
#nav ul li:hover li {
  border-bottom-width: 0;
}
<div id="nav">
	<div id="wrap">
    	<ul>
        <li><a href="#">Home</a></li><li>
        <a href="#">Study</a></li><li>
        <a href="#">Games</a>
        	<ul>
            	<li><a href="#">Riddles</a></li><li> 
                <a href="#">Flip card game</a></li><li>  
                <a href="#">Spot the mistake</a></li><li> 
                <a href="#">Multiple choice</a></li>            	
            </ul>
          </li><li>
        <a href="#">Read</a></li><li>
        <a href="#">Contact</a></li><li>
        <a href="#">About Us</a></li>
        </ul>
    </div>
</div>

In addition, you can also use :after + background to get the same bottom border style.

Jsfiddle Example

#nav {
    background-color: #e26a63;
}
#wrap {
    display: table;
    height: 100px;
    margin: 0 auto;
}
#nav ul {
    padding: 0;
    margin: 0;
    display: table-cell; 
    vertical-align: bottom;
}
#nav ul li {
    display: inline-block;
}
#nav ul li a {
    display: block;
    padding: 15px;
    text-decoration: none;
    color: white;
}
#nav ul li:after {
    content: "";
    display: block;
    height: 5px;
}
#nav ul ul {
    display: none;
    position: absolute;
    background-color: #e26a63;
    margin-top: 5px;
}
#nav ul ul li {
    display: block;
    min-width: 200px;
}

/* hover */
#nav ul li:hover {
    background-color: #cb5f59;
}
#nav ul li:hover:after {
    background: #9e4a45;
}
#nav ul li:hover ul {
    display: block;
}
#nav ul ul li:after {
    height: 0;
}
<div id="nav">
	<div id="wrap">
    	<ul>
        <li><a href="#">Home</a></li><li>
        <a href="#">Study</a></li><li>
        <a href="#">Games</a>
        	<ul>
            	<li><a href="#">Riddles</a></li><li> 
                <a href="#">Flip card game</a></li><li>  
                <a href="#">Spot the mistake</a></li><li> 
                <a href="#">Multiple choice</a></li>            	
            </ul>
          </li><li>
        <a href="#">Read</a></li><li>
        <a href="#">Contact</a></li><li>
        <a href="#">About Us</a></li>
        </ul>
    </div>
</div>

1 The Shapes of CSS - https://css-tricks.com/examples/ShapesOfCSS/

Upvotes: 2

David Genger
David Genger

Reputation: 915

you can change the border to box-shadow and a box shadow does not take up place from the box model

#nav ul li:hover {
    background-color: #cb5f59;
    box-shadow: 0 -2.2px 0 #9e4a45 inset,0 0 0 #9e4a45;
} 

Upvotes: 0

vals
vals

Reputation: 64164

Your ul is absolute positioned, so it is implicitly at top: 0px,

Just set this to 5px to compensate the border size

#nav ul ul {
    top: 5px;   /* added */
}

#nav {
    background-color: #e26a63;
}
#wrap {
    padding-left: 60px;
    height: 100px;
    width: 100%;
    margin: 0 auto;
    display: table-cell; 
    vertical-align: bottom;
}
#nav ul {
    list-style-type: none;
    padding: 0;
    margin: 0;
    position: relative;
    min-width: 200px; 
}
#nav ul li {
    display: inline-block;
    border: 5px solid transparent;
}
#nav ul li:hover {
    background-color: #cb5f59;
    border-bottom: 5px solid #9e4a45;
}
#nav ul li a, visited {
    color: white;
    display: block;
    padding: 15px;
    text-decoration: none;
}
#nav ul li:hover ul {
    display: block;
}
#nav ul ul {
    display: none;
    position: absolute;
    background-color: #e26a63;
    border-top: 0;
    margin-left: -5px;
}
#nav ul ul li {
    display: block;
}
#nav ul ul li a:hover {
    color: white;
}
<div id="nav">
	<div id="wrap">
    	<ul>
        <li><a href="#">Home</a></li><li>
        <a href="#">Study</a></li><li>
        <a href="#">Games</a>
        	<ul>
            	<li><a href="#">Riddles</a></li><li> 
                <a href="#">Flip card game</a></li><li>  
                <a href="#">Spot the mistake</a></li><li> 
                <a href="#">Multiple choice</a></li>            	
            </ul>
          </li><li>
        <a href="#">Read</a></li><li>
        <a href="#">Contact</a></li><li>
        <a href="#">About Us</a></li>
        </ul>
    </div>
</div>

Upvotes: 0

Orry
Orry

Reputation: 659

Because you've integrated your dropdown inside your header it might resize the header if you'd just make it visible.

An easy solution is to add something like this:

ul li ul{
    position: absolute;
    top: 58px;
}

By making this element absolute we "break" it out of the header code.

Note: this prabably isn't the perfect code, but it might give you a direction.

Upvotes: 0

Related Questions