I'm trying to create a horizontal menu with dropdown content boxes. I'm using the same method I'd use for a vertical menu with children that expand on :hover of their parent. It works fine, except that I can't seem to find a method that forces the dropdown content to stick around once the cursor moves from the parent element itself. You can see what I mean at http://asubtleweb.com/clients/kingswood/ ... The dropdown content isn't clickable because it contracts as soon as the mouse moves from its parent element.
Here's my CSS:
#header_menu nav { display: table; width: 30%; float: left; text-align: center; }
#header_menu nav ul, nav#mainmenu ul { list-style-type: none; }
#header_menu nav li { display: inline; margin-right: 2.5%; }
#header_menu nav a, nav#mainmenu a { font: 400 1.25em 'Oswald', sans-serif; color: black; text-transform: uppercase; }
#header_menu li .navhover { display: block; width: 100%; position: absolute; top: 50px; left: 0px; background-color: black; background-color: rgba(0,0,0,0.6); color: white; text-align: left; max-height: 0px; overflow: hidden; transition: all 1s linear; -wekbkit-transition: all 1s linear; }
#header_menu li:hover .navhover { max-height: 300px; min-height: 300px; }
#header_menu li .navhover article { margin: 20px; }
#header_menu li .navhover.news article { width: 30%; margin: 2.5% 0% 2.5% 2.5%; float: left; }
...and my HTML:
<div id="header_menu">
<nav>
<ul>
<li id="mission">
Mission
<div class="navhover">
[[CONTENT]]
</div>
</li>
<li id="news">
News
<div class="navhover news">
[[CONTENT]]
</div>
</li>
<li id="reserve">Reserve</li>
</ul>
</nav>
</div>
I've also tried making each parent element its own absolutely positioned block that expands on :hover, with no luck. I didn't expect to have so much trouble with the concept, but it's stumping me.
Simply add z-index: 1; to #header_menu li .navhover
As Francesco Frapporti pointed out:
Simply add z-index: 1; to #header_menu li .navhover
Edit: There is an error on your website moveWindow is not defined see body element
Simply add this to your css....
#header_menu li .navhover:hover{min-height:0;max-height:0;}
then it should work just fine!
The problem is that the parent element you are using with :hover doesn't actually "touch" the child element. So there is space between the parent and child element and that causes the parent element to lose focus when moving the mouse toward the child.
Choose whichever method you like to eliminate the gap between parent and child. Make the parent larger, move the child closer to the parent, etc.
Related
I made a simple HTML page with a simple drop-down menu (made with CSS). I have a problem with the drop-down text transparency: it shows the bottom text (as explained in the image below). The text in the menu is a link, so it's included in a tag. I tried to change the text color and opacity property but doesn't solve the problem. Any idea?
.menu {
margin-right: 0px;
margin-left: -40px;
}
li {
display: block;
float: left;
width: 25%;
height: 50px;
line-height: 50px;
font-family: Helvetica, sans-serif;
font-size: 20px;
text-align: center;
color: white;
background-color: #000000;
}
.pat:hover {
color: #EC008C;
}
.l {
width: 100%;
height: 50px;
margin-left: -20px;
}
.sub-menu {
visibility: hidden;
}
.menu .pat:hover .sub-menu {
visibility: visible;
}
<ul class="menu">
<li>Home</li>
<li class="pat">Patenti
<ul class="sub-menu">
<li class="l">Patente A</li>
<li class="l">Patente B</li>
<li class="l">Patenti superiori</li>
</ul>
</li>
<li>News</li>
<li>Contatti</li>
</ul>
Instead of visibility: hidden; and visibility: visible; on hover for submenus, it's better to use display: none and display: block, and use position: absolute on the submenu and position: relative on its parent menu entry.
The reason display: none doesn't take any space (and position: absolute will prevent the visible submenu to change the design of the main menu entries), whereas visibility: hidden; reserves the space for the hidden element and just makes it invisible, which makes it impossible to properly position it independently of objects which it should cover when visible.
Just add position: relative to .menu. It will create a stacking context causing it to appear above body text.
Here is a modified pen. I have rewritten all rules but only the last one is important.
ul {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333333;
position: relative;
li {
height: auto;
width: 20%;
position: absolute;
top: 50%;
transform: translateY(-50%);
a {
display: block;
color: white;
text-align: center;
padding: 16px;
text-decoration: none;
}
}
.float-left {
float: left;
font: 2em bold sans-serif;
}
}
Here is my html for context. I added another div just to test out vertical centering on a different element and it works fine. But I couldn't keep the li's on the nav from disappearing whenever I give them absolute positioning. Sorry it's in sass.
<ul>
<li class="float-left">Michael Thomas</li>
<li>About</li>
<li>Résumé</li>
<li>Portfolio</li>
<li>Contact</li>
</ul>
When the "li"s are inline/relative, they force the parent "ul" to take the dimensions of the child elements. But when you change the "li"s to position absolute, the "li"s no longer force the parent "ul" to take encompass the shape of its content, so the parent "ul" has a height and width of zero. If you removed the "overflow:hidden" on the parent I think you'd still see its contents. I think you need to give your nav/ul a height and width.
I have following CSS code:
nav li {
display: inline-block;
text-align: center;
}
nav li a {
display: block;
width: 100%;
height: 100%;
}
nav li :hover {
background-color: var(--main-color);
color: white;
}
Which makes elements in my navbar look like this:
But there's actually 4 items, not 6. I'll add some padding in <li>:
But when I hover over the first item, I have this ugly white space from both sides of it. Margin does exactly the same thing. Let's remove margin/padding and set <li> width manually to 120px:
First two items are now formatted somehow acceptably, but items a and b take visually far too much space than necessary. What I aim for would be something like this (made in image editor):
In other words, I'd like my <li> elements to have their width adjusted to their content with extra padding, while child <a> elements still take up 100% of <li> space. Any ideas?
Edit
I've updated updated the JSFiddle that you've posted.
You need to change your a element to not have display:block (should be inline instead). Also, you don't need to specify width and height of 100%. Just make your padding: 15px for the a, and you'll have equal, well-spaced hover padding.
I adapted your code above and put it into a codepen, see here:
http://codepen.io/himmel/pen/BNJZoL
Here is how I changed your CSS:
nav li {
display: inline-block;
text-align: center;
}
nav li a {
padding-left: 15px; ** add padding to both sides
padding-right: 15px;
display: inline;
}
nav li :hover {
background-color: brown;
color: white;
}
Try using table layout
body {margin:0}
nav ul {
padding:0;
margin:0;
width: 100%;
display: table;
}
nav li {
display: table-cell;
text-align: center;
}
nav li a {
background: #fafafa;
display: block;
width: 100%;
box-sizing: border-box;
padding: 10px;/*or whatever*/
}
nav li :hover {
background-color: brown;
color: white;
}
<nav>
<ul>
<li>Item</li>
<li>Very long item</li>
<li>a</li>
<li>b</li>
</ul>
</nav>
I have a horizontal menu that is made up of a series of ul's and li's. The submenus look great so I don't need to do anything with those. The primary ul looks great until you hover over the far right li.
When doing that, it looks good in Safari but the hover comes about 2 pixels short of the background on the ul in Firefox and IE and even more in Chrome. I have tried adjusting the padding to make it look good in Firefox and IE but then you still have the same issue in Chrome and in Safari, that far right li breaks down to a new line. Of course, adjusting it to look good in Chrome makes all the other browsers break to a new line. This site is using Wordpress which creates the menu dynamically so I can only change the CSS. Here is the basic idea for the code:
<html>
<head>
<style type="text/css">
#header {
margin: 0 auto;
width: 980px;
}
ul li {
font-size: 13px;
line-height: 21px;
}
#header .main-nav #menu-main-navigation {
background: #169BAC;
width: 100%
}
#header .main-nav > div ul {
width: 100%;
list-style: none;
float: left;
margin: 0;
padding: 0;
vertical-align: baseline;
}
#header .main-nav > div ul li ul{
top: 43px;
}
#header .main-nav .menu-div>ul>li {
padding: 5px 14px;
float: left;
border-right: solid 1px #54AEC2;
}
#header .main-nav .menu-div ul li:hover {
background: #2A588D;
}
#header .main-nav .menu-div>ul>li:first-child {
padding-top: 9px;
height: 28px;
}
#header .main-nav .menu-div>ul>li:last-child {
padding: 5px 26px;
border-right: none;
}
#header .main-nav .menu-div>ul>li a{
line-height: 15px;
text-decoration: none;
color: #FFF;
padding: 0px 13px;
text-align: center;
display: inline-block;
}
</style>
<head>
<body>
<header id="header">
<nav class="main-nav">
<div class="menu-div">
<ul id="menu-main-navigation" class="menu">
<li id="menu-item-275">Home</li>
<li id="menu-item-310">For New<br />Patients</li>
<li id="menu-item-376">Cleanings &<br />Prevention</li>
<li id="menu-item-381">General<br />Dentistry</li>
<li id="menu-item-453">Restore Your<br />Smile</li>
<li id="menu-item-462">Dental Anxiety &<br />Sedation Options</li>
<li id="menu-item-463">Dentistry For<br />Kids</li>
<li id="menu-item-464">Insurance &<br />Payment Options</li>
</ul>
</div>
</nav>
</header>
</body>
You can see the site at http://riverbend.caswellwebcreations.com.
Thank you for any help that you can give me on this.
The width of the li elements is being defined by their padding and the font-size (and padding) of the a elements inside them. The font propertys are not uniform between browsers, some browsers put text bigger or smaller than others. That seems to be the problem.
If you want to stretch the li elements "cross-browser" you should define the width of the li elements via css like this:
#menu-item-275{
width: 64px;
}
#menu-item-310{
width: 77px;
}
#menu-item-376{
width: 96px;
}
#menu-item-381{
width: 82px;
}
#menu-item-453{
width: 104px;
}
#menu-item-462{
width: 131px;
}
#menu-item-463{
width: 105px;
}
#menu-item-464{
width: 132px;
}
If you sum the width of each li item (plus padding and border) you get the width of the menu container: 980px. And the browsers will take that width to render the li's.
I hope this works!
UPDATE
Just found another (and more easy) solution!: https://stackoverflow.com/a/14361778/3762078
#header .main-nav .menu-div>ul>li:last-child {
padding: 5px 20px;
border-right: none;
float: none; /* ADD THIS */
overflow: hidden; /* AND THIS */
}
'float: none'. Forces last li element to be as wide as it can (the
default block element's behavior).
'overflow: hidden'. Prevents the last li element to stretch to ul's full width.
Although this doesn't prevent the width changes to all li elements on every browser, hence making the last li's width be thinner or wider (and sometimes expanding that li's height), is a nice solution.
Here's some HTML I have
<nav class="navlist">
<span class="left">
<li><a class="active" href="#">Home</a></li>
<li>Work</li>
<li>Services</li>
</span>
<span class="right">
<li>About</li>
<li>Blog</li>
<li>Contact</li>
</span>
</nav>
Relevant CSS:
.navlist {
position: fixed;
top: 0;
width: 100%;
list-style: none;
background-color: rgba(255,255,255,0.4);
}
.navlist span {
position: absolute;
margin: 10px 0;
}
.navlist .left {
right: 0px;
margin-right: 50%;
padding-right: 75px;
}
.navlist .left li {
margin-left: 75px;
}
.navlist .right {
left: 0px;
margin-left: 50%;
padding-left: 75px;
}
.navlist .right li {
margin-right: 75px;
}
.navlist li{
display: inline;
}
.navlist li a {
font-family: "Futura Thin", sans-serif;
font-size: 1.2em;
color: black;
text-decoration: none;
}
Why is the height of the <nav> element 0 instead of wrapping the height around the child elements? I've tried absolutely everything, adding overflow: auto; etc. and nothing works without simply defining the height manually, which is definitely not what I want. Any help?
<span> should be <ul> or <li> should be <span> or any inline-elements to make a valid code. best is to use <ul><li><a> for a list of links.
position:absolute;(or fixed) takes element out of the natural flow of the page, so <nav> have no content to make it grow.
this is caused by your
position:absolute
rule on the span elements.
Absolutely positioned elements don't fill the parent container, causing it to have a height of 0px.
Try making the same layout without using absolute positioning, and you should be fine.
Also, the <li> elements should be in a <ul> parent, not a <span>
You have taken <li> without <ul> or <ol> it is not a best practice.
absolute: The element is positioned relative to its first positioned (not static) ancestor element, So its container doesnt have specific value.
<ul>
<li><a class="active" href="#">Home</a></li>
<li>Work</li>
<li>Services</li>
</ul>
Need to wrap as above and need to give style to remove its default bullets.
Your child elements are positioned as absolute, thus also taking them out of the flow. Because of this, the .navlist element doesn't know how to expand.
Use floats to position your navigation lists and then user the overflow:hidden fix on the .navlist to have it expand to fit the child elements.
As others have said, positioning a child element as absolute will pull it out of the layout, its parent will then always have a height of 0 as it technically has no layout inside of it.
It completely depends on what your end result should look like so its hard to advise but a little reduced case of what you may want ( with a red background colour to make it obvious height is set on the nav is here:
http://jsbin.com/osobor/1/
.navlist {
position: fixed;
top: 0;
width: 100%;
list-style: none;
background: red;
}
.navlist ul {
float: left;
width:50%;
padding:0;
margin: 0;
list-style: none;
}
.navlist .right {
float:right;
}
.navlist li a {
font-family: "Futura Thin", sans-serif;
font-size: 1.2em;
color: black;
text-decoration: none;
}
Edit: Also your spans should be UL ( or OL ) elements if you're nesting LI's within them ( I've added this to the jsbin example )