Dropdown navigation with same width as parent navigation - html

I already tried "width: 100%;" but the dropdown element then gets the same width as the whole page. I'm working with floats so maybe that needs a different approach?
I swear I've looked at similar questions but none of the solutions there worked for me. Can anyone see what I'm doing wrong? You can find the jsfiddle with all of the code here. I currently "solved" the problem with a fixed width.
Here is the HTML for the navi:
<nav role="navigation" class="navi">
<ul class="nav-elements">
<li>Home</li>
<li>Ongoing Stories
<ul>
<li>Sublink</li>
<li>Another Sublink with a long text</li>
</ul>
</li>
<li>Sleeping Stories
<ul>
<li>Sublink</li>
<li>Another Sublink</li>
</ul>
</li>
<li>News</li>
<li>About/FAQ</li>
</ul>
</nav>
And the CSS:
.navi {
float: left;
margin-bottom: 0.5em;
}
.navi ul {
padding-left: 0; /* Navi aligned left */
margin: 0;
}
.navi li {
background: #808080;
float: left;
padding: 0.2em 0.8em 0.2em 0.8em;
border: 1px solid black;
margin: 0 0.4em 0.4em 0;
list-style: none;
font-size: 1.2em;
border-radius: 10px;
}
/* nav-elements for dropdown-menus */
.nav-elements ul {
margin-top: 0.2em;
padding: 7px 10px 0 0;
}
.nav-elements li ul {
position: absolute;
left:-9999px; /* Hide off-screen when not needed (this is more accessible than display:none;) */
z-index: 1000;
width: 9.25em;
margin-left: -0.85em; /* to counter the padding in .navi li */
}
.nav-elements li:focus,
.nav-elements li:hover { /* main navi gets shadow while dropdown is active */
text-shadow: 0 0 7px rgba(255,255,255,.5); /* kind of a glow effect */
}
.nav-elements li:focus ul, /* show the submenu when user focues (e.g. via tab) the parent li [doesn't work?]*/
.nav-elements li:hover ul { /* show the submenu when user hovers over the parent li */
left:auto; /* Bring back on-screen when needed */
text-shadow: none; /* dropdown doesn't inherit shadow from main-navi*/
}
.nav-elements ul li {
float: none;
font-size: .9em;
}

According to your issue that you don't want to use fixed width then please check my Updted fiddle
I have used width:100% so it will change according to parent ul. What you need is to change width:100% and position:relative or parent li(.navi li) and then i removed margin-right as it was extra and you got the result.
Updated
As i have used position:relative so width:100 is taking width inside the border so you are missing 2px gap so just for workaround i have used width:101%. Please check my updated fiddle.
let me know if its what you need. Thank you :)

your second ul element can just be wide as the li element around it. try this:
#subMenuFoo {
display: none;
}
#foo:hover ~ #subMenuFoo {
display: block;
}
<div class="nav-elements">
foo
<div id="subMenuFoo">
bar
</div>
</div>
--
please mind the gap

Related

Navigation bar items moving

