Make absolute element sit directly below relative element - html

I'm currently building a dropdown nav bar that activates upon hover.
I would like the dropdown nav to display directly under the PORTFOLIO link when hovered over, it's currently displaying over to the right.
Styling and what not is going to come later, I wanted this bit sorted before carrying on.
<div class="twelve columns">
<ul class="navigation six columns offset-by-three">
<li>HOME</li>
<li>PORTFOLIO</li>
<div class="sub-hover">
Photos
Physical
Write
Studies
</div>
<li>ABOUT</li>
<li>CONTACT</li>
</ul>
</div>
.navigation {
display: flex;
flex-direction: row;
justify-content: center;
}
.navigation li {
display: inline-block;
padding: 10px 20px;
}
.submenu {
position: relative
}
.sub-hover {
position: absolute;
display:;
margin-top: 25px;
padding: 5px 10px;
}
.sub-hover a {
display: block;
}
.submenu:hover .sub-hover {
display: block;
}

There are a couple things you need to change:
You need to place your .sub-hover inside of the portfolio <li> instead of outside of it.
Display your .sub-hover div when .submenu is hovered. You can accomplish this by using the CSS sibling selector ~.
Display your .sub-hover div when the div itself is hovered.
In your .sub-hover div, use padding instead of margin so the div won't disappear when you move your mouse from the title to the dropdown.
CSS
.sub-hover {
padding-top: 25px;
}
.submenu:hover ~ .sub-hover {
display: block;
}
.sub-hover:hover {
display: block;
}
.navigation {
display: flex;
flex-direction: row;
justify-content: center;
}
.navigation li {
display: inline-block;
padding: 10px 20px;
}
.submenu {
position: relative
}
.sub-hover {
position: absolute;
display:;
padding-top: 25px;
padding: 5px 10px;
display: none;
}
.submenu:hover ~ .sub-hover {
display: block;
}
.sub-hover:hover {
display: block;
}
.sub-hover a {
display: block;
}
.submenu:hover .sub-hover {
display: block;
}
<div class="twelve columns">
<ul class="navigation six columns offset-by-three">
<li>HOME</li>
<li>PORTFOLIO
<div class="sub-hover">
Photos
Physical
Write
Studies
</div>
</li>
<li>ABOUT</li>
<li>CONTACT</li>
</ul>
</div>

This will take a little tweaking of your markup, but a common way to deal with this boils down to
<ul class="navigation">
<li>
<a>main menu item 1</a>
<li>
<a>main menu item 2</a>
<ul>
<li>
<a>drop down 1 under menu item 2</a>
</li>
<li>
<a>drop down 2 under menu item 2</a>
</li>
</ul>
<li>
</ul>
and
.navigation {
list-style: none
}
.navigation li {
display: inline-block;
position: relative;// required for positioning the dropdown relative to the parent menu item
}
.navigation li li {
display: block
}
.navigation ul {
display: none;
position: absolute;
top: 100%;// makes the dropdown "hang" from the menu
left: 0;// tweak as needed
width: 100px;//some value required here
}
.navigation li:hover ul {
display: block
}
The keys to your question are putting the dropdown inside the main menu item, making the main menu item position: relative, and making the dropdown position: absolute; top: 100%; width: something and left: something or right: something

Related

How do I create a drop-down list using hover::after?

I'm having trouble in figuring out how to create a vertical drop-down menu since I'm using hover::after in my CSS. I'm trying to have a transparent drop-down list under shops where I created a submenu consisting of best-selling, sales and gifts. But when I write these codes down, the submenu don't seem to appear at all but the hovering effect on "Shop" is still there and I couldn't figure out how to make this work. Sorry if my lines of codes are messy, I'm still learning how to code and develop a website through YouTube.
.navbar {
height: 12%;
display: flex;
align-items: center;
}
nav {
flex: 1;
text-align: right;
}
nav ul li {
list-style: none;
display: inline-block;
margin-left: 60px;
}
nav ul li a {
text-decoration: none;
color: #fff;
font-size: 13px;
}
nav ul li::after {
content: '';
width: 0%;
height: 2px;
background: #E6C7F3;
display: block;
margin: auto;
transition: 0.5s;
}
nav ul li:hover::after {
width: 100%;
}
.submenu {
display: none;
}
.nav ul li:hover::after .submenu {
display: block;
position: relative;
background: #fff;
margin-top: 15px;
margin-left: 15px;
}
<section class="header">
<div class="navbar">
<nav>
<ul>
<li>HOME</li>
<li>ABOUT US</li>
<li>SHOP</li>
<div class="submenu">
<ul>
<li>Best-Selling</li>
<li>Sales</li>
<li>Gifts</li>
</ul>
</div>
<li>FEEDBACK</li>
<li>CONTACT</li>
</ul>
</nav>
</div>
</section>

menu bar does not display

