CSS Floats and Nested Lists - css

In CSS, I am floating sets of nested lists in order to create dropdown menus. However, the headers are not nearly as wide as many of the items in their dropdown menus, so the headers end up getting spaced disproportionately (because each of their dropdown components have different widths---apparently a list is as wide as its widest component). Does anyone have any suggestions for how to fix this?
Here is my code:
<body>
<ul id="navigation">
<li>Header A</li>
<li class="sub">
Header B
<ul>
<li>Item AAAAAAAAAAAA</li>
<li>Item BBBBBBBBBBBB</li>
<li>Item CCCCCCCCCCCC</li>
<li>Item DDDDDDDDDDDD</li>
<li>Item EEEEEEEEEEEE</li>
</ul>
</li>
<li>
Header C
</li>
</ul>
</body>
And here is the CSS:
body {
padding: 0;
margin: 0;
}
#navigation {
margin: 0;
padding: 0 1em;
background: #000;
height: 3em;
list-style: none;
font-family: "Helvetica Neue";
}
#navigation > li {
float: left;
height: 100%;
margin-right: 0.5em;
padding: 0 1em;
}
#navigation > li > a {
color: #7A7A7A;
text-decoration: none;
line-height: 3;
font-weight: bold;
}
#navigation > li > a:hover {
color: #FFFFFF;
}
#navigation > li.sub ul {
margin: 0;
padding: 0.5em 0;
list-style: none;
background: rgba(12,13,69,1);
position: relative;
top: 10000px;
}
#navigation > li.sub ul li a {
height: 100%;
display: block;
padding: 0.4em;
color: #fff;
font-weight: bold;
text-decoration: none;
}
#navigation > li.sub ul li a:hover {
background: #00F2FF;
text-decoration: none;
}
#navigation > li.sub:hover ul {
display: block;
top: 0px;
}