When I hover mouse over menu items they don't always fit perfectly within the navigation bar, I am also unable to fix that tiny gap between border and last navigation item and the gap changes when I zoom in/out the page, when I zoom in/out on google chrome and hover over menu items the hovered item gets taller than the rest of the bar. I've been trying to figure this out for quite some time now. Thank you for your help in advance.
Main objectives: getting rid of the gap next to "contact", making hovered items fit into the navbar, fixing google chrome navbar zooming issue.
Here's my codepen: http://codepen.io/anon/pen/QbBgKR
<nav class="menu">
<ul class="clearfix">
<li>HOME </li>
<li>PROFILE</li>
<li>STUFF</li>
<li>STUFF</li>
<li id="long"> PRODUCTS<span class="arrow">▼</span>
<ul class="sub-menu">
<li>STUFF1</li>
<li>STUFF2</li>
<li>STUFF3</li>
</ul>
</li>
<li>CONTACT</li>
</ul>
</nav><!-- menu -->
.clearfix:after {
display: block;
clear: both;
}
.clearfix {
margin-left: -37px;
}
nav {
font-size: 1em;
width: 700px;
background-color: #3A5199;
font-family: Verdana;
}
#current {
background-color: #6082ec;
}
.menu li {
display: inline-block;
list-style: none;
position: relative;
width: 15.2%;
text-align: center;
margin-left: -0.4%;
margin-right: -0.4%;
}
.menu li:hover {
background-color: #6082ec;
}
.menu a {
text-decoration: none;
color: white;
display: block;
padding-top: 10px;
padding-bottom: 10px;
}
#long {
width: 24%;
}
.menu .arrow {
font-size: 12px;
line-height: 0%;
}
.sub-menu {
width: 128px;
position: absolute;
z-index: -1;
opacity: 0;
transition: opacity linear 0.15s;
background-color : #6082ec;
}
.menu li:hover .sub-menu {
z-index:1;
opacity:1;
}
.sub-menu li:hover {
background-color: #3A5199;
}
.sub-menu li {
width: 131%;
display: block;
right: 39.2px;
}
.sub-menu a {
position: relative;
text-align: center;
}
Using a reset stylesheet or something like normalize.css will go a long way in fighting various margin, padding and display inconsistencies across browsers and you won't have to do negative margin "hacks" like you did for .clearfix.
Although you have calculated your percentages correctly for your li to add up to 100%, the gap to the right of Contact arises with the pixel rounding of the percentage width you've applied.
15.2% of 700px = 106.4px
The browser will likely round down to 106px. The change in the gap when zooming is also likely related to the percentage widths. At one zoom level the value gets rounded differently.
106px * 5 = 530px + 24% of 700px (168px) = 698px
Since you're using a fixed with on your <nav> element, why not use fixed widths on the li also? Or change up the percentage values a bit. 15.2% for the home link creates more padding between the text Home and the left and right edges of the li than it does for Profile.
Fixed Width Solution
/* default width for all li */
.menu li {
width: 108px;
}
/* Home */
.menu li:nth-child(1) {
width: 100px;
}
/* Products */
.menu li:nth-child(5) {
width: 168px;
}
As far as zooming in Chrome and getting a height change when hovering, I cannot replicate that issue.
Negative margin for UL is working.
.clearfix {
margin-left: -37px;
margin-right:-0.4%;
}
It's strange math her - imho.

How do I prevent all menu items from adding style on:hover?

Recently I have noticed that when you are styling menu item on:hover, some properties like text-shadow, color, background and and many others are applied to the menu item that is currently be hovered over.
However, it seems that the padding property is applied to all the menu items, not just the menu item being hovered over.
Here's an example: http://codepen.io/Bizzet/pen/LEvopq
.main-navigation a {
display: block;
text-decoration: none;
color: #fff;
font-size: 1.1em;
transition: 1s;
margin-bottom: -7px;
}
.main-navigation a:hover {
margin-bottom: 0;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
}
As you can see in Codepen, the text-shadow is applied to a single menu item while the padding is applied to all the elements.
What can I do to prevent this?
I only want one menu item to hover at once.
The padding is not being applied to all menu items. What's happening is that the height of the parent container is being expanded by the hover effect, and since the other menu items are top-aligned, they raise as well.
Try this:
.main-navigation a:hover {
...
margin-bottom: 0;
margin-top: -7px;
}
Demo
Problem
Your ul li a's have a negative margin-bottom initially.
When you hover over an a, though, you reset the margin-bottom to 0. This causes the box to grow in size and push the whole nav-bar upwards.
Insight
The padding is not being applied to all list items. One of the links in your nav boxes is pushing the whole navigation bar up, which gives the appearance of applying the padding to all list items.
Demo
Run this snippet for a demo. The menu-items are black.
header {
min-height: 10em;
background: rgba(0, 0, 0, 0.25);
position: relative;
}
h1 {
text-align: center;
}
.container {
background: green;
list-style: none;
position: absolute;
padding: 0;
margin: 0;
bottom: 0;
}
.container:after {
display: block;
content: '';
clear: both;
}
li {
float: left;
margin-right: 0.5em;
display: inline-block;
background: black;
position: relative;
}
span {
color: red;
margin-bottom: -0.75em;
display: block;
transition: all 3s;
}
span:hover {
margin-bottom: 0;
}
<header>
<h1>Title</h1>
<ul class="container">
<li class="item">
<span>Hello</span>
</li>
<li class="item">
<span>there</span>
</li>
<li class="item">
<span>friend</span>
</li>
</ul>
</header>
Solution
It should be noted that negative margins are usually not encouraged, unless you want element overlap. If it is necessary, it can be better to set a negative margin on 1 parent element than each individual child.
To hack this particular problem together, just replace this:
a:hover { margin: 0; }
with this:
a:hover { transform: translateY(-70%); }
Keep in mind that you might have to add -browser- prefixes to the transform rule. Browser support here

