Role of position: absolute in this CSS dropdown menu - html

While I've been learning more about CSS, I've been looking at this post on creating a drop-down menu and the code demo here.
Reading how position: absolute; should behave as described in the CSS specification, it states:
In the absolute positioning model, a box is explicitly offset with respect to its containing block. It is removed from the normal flow entirely (it has no impact on later siblings).
and the containing block is determined this way:
If the element has 'position: absolute', the containing block is established by the nearest ancestor with a position other than static... If there is no such ancestor, the containing block is the initial containing block.
In the linked post on the menu, it doesn't explain how the absolute positioning works in this case. First, there are no offsets to position the elements. And, unless I'm missing something, it looks to me as if no other page elements have anything other than the default position: static;
My expectation then isn't that the dropdowns using position:absolute; would appear as part of the dropdown, but should maybe be positioned with respect to the page instead, so perhaps appear in the top-left corner instead, completely out of flow.
My assumption's wrong. So, how is the positioning directly below the parent menu item explained?
HTML:
<body class="news">
<header>
<div class="nav">
<ul>
<li class="home">Home</li>
<li class="tutorials">Tutorials
<ul>
<li>Tutorial #1##</li>
<li>Tutorial #2</li>
<li>Tutorial #3</li>
</ul>
</li>
<li class="about"><a class="active" href="#">About</a></li>
<li class="news">Newsletter
<ul>
<li>News #1</li>
<li>News #2###</li>
<li>News #3</li>
</ul>
</li>
<li class="contact">Contact</li>
</ul>
</div>
</header>
</body>
CSS:
body {
margin: 0;
padding: 0;
background: #ccc;
}
.nav ul {
list-style: none;
background-color: #444;
text-align: center;
padding: 0;
margin: 0;
}
.nav li {
font-family: 'Oswald', sans-serif;
font-size: 1.2em;
line-height: 40px;
text-align: left;
}
.nav a {
text-decoration: none;
color: #fff;
display: block;
padding-left: 15px;
border-bottom: 1px solid #888;
transition: .3s background-color;
}
.nav a:hover {
background-color: #005f5f;
}
.nav a.active {
background-color: #aaa;
color: #444;
cursor: default;
}
/* Sub Menus */
.nav li li {
font-size: .8em;
}
/*******************************************
Style menu for larger screens
Using 650px (130px each * 5 items), but ems
or other values could be used depending on other factors
********************************************/
#media screen and (min-width: 650px) {
.nav li {
width: 130px;
border-bottom: none;
height: 50px;
line-height: 50px;
font-size: 1.4em;
display: inline-block;
margin-right: -4px;
}
.nav a {
border-bottom: none;
}
.nav > ul > li {
text-align: center;
}
.nav > ul > li > a {
padding-left: 0;
}
/* Sub Menus */
.nav li ul {
position: absolute;
display: none;
width: inherit;
}
.nav li:hover ul {
display: block;
}
.nav li ul li {
display: block;
}
}

add position: relative; to nav li and position: absolute; to all submenu <ul> elements (i.e. the nav li ul selector). This anchors the submenu lists to their corresponding list elements in the main menu.
Then add top and left values (in px) to those submenu <ul> elements to finetune their position in relation to their parent elements (i.e. the li ul)

Related

How do I get the submenu to not disappear?