Without seeing your code, it's impossible to say what's happening in your specific case.
But here is a working example: http://jsfiddle.net/kboucher/nrAPu/
HTML
<nav>
<ul>
<li>
Menu One
<ul>
<li>
Menu One Item One
<ul>
<li>Menu One Item One Submenu Item One</li>
<li>Menu One Item One Submenu Item Two</li>
<li>Menu One Item One Submenu Item Three</li>
<li>Menu One Item One Submenu Item Four</li>
</ul>
</li>
<li>Menu One Item Two</li>
<li>Menu One Item Three</li>
<li>Menu One Item Four</li>
</ul>
</li>
<li>
Menu Two
<ul>
<li>Menu Two Item One</li>
<li>Menu Two Item Two</li>
<li>Menu Two Item Three</li>
<li>Menu Two Item Four</li>
</ul>
</li>
</ul>
</nav>
CSS
body { font-family: Helvetica, Arial, Sans-serif; line-height: 1.5em; }
a:hover { color: #cc0000; }
/* Hide submenu */
nav ul > li > ul,
nav ul > li > ul > li > ul { display:none; }
/* Layout menubar and menus */
nav { background:#ddd; padding:0.25em 0.5em; }
nav > ul > li { cursor: pointer; display:inline-block; padding:0 1em; }
nav > ul > li > ul { background: #ddd; padding:0.5em; position: absolute; z-index: 1000; }
nav > ul > li > ul > li > ul { background: #ccc; padding:0.5em; position: absolute; left: 90%; top: 0; z-index: 1001; }
/* show submenu on hover */
nav ul > li:hover > ul,
nav ul > li > ul > li:hover > ul { display:block; width:10em; }

Related

Removing link from :before items in menu

So I have the following code:
<style>
.menu {
padding: 30px 50px;
padding-bottom: 0px;
}
.menu ul {
list-style-type: none;
}
.menu ul a {
display: inline-block;
text-transform: uppercase;
font-size: 20px;
}
.menu ul a li {
display: inline-block;
text-transform: uppercase;
font-size: 20px;
}
.menu ul a:not(:first-child):before {
padding-right: 15px;
padding-left: 15px;
content: '\2605';
}
</style>
<div class="menu">
<ul>
<li>LINK 1</li>
<li>LINK 2</li>
<li>LINK 3</li>
</ul>
</div>
Or if you prefer:
https://jsfiddle.net/f64z4tp8/1/
As you can see I have three links, and in between are an icon (star). However, I would like it so that the stars (before items) are not links. Can this be done ?
Your markup is incorrect: you cannot nest other elements except for <li> directly within <ul> (or <ol> too, for the sake of completeness). If you update your markup to reflect that changes, i.e.:
<ul>
<li>...</li>
</ul>
and slightly modify your selectors by changing this:
.menu ul a:not(:first-child):before
...to this:
.menu ul li:not(:first-child):before
and you are good to go:
.menu {
padding: 30px 50px;
padding-bottom: 0px;
}
.menu ul {
list-style-type: none;
}
.menu ul li {
display: inline-block;
}
.menu ul a {
text-transform: uppercase;
font-size: 20px;
}
.menu ul li:not(:first-child):before {
padding-right: 15px;
padding-left: 15px;
content: '\2605';
}
<div class="menu">
<ul>
<li>LINK 1</li>
<li>LINK 2</li>
<li>LINK 3</li>
</ul>
</div>
I've added display:inline-block; to the .menu ul a:not(:first-child):before css class. At this point the text-underline goes away and the stars become red.
This is because the CSS specs say:
When specified on or propagated to an inline element, it affects all the boxes generated by that element, and is further propagated to any in-flow block-level boxes that split the inline (see section 9.2.1.1). […] For all other elements it is propagated to any in-flow children. Note that text decorations are not propagated to floating and absolutely positioned descendants, nor to the contents of atomic inline-level descendants such as inline blocks and inline tables.
.menu {
padding: 30px 50px;
padding-bottom: 0px;
}
.menu ul {
list-style-type: none;
}
.menu ul li a {
display: inline-block;
text-transform: uppercase;
font-size: 20px;
}
.menu ul li a {
display: inline-block;
text-transform: uppercase;
font-size: 20px;
}
.menu ul li:not(:first-child):before {
padding-right: 15px;
padding-left: 15px;
content: '\2605';
}
<div class="menu">
<ul>
<li>LINK 1</li>
<li>LINK 2</li>
<li>LINK 3</li>
</ul>
</div>
Put as CSS selector:
.menu ul a:not(:first-child):before {
padding-right: 15px;
padding-left: 15px;
content: '\2605';
text-decoration: none;
pointer-events: none;
}
pointer-events: none; remove any pointer interaction with the ::before element.
text-decoration: none; remove any default UI effect like underline.
In order to achieve this you'll need to add the stars outside of the list links. You should also follow the HTML specs as much as possible, where <a> are not valid <ul> child elements.
So the quickest solution would be something like this:
https://jsfiddle.net/f64z4tp8/8/
HTML:
You can fix the HTML structure and use it according to the official specs by making the <a> elements children of the <li> items, like so:
<div class="menu">
<ul>
<li>LINK 1</li>
<li>LINK 2</li>
<li>LINK 3</li>
</ul>
</div>
CSS:
Since you changed the HTML structure, you'll also need to update the CSS selectors ensure you're still styling the stars and list items correctly, so change the rules that target .menu a li to just .menu li or just .menu a.
For example, on the selector where the star is added, change from .menu ul a to .menu ul li, ending up with something like this:
.menu ul li:not(:first-child):before {
padding-right: 15px;
padding-left: 15px;
content: '\2605';
color: $primaryRed;
}
EXAMPLE SOLUTION:
.menu {
grid-area: menu;
justify-self: right;
align-items: center;
padding: 30px 50px;
padding-bottom: 0px;
}
.menu ul {
list-style-type: none;
font-family: 'LemonReg', sans-serif;
}
.menu ul a {
display: inline-block;
color: $yellowish;
text-transform: uppercase;
font-size: 20px;
}
.menu ul li {
display: inline-block;
color: $yellowish;
text-transform: uppercase;
font-size: 20px;
}
.menu ul li:not(:first-child):before {
padding-right: 15px;
padding-left: 15px;
content: '\2605';
color: $primaryRed;
}
<div class="menu">
<ul>
<li>LINK 1</li>
<li>LINK 2</li>
<li>LINK 3</li>
</ul>
</div>
You must change html code, a element must be inside li element.
Like this:
<li>LINK 1</li>
and also
:before for li
.menu {
grid-area: menu;
justify-self: right;
align-items: center;
padding: 30px 50px;
padding-bottom: 0px;
}
.menu ul {
list-style-type: none;
font-family: 'LemonReg', sans-serif;
}
.menu ul a {
display: inline-block;
color: $yellowish;
text-transform: uppercase;
font-size: 20px;
}
.menu ul li {
display: inline-block;
color: $yellowish;
text-transform: uppercase;
font-size: 20px;
}
.menu ul li:not(:first-child):before {
padding-right: 15px;
padding-left: 15px;
content: '\2605';
color: blue;
}
<div class="menu">
<ul>
<li>LINK 1</li>
<li>LINK 2</li>
<li>LINK 3</li>
</ul>
</div>

Can't get navbar centered on page

I'm trying to get my navbar centered on my page with the edges of navbar going for entire length of browser window. I cannot figure this out. I think it has something to do with the float:left of the individual nav items. I want this nav bar to be orange background across entire browser window, but the actual nav items to be centered on page. I've copied code below and working demo below that.
<div id="nav-wrapper">
<div id="navmenu">
<ul class="nav" >
<li>About
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
</li>
<li>Members & Groups
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
</li>
<li>Meetings & Events
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
</li>
</ul>
<!-- hp navigation end -->
</div>
</div>
#nav-wrapper {
width:100%;
background: #ff6633;
margin 0 auto;
}
#navmenu{
margin 0 auto;
width:100%;
}
#navmenu ul {
list-style-type: none;
padding: 0;
}
.nav li > a {
background: #ff6633;
color: white;
width: 137px;
}
.nav > li > a {
display: block;
height: 100%;
padding: 0px;
color: #000000;
text-decoration: none;
text-align: center;
line-height: 32px;
outline: none;
border-right: 1px solid #D6D3D3;
}
.nav > li:hover > a {
color:#333;
}
.nav > li {
padding: 0;
height: 30px;
font-family: Arial, Helvetica, sans-serif;
letter-spacing: -0.5px;
font-size: 14px;
}
.nav li {
float: left;
}
.nav li > ul {
position: absolute;
display: none;
border-bottom: 0;
width: 220px;
z-index: 9999;
}
.nav li > ul > li > a {
text-decoration: none;
color: #0f2992;
display: block;
padding:5px 3px 5px 10px;
text-indent:-7px;
}
.nav li:hover > ul {
display: block;
}
http://codepen.io/trevoray/pen/KwJPLO
#navmenu{
margin 0 auto;
width:100%;
}
#navmenu ul {
list-style-type: none;
padding: 0;
text-align:center
}
.nav li > a {
background: #ff6633;
color: white;
width: 137px;
}
.nav li > ul > li {
width:100%;display:inline-block
}
.nav > li > a {
display: block;
height: 100%;
padding: 0px;
color: #000000;
text-decoration: none;
text-align: center;
line-height: 32px;
outline: none;
border-right: 1px solid #D6D3D3;
width:100%;
}
.nav > li:hover > a {
color:#333;
}
.nav > li {
padding: 0;
height: 30px;
font-family: Arial, Helvetica, sans-serif;
letter-spacing: -0.5px;
font-size: 14px;
position: relative;
width: 32%;
}
.nav li {
display:inline-block
}
.nav li > ul {
position: absolute;
display: none;
border-bottom: 0;
width: 100%;
z-index: 9999;
list-style:none;
text-align: left !important;
}
.nav li > ul > li > a {
text-decoration: none;
color: #0f2992;
display: block;
padding:5px 3px 5px 10px;
text-indent:-7px;
width:100%;
box-sizing: border-box;
}
.nav li:hover > ul {
display: block;
}
<div id="nav-wrapper">
<div id="navmenu">
<ul class="nav" >
<li>About
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
</li>
<li>Members & Groups
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
</li>
<li>Meetings & Events
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
</li>
</ul>
<!-- hp navigation end -->
</div>
</div>
try this :http://jsfiddle.net/au07b2r3/3/
i remove float left from li ..and set display : inline-block