Lining Up Submenu With Menu

I'm still relatively new to coding, so this is probably an easy fix.
I have set up menu with 5 menu items, and submenu items under two of the primary menu items. If I line up the first submenu with its menu item, the second one is too far right. If I line up the second submenu with its menu item, the first one is too far right. Is there a way to make both submenus line up under their respective menu items?
Here is the HTML:
<ul id="menu">
<li>Home</li>
<li>About Me
<ul>
<li>Fairfax Psychological Associates</li>
<li>Credentials</li>
</ul></li>
<li>Publications
<ul>
<li>The Wisdom of the Five Messengers</li>
<li>Other Publications</li>
</ul></li>
<li>Location</li>
<li>Strategic Interactions</li>
And this is the CSS:
#menu {
width: 950px;
height:35px;
font-size: 20px;
font-family: cambria, Georgia, sans-serif;
font-weight: bold;
text-align: center;
background-color: #FFF;
border-radius: 0px;
margin-top: -175px;
margin-left: 25px;
}
#menu li {
display: inline;
padding: 10px;
}
#menu a {
text-decoration: none;
color: #2B297F;
padding: 10px 10px 10px 10px;
}
#menu a:hover {
color: #2B297F;
background-color: #999;
}
#menu li ul
{font-size:15px;
margin-left:-160px;
margin-top:25px;
position:absolute;
text-align:left;
display:none;}
#menu li:hover ul
{display:inline-block;
}
#menu li li
{list-style:none; display:list-item;}
#menu li li a
{color:#2B297F; text-decoration:none;white-space:nowrap;
}
#menu li li a:hover
{color:#2B297F; background-color: #999 text-decoration:none;}
The site is at http://kerryaltmantest.info if you want to see what I mean about the submenu. Thank you!
There are a few changes in css that need to be made:
#menu li ul {
font-size: 15px;
/* margin-left: -160px; REMOVE */
/* margin-top: 25px; REMOVE */
position: absolute;
text-align: left;
top: 30px; /* add this */
left: 0; /* add this */
padding: 0 /* add this */
display: none;
}
#menu li {
display: inline;
padding: 10px;
position: relative; /* add this */
}
The biggest reason that the ul is not positioning properly is because the li it is contained in did not have a position style set. When this happens, absolutely-positioned elements are positioned according to the first ancestor that has a position type set. Additionally, that was apparently not coming into effect because no positioning rules (top/left/bottom/right) were set in the ul. Adding these two things and resetting the margins/padding fixed the issue (css is directly editable/debuggable in chrome's debugger).
https://developer.mozilla.org/en-US/docs/Web/CSS/position:
Absolute positioning
Elements that are positioned relatively are still considered to be in
the normal flow of elements in the document. In contrast, an element
that is positioned absolutely is taken out of the flow and thus takes
up no space when placing other elements. The absolutely positioned
element is positioned relative to nearest positioned ancestor. If a
positioned ancestor doesn't exist, the initial container is used.
Chrome debugging information: https://developer.chrome.com/devtools/index

Why doesn't this button expand to width of its content in Firefox like it does in other browsers?

This question seems crazy long, but I wanted to clearly explain everything.
Desired Result
I have a horizontal menubar with submenus. I created it from scratch, so I am not using any existing framework. It uses a combination of buttons, anchors, and spans for semantic markup.
anchors for items that go to a new page
buttons for items that don't go anywhere but have submenus
spans for disabled items
Note: This site is for a limited number of specific users so I am not concerned about the lack of accessibility.
Submenus should be as wide as the widest menu item that it contains. And each menu item should fill the width of the submenu so that the cursor and focus outlines display as desired.
The Problem
In Firefox, a submenu does not expand to the width of the widest item in the following scenario:
submenu is absolutely positioned
submenu is contained within a block that has position other than static
longest menuitem is a button
I've tested with Chrome, IE 8, Firefox 12, and Firefox 20. It displays as desired in Chrome and IE, but not in either version of Firefox.
I created a scaled down version with JavaScript, images, disabled items, and many of the menu items removed. Code is below and also on jsFiddle. Here's a screenshot in Firefox 20.
Note how the Section Titles item is squished. The submenu is only as wide as the Page Titles item (with padding). Also note how this is not a problem in the top level submenu - that menu expanded to the width of Customize PDF Titles.
The Section Titles item is a button. If I change it to an anchor, the submenu expands as desired. If I change the button CSS to remove width: 100%, then the submenu expands as desired. But then, menu items that are narrower than the submenu no longer fill the width (even if I add display: block).
Here's a screenshot of how the above fix breaks other parts of the menu.
Note how the cursor is not a pointer when hovering outside the text. Yes, I could fix that by changing the cursor for the li, but the other problem is the focus outline. I want the focus outline to be around the whole menu item not just the text (which is how it works with width: 100%).
I also tried playing around with -moz-box-sizing, but still no joy.
As a simple workaround, for this particular case, I've just added a few to Page Titles to make it longer. But that solution won't work when the menu is created dynamically.
HTML Code (jsFiddle)
<ul id="navAdminMenu">
<li>Companies</li
><li class="hasSubmenu"><button type="button">Books</button>
<ul>
<li>Manage Books</li
><li>PDF Profiles</li
><li class="hasSubmenu"><button type="button">Customize PDF Titles</button>
<ul>
<li>Page Titles</li
><li class="hasSubmenu"><button type="button">Section Titles</button>
<ul>
<li>Profile Section</li
><li>Index Section</li>
</ul>
</li>
</ul>
</li>
</ul>
</li
><li class="hasSubmenu"><button type="button">Lists</button>
<ul>
<li class="hasSubmenu"><button type="button">Categories</button>
<ul>
<li>Manage</li
><li>Reports</li>
</ul>
</li
><li>Key Contact Positions</li>
</ul>
</li>
</ul>
CSS Code
#navAdminMenu {
font-family: Arial, Helvetica, sans-serif;
font-size: 1em;
list-style: none;
margin: 0;
padding: 0;
background-color: #efefef;
}
#navAdminMenu button {
margin: 0;
padding: 0;
vertical-align: baseline;
border: none;
background-color: transparent;
cursor: pointer;
font-family: Arial, Helvetica, sans-serif;
font-size: 1em;
}
#navAdminMenu button::-moz-focus-inner {
padding: 0;
border: none;
}
#navAdminMenu a {
text-decoration: none;
}
#navAdminMenu li {
display: inline-block;
margin: 0;
border-right: 1px solid #ccc;
}
#navAdminMenu li:hover {
background-color: #4b545f;
}
#navAdminMenu > li > button, #navAdminMenu > li > a {
display: inline-block;
height: 2.3em;
line-height: 2.6;
padding: 0 10px;
}
#navAdminMenu > li > button, #navAdminMenu > li > a {
color: #06c;
}
#navAdminMenu > li > button:focus, #navAdminMenu > li > a:focus {
outline: 0; /* Firefox displays outline outside the menu box-shadow */
box-shadow: 0 0 0 3px #06c;
}
#navAdminMenu > li:hover > button, #navAdminMenu > li:hover > a {
color: #fff;
}
#navAdminMenu > li.hasSubmenu > button:after {
content: "v";
display: inline-block;
width: 13px;
margin-left: 5px;
}
#navAdminMenu ul {
display: none;
position: absolute;
padding: 0;
background-color: #5f6975;
}
#navAdminMenu li:hover > ul {
display: block;
}
#navAdminMenu ul > li {
display: block;
position: relative;
border-top: 1px solid #999;
border-bottom: 1px solid #000;
}
#navAdminMenu ul > li > button, #navAdminMenu ul > li > a {
height: 2em;
line-height: 2;
padding: 0 30px 0 10px;
white-space: nowrap;
}
#navAdminMenu ul > li > button {
width: 100%; /* full width of submenu */
text-align: left;
}
#navAdminMenu ul > li > a {
display: block; /* full width of submenu */
}
#navAdminMenu ul > li > button, #navAdminMenu ul > li > a {
color: #fff;
}
#navAdminMenu ul > li > button:focus, #navAdminMenu ul > li > a:focus {
outline: #fdcb01 solid 3px;
}
#navAdminMenu ul > li.hasSubmenu > button:after {
content: ">";
width: 16px;
position: absolute;
right: 0;
}
#navAdminMenu ul ul {
left: 100%;
top: 0;
}
Question
Is there something simple I am missing? Or should I report this as a bug to Mozilla?
Note: I don't want to change the buttons to anchors.
I spent way too much time on this tiny glitch, but I am like a dog with a bone.
After all the trial and error and the time spent drafting the question, I found a very simple solution. I thought of just discarding my question, but maybe it can help someone else.
Very, very simple solution. So simple I could almost cry.
#navAdminMenu ul > li > button {
/* full width of submenu (even when its the longest item) */
min-width: 100%;
}
Note the use of min-width.