I have a navigation menu on my website. It works, however when hovering over a menu item with sub-items they disappear when trying to click on them. It appears that there is a spacing issue with these items.
*Additionally, I am trying to figure out how to insert a | between the menu items. If you could share some insight that would be amazing. I only have basic coding knowledge as you can probably tell from my post.
I appreciate the assistance!
/* do not change */
.container {
overflow: unset;
}
#container ul {
margin: 0px;
padding: 0px;
list-style-type: none;
display: inline-block;
}
#container ul li ul li {
display: none;
}
/* can change */
#container {
text-align: center;
}
#container ul li {
width: 130px;
height: 30px;
line-height: 30px;
float: left;
text-align: center;
margin: 5px;
border-radius: 0px;
}
#container ul li a {
color: black;
text-decoration: none;
font-weight: bold;
display: block;
}
#container ul li a:hover {
text-decoration: none;
border-radius: 0px;
color: #1dcdfe;
}
#container ul li:hover ul li {
background-color: white;
display: block;
margin-left: 0px;
}
<div id="container">
<ul>
<li><a href='#scroll-home'>Home</a></li>
<li><a href='#'>About Us</a>
<ul>
<li><a href='#scroll-whyhere'>Why You're Here</a></li>
<li><a href='#scroll-ourmethod'>Our Method</a></li>
<li><a href='#scroll-whyus'>Why Choose US</a></li>
<li><a href='#scroll-testimonials'>Testimonials</a></li>
</ul>
</li>
<li><a href='#'>Our Services</a>
<ul>
<li><a href='#scroll-wetreat'>What We Treat</a></li>
<li><a href='#scroll-packages'>Packages & Pricing</a></li>
</ul>
</li>
<li><a href='#scroll-faq'>FAQs</a></li>
<li><a href='#'>Contact Us</a></li>
</ul>
</div>
If I'm understanding you correctly, you want horizontal separators on your top-most navigation elements.
To do this, you can add borders to your li elements and then exclude the last one, like so:
#container ul li {
// ... other styles here
border-right: 1px solid black;
}
/* Add this additional style so that the last item doesn't receive the border */
#container ul li:last-child {
border-right: none;
}
A working example can be found at https://codepen.io/BrandonClapp/pen/wvGqrmQ
Following code add the pipes between menu's
#container > ul > li {
border-right: 1px solid black;
}
#container > ul > li:last-child {
border-right: 0;
}
Well thats because you have given every li a specific height here:
#container ul li {
width: 130px;
height: 30px;
line-height: 30px;
float: left;
text-align: center;
margin: 5px;
border-radius: 0px;
}
Which does not let the box grow when its hovered. You can give the nav buttons that have the hovering option an id and give the following code:
#container ul li #drop_down{
height: 100%;
}
For hindering future confusion, if you want to select direct children, use >, like so:
#container > ul {
margin: 0px;
padding: 0px;
list-style-type: none;
display: inline-block;
}
Here you have not used it, so even the inner ul is having these attributes, which ruins it. If you change it to the code above it will get fixed. Why? because the inner ul has the display: inline-block; attribute in your code which should not be.
Furthermore, Try giving the box a background-color and a z-index, so it will not keep detecting hover in behind boxes, in this case contact button.
For your other question I refer you to this link:
How to make a vertical line in HTML
And, or:
https://medium.com/#hollybourneville/creating-border-lines-using-pseudo-elements-in-css-a460396299e8

I'm Making Drop Down Menu, But It Shows Vertically Incorrectly