How do I make the dropdown menu width the same as the tab size?

I'm new to this - sorry if this is a silly problem. When I hover over the dropdown menu options, the submenu appears, but the background of the submenu has a width of 100%, like the main menu. How can I alter it so that the submenu has a width only of, say, the tab it originates from?
Also, apologies for messy coding. I was playing around with jquery so there are some unnecessary tags in there...
Here is the CSS code:
#menu {
float:left;
width:100%;
background-color:#f23918;
overflow:hidden;
position:relative;
}
#menu ul {
clear:left;
float:left;
list-style:none;
margin:0;
padding:0;
position:relative;
left:50%;
text-align:center;
}
ul li {
display:block;
float:left;
list-style:none;
margin:0;
padding:0;
position:relative;
right:50%;
}
li ul {
display: none;
}
ul li a {
display: block;
text-decoration: none;
font-weight: bold;
color: #ffffff;
white-space: nowrap;
background-color: #f23918;
text-align: center;
padding: 10px;
text-transform: uppercase;
}
ul li a:hover {
background: #f29c18;
}
li:hover ul {
display: block;
position: absolute;
}
li:hover li { /*Controls dropdowns*/
float: none;
font-size: 11px;
}
li:hover a { background: #f23918;
}
li:hover li a:hover
{
background: #f29c18;
}
and Here is the HTML code:
<div id="menu">
<ul id="navbar">
<li class="active"><span>Home</span></li>
<li class="has-sub"><span>Alpaca Wool Products</span>
<ul class="submenu">
<li><span>Fur Hats</span></li>
<li><span>Capes</span></li>
<li><span>Ponchos</span></li>
<li><span>Shawls</span></li>
<li class="last"><span>Scarves</span></li>
</ul>
</li>
<li class="has-sub"><span>Home Décor</span>
<ul class="submenu">
<li><span>Rugs</span></li>
<li><span>Tapestries</span></li>
<li><span>Throws</span></li>
<li><span>Upholstery</span></li>
<li class="last"><span>Teddy Bears</span></li>
</ul>
</li>
<li><span>About Us</span></li>
<li class="last"><span>Artisans</span></li>
</ul>
</div>
Ok. Here a workout. There might better solution exists.
First you need to give a fixed height to div#menu. Also I dont think you need a float there. Remove overflow hidden and position relative.
#menu {
width:100%;
background-color:#f23918;
height: 38px;
}
Then for submenu add following
li ul {
display: none;
min-width: 100%;
white-space: nowrap;
}
Last solution actually credited to https://stackoverflow.com/a/13775531/2120162
Here you can find how it looks. https://jsfiddle.net/theprog/3h8wpx97/1/
Update: Fixed moving part. Thanks #dowomenfart
li ul {
display: none;
min-width: 100%;
white-space: nowrap;
position:absolute !important;
z-index: 100;
}
Rather than tweaking your code I rewrote a simplified version based on what you need.
$(document).ready(function () {
$("#navbar > li").mouseover(function () {
if (!$(this).hasClass("active")) {
$(this).addClass("active");
$(this).mouseout(function () {
$(this).removeClass("active");
});
}
});
});
#navbar {
background: #f23918;
padding: 0;
margin: 0;
font-size: 0; /*fix inline block gap*/
}
#navbar > li {
font-size: 16px;
list-style: none;
position: relative;
display: inline-block;
padding: 0;
margin: 0;
}
#navbar > li > a {
text-transform: uppercase;
text-decoration: none;
font-size: 16px;
font-weight: bold;
padding: 10px;
display: block;
color: #fff;
}
#navbar > li > a:hover,
#navbar > li.active > a,
#navbar > li > ul {
background: #f29c18;
}
#navbar > li > ul {
display: none;
white-space: nowrap;
padding: 0 0 5px;
margin: 0;
position: absolute;
left: 0;
top: 36px;
}
#navbar > li > ul > li {
display: block;
margin: 10px 20px;
padding: 0;
}
#navbar > li > ul > li > a {
color: #fff;
}
#navbar > li:hover > ul {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul id="navbar">
<li>
Item A
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
<li>Sub Item 3</li>
</ul>
</li>
<li>
Item B
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
<li>Sub Item 3</li>
</ul>
</li>
<li class="active">
Item C
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
<li>Sub Item 3</li>
</ul>
</li>
<li>
Item D NoSub
</li>
</ul>