Vertical CSS Multi-Level Menu That Positions Itself at the Top of the div, not at the 1st Menu Option's Position

Most CSS vertical menus have their second level and third layer menus popping out right beside the 1st level menu. This creates a space if you go to the third option in the first level menu. The second level menu from that third option is positioned only as high as the third menu first level item. Thus, there's a space above the second level menu, all the way up to the first level menu first selection.
How would I go about making it so that the second level menu that pops out would be at the highest first level menu selection?
I made a graphic to further iterate this.
http://i.imgur.com/v1UIk.png
http://i.imgur.com/weEwn.png
In the first image, when you hover over Purchase, the menu pops out to the side. Instead, I want the menu to pop out above, at the Products area. I want it so that even if I go to Products, Purchase, Support, Downloads...etc, that second level menu ALWAYS pops out at the top of the menu/Products.
In my actual menu, each level will only have four options, so there will be no issues hovering over and keeping the menu active.
Does anyone have a link or an idea on how to get this done?
Thanks - and I hope I explained it well..lol.
EDIT:
*I took this off of a website, I realize there's a ton of syntax errors like missing quotes and such. I'm just trying to get it to work before I fix anything and refine it.
CSS
#menu ul {
margin: 0;
padding: 0;
list-style: none;
width: 150px; /* Width of Menu Items */
border-bottom: 1px solid #ccc;
}
#menu ul li {
position: relative;
}
#menu li ul {
position: absolute;
left: 149px; /*Set 1px less than menu width */
top: 0;
display: block;
}
#menu li:hover ul {
display: block;
}
#menu li:hover>ul {
visibility:visible;
}
#menu ul ul {
visibility:hidden;
}
/* Fix IE. Hide from IE Mac \*/
* html #menu ul li { float: left; height: 1%; }
* html #menu ul li a { height: 1%; }
/* End */
/* Make-up syles */
#menu ul, li {
margin: 0 0 0 0;
}
/* Styles for Menu Items */
#menu ul a {
display: block;
text-decoration: none;
color: #777;
background: #fff; /* IE6 Bug */
padding: 5px;
border: 1px solid #ccc;
border-bottom: 0;
}
/* Hover Styles */
#menu ul a:hover {
color: #E2144A;
background: #f9f9f9;
}
/* Sub Menu Styles */
#menu li ul a {
text-decoration: none;
color: #77F;
background: #fff; /* IE6 Bug */
padding: 5px;
border: 1px solid #ccc;
border-bottom: 0;
}
/* Sub Menu Hover Styles */
#menu li ul a:hover {
color: #E2144A;
background: #f9f9f9;
}
/* Icon Styles */
#menu ul a.submenu {background:#fff url("r_arrow.gif") no-repeat right; }
#menu ul a.submenu:hover {background:#f9f9f9 url("r_arrow.gif") no-repeat right;}
html:
<div id=menu>
<ul id=menuList>
<li>Products
<ul>
<li>All</li>
<li>CodeCharge</li>
<li>CodeCharge Studio</li>
<li>DemoCharge Studio</li>
<li>Comparison<ul>
<li>CodeCharge Studio</li>
<li>DemoCharge Studio</li>
</ul></li>
</ul>
</li>
<li>Downloads
<ul>
<li>CodeCharge</li>
<li>CodeCharge Studio</li>
<li>DemoCharge Studio</li>
</ul>
</li>
<li>Support
<ul>
<li>Support</li>
<li>Forums</li>
<li>KB</li>
</ul>
</li>
<li>Purchase
<ul>
<li>Store</li>
<li>Resellers</li>
<li>Affiliate</li>
</ul>
</li>
<li>Company
<ul>
<li>About Us</li>
<li>Contact Us</li>
<li>Press Releases</li>
</ul>
</li>
</ul>
</div>
IE Fix:
<script type="text/javascript">
startList = function() {
// code for IE
if(!document.body.currentStyle) return;
var subs = document.getElementsByName('submenu');
for(var i=0; i<subs.length; i++) {
var li = subs[i].parentNode;
if(li && li.lastChild.style) {
li.onmouseover = function() {
this.lastChild.style.visibility = 'visible';
}
li.onmouseout = function() {
this.lastChild.style.visibility = 'hidden';
}
}
}
}
window.onload=startList;
</script>
In your CSS, change #menu ul to position: relative:
#menu ul
{
margin: 0;
padding: 0;
position: relative;
list-style: none;
width: 150px; /* Width of Menu Items */
border-bottom: 1px solid #ccc;
}
And remove the relative positioning from #menu ul li:
#menu ul li
{
/*position: relative;*/
}
This makes it a little difficult to get over to the subitems, though.
Here's a demo: http://jsfiddle.net/KvaTC/
If you give each ul that is a submenu an id, then you can specify in CSS for that ID a negative top value of whatever is necessary for each one. I would recommend setting a height value for the li tags concerned for two reasons, it will tell every browser to render them at the same height and you can calculate the negatives required - no javascript required to do this.
So, take out the top:0 in the following code block so it is like this:
#menu li ul {
position: absolute;
left: 149px; /*Set 1px less than menu width */
display: block;
}
Then set a height for each li concerned:
#menu ul li {
position: relative;
height:30px;
}
Then for each submenu ul give an id (I show the first one as an example):
<ul id=menuList>
<li>Products
<ul id="submenu1">
<li>All</li>
<li>CodeCharge</li>
<li>CodeCharge Studio</li>
<li>DemoCharge Studio</li>
<li>Comparison<ul>
<li>CodeCharge Studio</li>
<li>DemoCharge Studio</li>
</ul></li>
</ul>
</li>
Then the CSS:
#submenu1 {
top:0px;
}
Each subsequent id would then need negative values for whatever is required for them to be at the top. so for the second, now they have a definite height of 30px would be:
#submenu2 {
top:-30px;
}
JSFiddle: http://jsfiddle.net/Psyrus/C3xqX/