I found a video that explains how to create drop down menu, as the headlines should appear horizontally and sublines should appear vertically, with me the head & sub lines shows vertically! I checked the code many times, but I can't find where is the problem in the code!
I'm beginner to HTML5 & CSS.
#headlist ul {
margin: 0px;
padding: 0px;
list-style: none;
font-family: Roboto Light;
}
#headlist ul li {
float: left;
width: 1225px;
height: 70px;
background-color: #303030;
line-height: 70px;
text-align: center;
font-size: 30px;
position: relative;
bottom: 15px;
}
#headlist ul li a {
text-decoration: none;
color: white;
display: block;
}
#headlist ul li a:hover {
background-color: green;
}
#headlist ul li ul li {
display: none;
}
#headlist ul li:hover ul li {
display: block;
<div class="welcome">
<div id="headlist">
<ul>
<li>
<a>About</a>
<ul>
<li>Who We Are?</li>
<li>Key People</li>
</ul>
</li>
<li>
Divisions
<ul>
<li>ExtenzaLife</li>
<li>Ludic Science</li>
<li>Fleming-Monroe</li>
<li>Massive Logistic</li>
<li>Massive Energetic</li>
<li>Teleportation Center</li>
</ul>
</li>
<li>
Massive Dynamic Foundation
</li>
</ul>
</div>
<p id="welto">WELCOME TO</p>
<h1> M A S S I V E<br>D Y N A M I C </h1>
<h2><span>“</span>What do we do? What don't we do!<span>"</span></h2>
</div>
the project content I inspired it from Fringe series.
Several issues with the original code...
Whenever you have a nested ul li structure like this (very common for menus), you must make sure that the CSS is specific enough to target the top level (main menu) and the child menus (dropdowns) separately. Your CSS was unintentionally targeting both, example:
#headlist ul li
This selector is targeting ALL the li elements in your menu when I believe you only wanted to target the top level items. To fix you can use the immediate child selector ">" like this:
#headlist > ul > li
This is targeting only li elements that are immediately inside of ul elements that are immediately inside of the #headlist element (the top menu items only).
Once you are clearly targeting the top level menu items and the drop down items with different CSS, you can achieve the desired layout more easily. I removed the float and styled the top level menu items like this:
#headlist > ul {
display: flex;
}
#headlist > ul > li {
position: relative;
flex: 1 0 auto;
}
The top level menu becomes a flexbox container allowing the contained li elements to flow in a horizontal row. The flex rule on the li items allows them to grow to fill the available space.
The only other main change is I am using absolute positioning on the dropdowns which requires position: relative on the top level lis.
Not perfect but I hope this will help you get going in the right direction.
#headlist ul {
margin: 0px;
padding: 0px;
list-style: none;
font-family: Roboto Light;
}
#headlist > ul {
display: flex;
}
#headlist > ul > li {
position: relative;
flex: 1 0 auto;
}
#headlist ul li {
height: 70px;
background-color: #303030;
line-height: 70px;
text-align: center;
font-size: 30px;
position: relative;
bottom: 15px;
}
#headlist ul li a {
text-decoration: none;
color: white;
display: block;
}
#headlist ul li a:hover {
background-color: green;
}
#headlist > ul > li ul {
display: none;
position: absolute;
min-width: 250px;
top: 100%;
left: 0;
}
#headlist > ul > li:hover ul {
display: block;
}
<div class="welcome">
<div id="headlist">
<ul>
<li>
<a>About</a>
<ul>
<li>Who We Are?</li>
<li>Key People</li>
</ul>
</li>
<li>
Divisions
<ul>
<li>ExtenzaLife</li>
<li>Ludic Science</li>
<li>Fleming-Monroe</li>
<li>Massive Logistic</li>
<li>Massive Energetic</li>
<li>Teleportation Center</li>
</ul>
</li>
<li>
Massive Dynamic Foundation
</li>
</ul>
</div>
<p id="welto">WELCOME TO</p>
<h1> M A S S I V E<br>D Y N A M I C </h1>
<h2><span>“</span>What do we do? What don't we do!<span>"</span></h2>
</div>

Dropdown Submenu Disappears on Hover

While I know there are several discussions regarding this issue, none of the solutions fixed my problem. No matter what I do, the CSS submenu I'm trying to use disappears after you stop hovering over the parent li. I haven't the slightest idea what could be causing this, and I've really been staring at this forever trying to find a solution and just can't. I tried adding in a top: px; to the submenu in the CSS, which allowed me to select the submenu options, however it also moved the menu so that it would appear covering and centered over the parent li, which is also no good to me because I need it to appear directly below. Could the header be clipping it and if so what would I need to add to change that? All assistance is so greatly appreciated!
.nav ul {
list-style: none;
background-color: #444;
text-align: center;
padding: 0;
margin: 0;
}
.nav li {
font-size: 1.2em;
line-height: 40px;
text-align: left;
display: none;
}
.nav a {
text-decoration: none;
color: #fff;
display: block;
padding-left: 15px;
transition: .3s background-color;
}
.nav a:hover {
background-color: #005f5f;
}
.nav a.active {
background-color: #aaa;
color: #444;
cursor: default;
}
/* Sub Menus */
.nav li li {
font-size: .8em;
}
#media screen and (min-width: 650px) {
.nav li {
width: 130px;
border-bottom: none;
height: 50px;
line-height: 50px;
font-size: 1.4em;
display: inline-block;
margin-right: -4px;
}
.nav a {
border-bottom: none;
}
.nav > ul > li {
text-align: center;
}
.nav > ul > li > a {
padding-left: 0;
}
/* Sub Menus */
.nav li ul {
position: absolute;
display: none;
width: inherit;
}
.nav li:hover ul {
display: block;
}
.nav li ul li {
display: block;
}
}
#header {
float: left;
background-color: #ffffff;
cursor: default;
padding: 1.75em 2em 0em 0em;
position: relative;
}
<header>
<img id="logo" src="images/logo.jpg" alt="logo">
<div class="nav">
<ul>
<li class="home">Home
</li>
<li class="tutorials">Tutorials
<ul>
<li>Tutorial #1##
</li>
<li>Tutorial #2
</li>
<li>Tutorial #3
</li>
</ul>
</li>
<li class="about"><a class="active" href="#">About</a>
</li>
<li class="news">Newsletter
<ul>
<li>News #1
</li>
<li>News #2###
</li>
<li>News #3
</li>
</ul>
</li>
<li class="contact">Contact
</li>
</ul>
</div>
</header>
I did figure this out eventually but thought I should come back and update with my solution, in case it is helpful to anyone who is having a similar issue. It was actually really simple.
I had to add a z-index here:
.nav li:hover ul {
display: block;
z-index: 99999;
}
This was recommended to other users, and I did try it initially but did not place it in li:hover thus it didn't work. I guess because the high z-index forces it to the top, it stopped whatever was causing the clipping by placing the submenu above it. I must have misread something somewhere along the line and placed the z-index in the wrong section. The real solution here is probably to read your code carefully!