Using :target #id and classes to show/hide navigation without JS

So I am struggling to make a show/hide button within my navigation to work. My goal is do this purely with CSS. It is supposed to activate when the browser screen is too small to display all the navigation items. I am successful in hiding the items I do not want seen at certain screen widths, however I cannot seem to get the link which activates the :target to display them when clicked.
Here is the css
nav {width:100%; min-width:287px;}
nav ul {padding:0;}
nav li {
list-style: none;
width:26%;
min-width:67px;
display:block;
line-height: 2.5em;
position: relative;
float: left;
border-bottom: 1px solid #fff;
background-color:#333;
box-shadow: 0px 5px 5px 1px #333;
text-align:center;}
nav li a {color:#fff; text-decoration:none; height:100%; font-size:1em; display:block; white-space:nowrap;}
nav li:hover {background-color:#BA7007;}
nav li a:hover {color:#FFF;}
nav li a:visited {color:#FFF; background-color:#333;}
.prio-alpha {}
.prio-gamma,
.prio-beta,
.show-nav-less {display: none;}
#prio:target + .prio-beta,
#prio:target + .prio-gamma,
#prio:target + .show-nav-less {display: block; }
#prio:target + .show-nav-more { display: none; }
.show-nav-more {width:20%;}
#media screen and (min-width: 41em) {
nav li {width:20%;}
nav li a {font-size:1.4em;}
.prio-beta { display: block; }
#prio:target + .prio-gamma, #prio:target + .show-nav-less {display: block;}
#prio:target + .show-nav-more { display: none; }}
#media screen and (min-width: 65em) {
nav li {width:16.5%;}
.prio-gamma { display: block; }
.show-nav-more,
#prio:target + .show-nav-less { display: none; } }
and html:
<nav>
<ul>
<li class="prio-beta">Home</li>
<li class="prio-alpha">Research</li>
<li class="prio-alpha">Publications</li>
<li class="prio-gamma">Space Flies</li>
<li class="prio-gamma">Aging PPG Project</li>
<li class="prio-alpha">Contact</li>
<li class="show-nav-more">+ more</li>
<li class="show-nav-less">- less</li>
</ul>
I have tried to switch up the order, placing the class in front of the :target and even removing #prior and just using .class:target to no apparent difference in the function of the code when live.
From what I understand you just want it so that you don't need JS for a submenu to open on click?
Here's a very quick/dirty version, it should get the idea across and hopefully you can edit it for your needs
Quick and Dirty
#nav {
list-style-type: none;
position: relative;
}
#nav li {
display: inline-block;
width: 100px;
border: 1px solid grey;
border-radius: 2px;
box-sizing: padding-box;
padding: 3px;
}
#nav #show_more {
display: none;
}
#nav li:target {
display: block !important;
position: relative;
top: 100%;
left: 10px;
}
<ul id="nav">
<li>Page 1</li>
<li>Page 2</li>
<li>Page 3</li>
<li>Page 4</li>
<li>
More
<ul class="submenu">
<li id="show_more">
There is more stuff here, woo.
</li>
</ul>
</li>
</ul>
One that uses Hovers
This should give a bit more responsiveness when hovering over a menu item. I'm not sure what you are going for, but hopefully one of these helps.
#nav,
#nav > li {
list-style-type: none;
position: relative;
}
#nav li {
display: inline-block;
width: 100px;
border: 1px solid grey;
border-radius: 2px;
box-sizing: padding-box;
padding: 3px;
}
#nav li > ul {
display: none;
}
#nav li:hover >ul {
position: absolute;
top: 100%;
left: 0;
margin: 0;
padding: 0;
display: block;
}
#nav li:hover >ul li {
display: block;
}
<ul id="nav">
<li>Page 1</li>
<li>Page 2</li>
<li>Page 3</li>
<li>Page 4</li>
<li>
More
<ul>
<li>Sub Menu 1</li>
<li>Sub Menu 2</li>
<li>Sub Menu 3</li>
<li>Sub Menu 4</li>
<li>Sub Menu 5</li>
</ul>
</li>
</ul>

