CSS3: how to make a dynamic drop down navigation bar without JS - html

So I am trying to make a pure CSS3 dropdown navigation. Of all the stack overflow questions about this, this was the closest I found.
What I dislike, however, is the use of defined heights, which makes everything a pain to refactor if you wish to change the heights later on.
Below is my own attempt, which uses barely any css and gets close to the desire result. The only issues with it is:
the "drop down" is more of a shove up and
if the first point is fixed, it would look bad in a header (as the entire header would jump about)
How can I fix these issues with minimal CSS and in a way that is dynamic and flexible (e.g. no absolute positionings, no fixed heights, etc)
/* all the CSS needed to make the drop down*/
/* set horizontal navigation for list elements*/
nav ul li {
display: inline-block;
}
/*remove padding from nested unordered list to get text to align*/
li > ul {
padding: 0;
}
/* hide nested list elements*/
li > ul li{
display: none;
padding: 0;
}
/* when hovering on the outer list element display nested list elements */
li:hover ul li{
display: block;
}
/* the following is added just to make the links clear to see*/
/*make text eady to see on dark background*/
li {
border: 1px coral solid
}
/*highlight the issue with the header bouncing*/
nav {
background-color: black;
color: coral;
}
<nav>
<ul>
<li><a>Link</a></li>
<li>
<a>Drop Down</a>
<ul>
<li><a>1</a></li>
<li><a>2</a></li>
<li><a>3</a></li>
<li><a>4</a></li>
</ul>
</li>
</ul>
</nav>

How is this, just added absolute positioning to the child ul - using absolute positioning doesn't make it any less responsive
/* all the CSS needed to make the drop down*/
/* set horizontal navigation for list elements*/
nav ul li {
display: inline-block;
position:relative;
}
/*remove padding from nested unordered list to get text to align*/
li>ul {
padding: 0;
position:absolute;
width:100%;
background: black; /* not sure if you want background-color on this */
}
/* hide nested list elements*/
li>ul li {
display: none;
padding: 0;
}
/* when hovering on the outer list element display nested list elements */
li:hover ul li {
display: block;
}
/* the following is added just to make the links clear to see*/
/*make text eady to see on dark background*/
li {
border: 1px coral solid
}
/*highlight the issue with the header bouncing*/
nav {
background-color: black;
color: coral;
}
<nav>
<ul>
<li><a>Link</a></li>
<li>
<a>Drop Down</a>
<ul>
<li><a>1</a></li>
<li><a>2</a></li>
<li><a>3</a></li>
<li><a>4</a></li>
</ul>
</li>
</ul>
</nav>

Use absolute position to style the dropdown.So the height issue will be fixed.Also don't forgot to add position:relative to the parent li tags.So the dropdown will position relative to the li tags
/* all the CSS needed to make the drop down*/
/* set horizontal navigation for list elements*/
nav ul li {
display: inline-block;
position:relative;
}
/*remove padding from nested unordered list to get text to align*/
li > ul {
padding: 0;
}
/* hide nested list elements*/
li > ul li{
display: none;
padding: 0;
}
/* when hovering on the outer list element display nested list elements */
li:hover ul li{
display: block;
}
/* the following is added just to make the links clear to see*/
/*make text eady to see on dark background*/
li {
border: 1px coral solid
}
/*highlight the issue with the header bouncing*/
nav {
background-color: black;
color: coral;
}
.dropdown{
position:absolute;
z-index:999;
width:100%;
}
<nav>
<ul>
<li><a>Link</a></li>
<li>
<a>Drop Down</a>
<ul class="dropdown">
<li><a>1</a></li>
<li><a>2</a></li>
<li><a>3</a></li>
<li><a>4</a></li>
</ul>
</li>
</ul>
</nav>

Related