Creating a dropdown list item menu with CSS only

In a section of website I'm working on I have a NAV element that contains three sections: About, Portfolio, Contact. I'm trying to make it so that when you hover over the Portfolio section, a drop down appears allowing you to choose between two other sections, "Writing Samples" and "Photoshop." I am trying to accomplish this using only CSS.
This is my HTML section:
<nav>
<ul>
<li>
<a href="index.html" >About</a>
</li>
<li class="subNav">
<a class="selected" >Portfolio</a>
<ul>
<li>Writing Samples</li>
<li>Photoshop</li>
</ul>
</li>
<li>
Contact
</li>
</ul>
</nav>
And CSS:
nav {
position: absolute;
bottom: 0;
right: 0;
padding: 10px 0;
}
nav ul {
list-style: none;
margin: 0 10px;
padding: 0;
}
nav li {
display: inline-block;
}
nav a {
font-weight: 800;
padding: 15px 10px;
}
nav ul li.subNav ul {
display: none;
}
nav ul li.subNav:hover ul {
display: block;
}
I have reached the point that when I hover over the Portfolio list item, you see the resulting list items "Writing Samples" and "Photoshop", except that it displays these two items as a part of the original unordered list, and moves the "Portfolio" list item above the rest of the items. I would like "Writing Samples" and "Photoshop" to appear vertically under "Portfolio", but I can't quite figure this out with CSS.
This is the basics of it:
nav {
position: absolute;
padding: 10px 0;
}
nav ul {
list-style: none;
;
padding: 0;
}
nav > ul > li {
display: inline-block;
position: relative;
border: 1px solid lightgreen;
/* for demo */
}
nav a {
font-weight: 800;
padding: 5px 10px;
display: block;
}
nav > ul > li.subNav ul {
display: none;
position: absolute;
top: 100%;
left: 0;
white-space: nowrap;
background: pink;
}
nav ul li.subNav:hover ul {
display: block;
}
<nav>
<ul>
<li>
About
</li>
<li class="subNav">
<a class="selected">Portfolio</a>
<ul>
<li>Writing Samples
</li>
<li>Photoshop
</li>
</ul>
</li>
<li>
Contact
</li>
</ul>
</nav>
The parent li is given position:relative to provide positioning context.
The submenu is positioned absolutely, at the bottom of the parent li and aligned left.
Note that I have used the direct child selector > to target only the elements I want to.
Then, since the submenu is too wide to be contained within the parent's width, I added white-space:nowrap so that the text will flow as required.
You have the right idea; the comment tags in the HTML below are used to remove space between the "li" elements.
Instead of using display:none, I use visibility: hidden for S.E.O purposes.
Even though you use position: absolute, you should also use z-index so that menu elements are able to be clicked if they are overlapping other content.
.mm,
.sm {
list-style: none;
}
.mm {
position: relative;
margin: 0px;
padding: 0px;
background-color: #000;
border-bottom: 4px solid red;
}
.sm {
position: absolute;
z-index: 1;
visibility: hidden;
background-color: #000;
border-width: 0px 4px 4px 4px;
border-style: solid;
border-color: red;
}
.mm > li {
display: inline-block;
}
.mm > li > a {
display: inline-block;
padding: 8px;
}
.sm a {
display: block;
padding: 8px;
}
.mm > li > a:hover + .sm,
.sm:hover {
visibility: visible;
}
.mm a {
text-decoration: none;
color: #FFF;
}
.mm a:hover {
text-decoration: underline;
color: yellow;
}
<nav>
<ul class="mm">
<li>AAA</li><!--
--><li>BBB
<ul class="sm">
<li>SUB</li><!--
--><li>SUB</li><!--
--><li>SUB</li>
</ul>
</li><!--
--><li>CCC
<ul class="sm">
<li>SUB</li><!--
--><li>SUB</li><!--
--><li>SUB</li>
</ul>
</li>
</ul>
</nav>
<h1>CSS NAVIGATION</h1>