good morning, I have a problem with the menu bar, which when placing the logo makes the bar bigger, and I have a submenu, which does not display the options. I attach the code in case anyone can collaborate.
HOME
ABOUT
CONTACT
MENU
Ingresar
Buscar
Codigo QR
.imgBarra {
width: 30px;
height: 30px;
position: relative;
background: none;
align-items: flex-start;
padding: 0px;
margin: 0px;
margin-left: -20px;
margin-top: 20px;
}
.Barra li a{
text-decoration: none;
color: rgb(255, 255, 255);
padding: 20px;
display: block;
}
.Barra li{
display: inline-block;
text-align: center;
position: relative;
}
.Barra li a:hover{
background-color: aquamarine;
color: black;
}
.submenu{
position: absolute;
background: #e8e8e8;
width: 120%;
visibility: hidden;
}
.submenu li a{
display: block;
padding: 15px;
color: #fff;
font-family: Arial;
text-decoration: none;
}
.submenu li a:hover{
display: block;
transition: all .3s;
If your logo is .imgBarra, you don't need to add the property align-items: flex-start;
no display: flex; property has been set.
If you want to align it at the left of your header, you need to set the property to the container .barra.
Basically, if you set align-items: flex-start; to your logo container it will align all the children inside your logo container, not the logo itself.
To control the height and the alignment of the header properly you need to be careful with paddings and consider all the children inside.
Supposing that your HTML is like that:
<div class="barra>
<div class="imgBarra">Logo</div>
<ul>
<li>
Home
</li>
<li>
About
</li>
<li>
Contact
</li>
</ul>
</div>
To have an height of 110px total [30px(logo) + 40px(20px top + 20px bottom header padding) + 40px(20px top + 20px bottom links padding)], your CSS should look like this:
.barra {
position: relative;
padding: 20px;
display: flex;
align-items: center; /* to align vertically in the center all the children inside the header, so imgBarra and the li */
justify-content: space-between; /* or any other property to align horizontally the content inside the header */
}
.imgBarra {
width: 30px;
height: 30px;
}
.barra ul li a {
padding: 20px;
}
Regarding the submenu let's suppose your HTML looks like this, by hovering on "Home" the user should see your dropdown.
<div class="barra">
<div class="imgBarra">Logo</div>
<ul>
<li class="hasDropdown">
<a class="dropdownTrigger" href="#">Home</a>
<div class="dropdown">
<ul>
<li>Submenu Item 1</li>
<li>Submenu Item 2</li>
<li>Submenu Item 3</li>
</ul>
</div>
</li>
<li>
About
</li>
<li>
Contact
</li>
</ul>
</div>
To trigger and show the submenu you first need to hide the dropdown with visibility:hidden; then give this CSS rule which basically says "when hovering on "Home" (identified by the class dropdownTrigger) change the dropdown class to visiblity: visible;.
Your CSS should look like this:
.hasDropdown {
position: relative;
}
.dropdown {
visibility: hidden; /* Dropdown hidden by default */
position: absolute /* You will position it relatively to its parent hasDropdown */
top: 20px;
left: 0;
display: flex;
align-items: flex-start;
}
.dropdownTrigger:hover .dropdown {
visibility: visible;
}
As you can see in the dropdown container I have added the properties display: flex; and align-items: flex-start;, so all the children inside .dropdown will be aligned to the left, as said before. The property align-items will work only if display: flex; has been set.

Positioning a circle underneath text in CSS

I'm trying to position a 5px x 5px circle in the centre of the underneath of the links in a nav to indicate which page the user is currently on, but I'm not sure how I should be going about this.
Currently I have this: Image
I am trying to do this:
Image
This is the code:
<ul id="nav-menu">
<li class="nav-menu-item">
Our work
</li>
<li class="nav-menu-item">
What we do
</li>
<li class="nav-menu-item">
Blog
</li>
<li class="nav-menu-item">
Contact
</li>
</ul>
nav {
height: 70px;
background: #fff;
display: flex;
align-items: center;
padding: 0 75px;
}
#nav-logo-link {
flex: 1;
}
#nav-logo {
height: 35px;
}
#nav-menu {
list-style: none;
padding: 0;
white-space: nowrap;
}
#nav-menu > li {
display: inline;
margin: 0 10px;
}
#nav-menu > li > a {
text-decoration: none;
color: #000;
}
I have tried putting an <i> element within the <li> and then positioning it as absolute, and whilst I can put it down at the correct height (since the nav height is static), when I set it as left: 0;, it jumps to the left hand side of the entire nav. I tried putting a <div> within the <li> but that didn't do anything.
Any ideas?
You can use an after pseudo element to do this along with a UTF8 character, see the following fiddle.
Edit: I'm assuming you want this to happen when the user clicks a link and is then on that page hence why I've used a data attribute, the previous answer does it on hover.
I've made three amendments to your code here:
Added position: relative; to your anchors, this allows me to use position: absolute in the next css block:
nav-menu > li > a {
text-decoration: none;
color: #000;
position: relative;
}
Added the pseudo element absolutely positioned at 50% of the anchor width, I've also set it's width and then centred it within that by using a negative margin of half its width. This relies on you setting the selected item with a little bit of javascript, see point 3. You may want to adjust the colour:
nav-menu > li > a[data-selected=true]:after {
content: "\25CF";
position: absolute;
top: 1.1em;
left: 50%;
width: 10px;
margin-left: -5px;
color: cadetblue;
}
Added a data-selected="true" attribute to the selected anchor, you need to do this in javascript as a different anchor is selected. This allows the css in step 2 to select the right anchor.
This can be done by adding a nav-menu-item:after{ rule which adds a circle after the <li> tag then set the display for the #nav-menu > li { to inline-block and you should get the desired result on hover
nav {
height: 70px;
background: #fff;
display: flex;
align-items: center;
padding: 0 75px;
}
#nav-logo-link {
flex: 1;
}
#nav-logo {
height: 35px;
}
#nav-menu {
list-style: none;
padding: 0;
white-space: nowrap;
}
#nav-menu > li {
display: inline-block;
margin: 0 10px;
}
#nav-menu > li > a {
text-decoration: none;
color: #000;
}
.nav-menu-item:hover:after {
content: "\25CF";
display: block;
opacity: 1;
margin-left: auto;
margin-right: auto;
}
.nav-menu-item::after {
content: "\25CF";
opacity: 0;
color: #1ba9b3;
display: block;
margin-left: auto;
margin-right: auto;
width: 5px;
height: 5px;
}
<nav>
<ul id="nav-menu">
<li class="nav-menu-item">
Our work
</li>
<li class="nav-menu-item">
What we do
</li>
<li class="nav-menu-item">
Blog
</li>
<li class="nav-menu-item">
Contact
</li>
</ul>
</nav>
If you want to show the dot when selected you can use javascript to set the class to be <li class="nav-menu-item selected"> then in css you would change .nav-menu-item:hover:after { to .nav-menu-item.selected:after {
Hope this helps!

Horizontal navbar with float:left;none;right items

I want a horizontal navbar with 3 items: one left, one center, and one right. But I cannot seem to get float: to work for me. The attached picture shows how the items do not line up horizontally. I want the centered item to really be a page title, not a link.
The clear: I have used seems to at least center the middle item, but without the clear: there is no symmetry. How can I get all 3 items to be positioned horizontally?
<ul>
<li style="float:left">Home</li>
<li style="clear:both;float:none">News</li>
<li style="float:right"><a class="active" href="#about">About</a></li>
</ul>
Flexbox does this pretty simply.
Assuming your markup:
<ul>
<li>Home</li>
<li>News</li>
<li><a class="active" href="#about">About</a></li>
</ul>
The css will then be:
ul {
display: flex;
justify-content: space-between;
align-items: center;
}
Do remember to add the necessary vendor prefixes for cross-browser compatibility.
You're close! You just need to set text-align: center; on the parent to center the middle element, then float the first element left and last one right.
ul {
text-align: center;
padding: 0;
}
li {
display: inline-block;
}
li:nth-child(1) {
float: left;
}
li:nth-child(3) {
float: right;
}
<ul>
<li>Home</li><li>News</li><li><a class="active" href="#about">About</a></li>
</ul>
You can also have them all take up the same amount of space and use text-align to position the text left/right/center.
ul { padding: 0; }
li {
width: 33.33%;
display: inline-block;
text-align: center;
}
li:nth-child(1) {
text-align: left;
}
li:nth-child(3) {
text-align: right;
}
<ul>
<li>Home</li><li>News</li><li><a class="active" href="#about">About</a></li>
</ul>
In this issue, you should read this blog to figure out how to make element horizontal in correct.
In your case, there has servals way to achieve it, I will put them on this answer.
ul {
padding: 0;
}
li {
list-style: none;
}
.first li {
float: left;
width: 50px;
}
.first .news {
width: 100%;
text-align: center;
margin-left: -50px;
margin-right: -50px;
}
.first li + li + li {
float: right;
}
.second li {
display: inline-block;
float: left;
width: 33%;
}
.second .news {
text-align: center;
}
.second li + li + li {
text-align: right;
width: 34%;
}
.third {
position: relative;
}
.third li {
position: absolute;
}
.third .news {
width: 100%;
text-align: center;
}
.third li + li + li {
position: absolute;
right: 0;
top: 0;
}
<h4>1.The key is 'margin-left' nagative value to expand space to text center is right.</h4>
<ul class="first">
<li>home</li>
<li class="news">news</li>
<li>about</li>
</ul>
<br>
<h4>2.The key is make 'li' elements have average width and use text align to achieve it, but there is 1% error, but it's too tiny on sight</h4>
<ul class="second">
<li>home</li>
<li class="news">news</li>
<li>about</li>
</ul>
<h4>3. This situation is easy to understand.</h4>
<ul class="third">
<li>home</li>
<li class="news">news</li>
<li>about</li>
</ul>
Try displaying the li inline
<li style="display:inline">

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>