z-index layered elements affecting base layer elements [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
As you can see there is an image slideshow in center of the page and those two description divisions which are set to z-index 2 but still it is been affecting the images and slideshow which doesnt have z-index defined
and when I removed the description divisions the slideshow gets back to normal
So is there any way I can add those description divisions in somewhat different layer from all other elemetns and prevent it from affecting other elements in the page (also those description divisions will be appeared on clicking the buttons in menubar by default they will be hidden)
You have to use position: absolute; for more info since you didn't share your code's use my example:
/* Giving a background-color to the nav container. */
nav {
margin: 100px 0;
background-color: #E64A19;
width: 700px;
}
/* Removing padding, margin and "list-style" from the "ul",
* and adding "position:reltive" */
nav ul {
padding:0;
margin:0;
list-style: none;
position: relative;
}
/* Positioning the navigation items inline */
nav ul li {
margin: 0px -7px 0 0;
display:inline-block;
background-color: #E64A19;
}
/* Styling the links */
nav a {
display:block;
padding:0 10px;
color:#FFF;
font-size:20px;
line-height: 60px;
text-decoration:none;
}
/* Background color change on Hover */
nav a:hover {
background-color: #000000;
}
/* Hide Dropdowns by Default
* and giving it a position of absolute */
nav ul ul {
display: none;
position: absolute;
top: 100%;
}
/* Display Dropdowns on Hover */
nav ul li:hover > ul {
display:inherit;
}
/* Fisrt Tier Dropdown */
nav ul ul li {
min-width:170px;
display:list-item;
position: relative;
}
/* Second, Third and more Tiers
* We move the 2nd and 3rd etc tier dropdowns to the left
* by the amount of the width of the first tier.
*/
nav ul ul ul {
position: absolute;
top:0;
left:100%;
}
/* Change ' +' in order to change the Dropdown symbol */
li > a:after { content: ' +'; }
li > a:only-child:after { content: ''; }
<nav>
<ul>
<li>Home</li>
<li>WordPress
<!-- First Tier Drop Down -->
<ul>
<li>Themes</li>
<li>Plugins</li>
<li>Tutorials
<!-- Second Tier Drop Down -->
<ul>
<li>Stuff</li>
<li>Things</li>
<li>Other Stuff</li>
</ul>
<!-- Second Tier Drop Down ends-->
</li>
</ul>
<!-- First Tier Drop Down ends -->
</li>
<li>Graphic Design</li>
<li>Inspiration</li>
<li>Contact</li>
<li>About</li>
</ul>
</nav>

Dropdown navigation with same width as parent navigation

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

Having issues centering my text in the drop down menu

I was able to create a drop down menu, but unable to center the text. Its
as if padding-left is set but I didn't set it. I just need help centering
the text in the drop down menu.
//drop down menu
<!DOCTYPE html>
<html>
<head>
<style>
.menu {
background-color:grey;
padding: 5px;
}
.menu li {
list-style:none;
padding: 3px;
}
.menu a {
text-decoration: none;
color: black;
}
.menu > li {
display:inline;
}
.dropmenu {
display:none;
float:right;
position:relative;
top:18px;
left:-422px;
}
.dropdown:hover > .dropmenu {
display:block;
}
.dropmenu {
background-color:grey;
}
</style>
</head>
<body>
<ul class = "menu">
<li>HOME</li>
<li>ABOUT</li>
<li class = "dropdown">SPORTS
<ul class = "dropmenu">
<li>NBA</li>
<li>NFL</li>
<li>MLB</li>
</ul>
</li>
<li>CONTACTS</li>
<li>BLOG</li>
</ul>
</body>
</html>
First, use text-align: center; on the dropdown menus. Your dropdown menus will look off center as there is default padding and margin the ul you are using for your dropdown menus that browser add by default. You will want to remove that padding/margin from the dropdown uls.
.dropmenu {
padding: 0;
text-align: center;
}
If the dropdown menu becomes too narrow after doing this you'll likely want to set a specific width for your dropdown menus.
.dropmenu {
padding: 0;
text-align: center;
width: 100%; /* same width as containing li */
}
jsFiddle: http://jsfiddle.net/7hjqjrjj/2/
If you're looking to clean up/fix alignment of your dropdown menu read below.
You want to apply position: relative; to the li's that contain a dropdown menu. Then apply position: absolute; to that dropdown menu (ul). You'll usually add left: 0; to the drowpdown menu (ul) as well.
Applying position: relative; to the containing li causes the absolutely positioned dropdown menu to position itself relative to the containing li, rather than some place like the top of the page.
We don't want the dropdown to position itself after the anchor tag or other content within the containing li so we use absolute positioning.
Update your CSS selectors as follows:
.menu li {
list-style: none;
padding: 3px;
position: relative;
}
.dropmenu {
display: none;
position: absolute;
top: 18px;
left: 0;
}
You may need to fiddle with your top and left values.
jsFiddle: http://jsfiddle.net/7hjqjrjj/1/

HTML and CSS Dropdown menu

I am working on our company website and I'm very new to HTML and CSS. I am trying to make a drop down menu for the Nav bar and I have the gist of it, but it needs some help. The dropdowns are not lining up properly, the text is too large, and the border I have is spanning the entire length of the lists.
CSS:
.menu{
padding:0;
margin:25px 0 0 0;
}
.menu, .menu li{
list-style: none;
display: block;
float:right;
padding:12px;
border-right: 1px solid #d8d8d8;
}
.menu li{
float:left;
display: block;
width: 100px;
}
.menu ul{
opacity: 0;
}
.menu ul li{
background-color: white;
}
.menu li:hover > ul{
opacity: 1;
}
.menu li.last-menu-item{
border: none;
padding-right:0;
}
.menu a{
color:#132d3c;
font-size:15px;
font-family: 'sansationbold';
text-transform: uppercase;
text-decoration: none;
font-weight:lighter;
}
.current-menu-item a{
color:#f15c22;
}
.menu a:hover{
color:#f15c22;
}
HTML:
<ul class="menu alignright">
<li class="current-menu-item">Home</li>
<li>About
<ul>
<li>Who We Ar</li>
<li>Values</li>
<li>Owners Message</li>
<li>Infotek Blog</li>
<li>Success Stories</li>
<li>Partners</li>
</ul>
</li>
<li>Products & Solutions
<ul>
<li>Security Solutions</li>
<li>Data Solutions</li>
<li>Communication Solutions</li>
<li>Connectivity Solutions</li>
<li>Infrastructure Solutions</li>
<li>Resources</li>
</ul>
</li>
<li class="last-menu-item">Contact</li>
</ul>
Can I get a little help?
http://jsfiddle.net/pQhpu/191/
Hi in this you're making some mistakes.
Don't use opacity for hide the submenus, set it with the property display:none
Set with position:relative your li and the ul inside them with position:absolute
View this demo an make any question http://jsfiddle.net/pQhpu/214/
EDIT
To resolve your request of centering the submenus in relation with his parent you can use Jquery.
I created this function for you: Review the demo here http://jsfiddle.net/pQhpu/264/
$(document).ready (function () {
$('.menu li').mouseenter(function (){
var $this = $(this),
$sub =$(this).children('ul'),
pad = parseInt($this.css('padding-left'),10)+parseInt($this.css('padding-right'),10),
move=($this.width()+pad-$sub.width())/2;
$sub.css ('left',move+'px');
});
})
All you have to change here is the name route of your li that displays the submenu; in my case is '.menu li' . This function takes the width of the submenu and his parent and make an operation to make it centered.
For the borders, put them on the a instead of the actual li. And put your padding on the a as well to push the borders to the right. You usually have to add a class like '.last' to the last item if you don't want a floating border off to the right. Will have to make the widths larger to accommodate all the text on one line, or reduce the overall size. That should get you started.
First off, your design is horrible. I think you probably copied it from somewhere, but there are so many cross-over/overlaying elements. Define each different part(menu options, drop down options, etc.) seperately, rather than applying things to all lis and what not.
Here is a fix for the width. I made the divs larger. It was pretty hard. Next you'd have to define a class for all drop down items, and then make their font-size smaller, and apply the same width as menu items so they aren't slightly larger than the menu items.
http://jsfiddle.net/pQhpu/200/
To correct the alignment issues add:
.menu, .menu li
{
padding: 12px 0 12px 0;
}
This is shown in firebug but not in your code above
.menu, .menu li
{
padding: 12px;
}
To prevent the border from spanning the entire length of the list, use the display property instead changing the opacity.
.menu ul{
display: none;
}
.menu li:hover > ul{
display: inline;
}

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/