CSS - looking for a good way to display <LI> options with posotion:absolute

I have the code:
<div class='selectAnAction'>
<ul>
<li class='actionSelect'><span>Select an Action</span></li>
<li class='action' onclick='location.href=\"/post.php?key=".$row['hash']."\";'>post</li>
<li class='action' onclick='location.href=\"/adpreview.php?key=".$row['hash']."\";'>preview</li>
<li class='action' onclick='location.href=\"/adupdate.php?key=".$row['hash']."\";'>edit</li>
<li class='action' onclick='location.href=\"/addelete.php?key=".$row['hash']."\";'>archive</li>
</ul>
</div>
And I have this CSS:
.selectAnAction ul {
display: block;
background-image: url("/images/selectAnAction-dropdown.png");
background-position: 0px -200px;
background-repeat: repeat-x;
border: 1px solid #FFFFFF;
box-shadow: 0px 0px 3px #CCCCCC;
font-size: 0.75em;
list-style: none outside none;
margin: 0px;
overflow: hidden;
padding: 0px;
text-indent: 0px;
width: 120px;
color:white;
}
ul {
display: block;
}
.selectAnAction ul li.actionSelect {
background: url("/images/selectAnAction-bg.png") repeat-x transparent;
font-weight: bold;
}
.selectAnAction ul li:first-child {
display: block;
}
.selectAnAction ul li {
display: none;
margin: 0px;
text-indent: 0px;
width: 120px;
background-color:grey;
}
.selectAnAction:hover ul li{
display: block;
margin: 0px;
text-indent: 0px;
width: 120px;
}
.selectAnAction ul {
font-size: 0.75em;
list-style: none outside none;
}
.selectAnAction ul li {
display: none;
margin: 0px;
text-indent: 0px;
width: 100%;
padding-left:10px;
font-family:"Times New Roman",Georgia,Serif;
font-size:1.3em;
text-align:left;
}
.action:hover {
background-color:black;
cursor:pointer;
}
What I get is an action menu.
First I see only the LI "select option".
On mouse over - it shows other options (post, edit, archive etc)
I have many such menus on the page.
I want to fix the position of .action elements so that they don't influence the design of rest of the site (because right now when they become visible - other elements of the site move as well).
So I was trying to add something like:
.action {
position:absolute;
}
But what happens is all the .action elements show up on top of each other - right after the first LI (.actionSelect).
So now I'm trying to make them show not on top of each other, but one after another, but with position absolute.
Is there any good way to do that?
(m.b. someting like top:+20px;)
Position: relative does not work - in this way when .action elements become visible - they will move all other elements.
Can't use hard absolute positioning too (top:100px) as I have many of these lists on the page.
You want to position the ul absolutely, and then move the action select outside of the ul as the parent element. If you want to keep the select in a ul, you should have a nested ul for the options. Be sure to add position:relative to whatever is the parent of the options list.
<div class='selectAnAction'>
<ul>
<li class='actionSelect'>
<span>Select an Action</span></li>
<ul class="optionMenu">
<li class='action' onclick='location.href=\"/post.php?key=".$row['hash']."\";'>post</li>
<li class='action' onclick='location.href=\"/adpreview.php?key=".$row['hash']."\";'>preview</li>
<li class='action' onclick='location.href=\"/adupdate.php?key=".$row['hash']."\";'>edit</li>
<li class='action' onclick='location.href=\"/addelete.php?key=".$row['hash']."\";'>archive</li>
</ul>
</li>
</ul>
</div>
position:absolute should be on the .selectAnAction ul li ul I believe
Check out this site for doing dropdowns http://www.htmldog.com/articles/suckerfish/dropdowns/