css navigation bar problems with the submenus

I am hoping that someone could help me out with a css problem that has been driving me crazy all day. I know I'm missing something obvious here, I just don't see it. If you can help that would be greatly appreciated.
Here is the fiddle http://jsfiddle.net/taglegacy/HK7Hy/
And here is the css:
body
{
margin: 20;
padding: 20;
text-align: center;
font: 85% arial, helvetica, sans-serif;
background: #f1f1f1;
color: #444;
}
#container
{
text-align: left;
margin: 0 auto;
width: 700px;
height: 400px;
background: #FFF;
}
/*---NavigationBar---*/
ul
{
font-family: Arial, Verdana;
font-size: 14px;
width: 100%;
margin: 0;
padding: 0;
list-style: none;
float: left;
background: #9b1b19;
}
ul li
{
display: block;
position: relative;
float: left;
border-right: 1px solid #fff;
}
li ul
{
display: none;
position:absolute;
left:0;
}
ul li a
{
display: block;
text-decoration: none;
color: #fff;
padding: 5px 15px 5px 15px;
background: #9b1b19;
margin-left: 1px;
white-space: nowrap;
}
ul li a:hover
{
background: #af1f1c;
}
li:hover ul
{
display: block;
position: absolute;
background: #af1f1c;
}
li:hover li
{
float: none;
font-size: 11px;
background: #af1f1c;
border-top: 1px solid #fff;
}
li:hover a
{
background: #af1f1c;
}
li:hover li a:hover
{
background: #af1f1c;
}
Here is the HTML:
<body>
<div id="container">
<ul>
<li>Menu 1</li>
<li>Menu 2
<ul>
<li>Submenu 1</li>
<li>Submenu 2</li>
<li>Submenu 3</li>
</ul>
</li>
<li>Menu 3
<ul>
<li>Submenu 1</li>
<li>Submenu 2</li>
<li>Submenu 3</li>
<li>Submenu 4</li>
<li>Submenu 6</li>
</ul>
</li>
<li>Menu 4
<ul>
<li>Submenu 1</li>
<li>Submenu 2</li>
<li>Really Long Submenu 3 Really Long</li>
</ul>
</li>
</ul>
</div>
</body>
The "really long" list item is being cut off because your submenu ul is set to the width of it's parent li. Take out the width: 100% and it'll show the enter text.
Move it so that it only applies to the parent ul to retain the navbar width:
#topnav { width: 100% }
Fiddle
I think, a position:absolute is needed for the 2nd ul. Play around a bit with padding-top and/or top. In the example the padding-top is equal to height of main menu items.
ul#topnav > li > ul {position: absolute; top:0; left:0; padding-top:36px;}
should work, good luck!

Resources