How to align a dropdown in CSS - html

I am making a website and I want to make a drop-down list but I have a trouble.
I want to do something like this:
Option A Option B Option C Option D Option E
and a dropdown list to B with 4 options but when I do it, it looks like that:
Option A Option B
.....................Option 1
.....................Option 2
.....................Option 3
.....................Option 4
...........................................Option C Option D Option E
this is my code:
.option {
display: inline-block;
}
.option>li {
display: inline;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<nav>
<ul>
<div class="option">
<li>Home</li>
<li>Services
<ul>
<li>3D
<li>2D
<li>Websites
<li>IT help
</ul>
</li>
</div>
<div class="option">
<li>Gallery
<li>Contact
<li>About Me
</div>
</ul>
</nav>
</body>
</html>
</nav>

Restructure your HTML
Close your li tags. Make sure you are closing them properly like
this:
<li>Home</li>
Nest all of the top level menu items (Home, Services, Gallery, Contact, About Me) in a single ul
Your HTML should look something like this
<nav>
<ul>
<li>Home</li>
<li>Services
<ul>
<li>3D</li>
<li>2D</li>
<li>Websites</li>
<li>IT help</li>
</ul>
</li>
<li>Gallery</li>
<li>Contact</li>
<li>About Me</li>
</ul>
</nav>
Add style
Add a class to the Services li to indicate that it is a dropdown. I am calling mine dropdown
Remove those pesky dots on each list item using list-style: none; padding: 0;
To arrange the top level ul horizontally, make it a flexbox by applying display: flex; on the ul. I would also add flex-wrap: none; to make sure the list does not try to wrap its elements on small screens.
I recommend giving each element of the flexbox a constant width and aligning the text how you like like. I used width: 80px; text-align: center;
Lastly, hide the elements of your dropdown by setting the inner ul's display to none. And show the dropdown by setting display to block. I did this using the class open
ul {
list-style: none;
padding: 0;
}
nav > ul {
display: flex;
flex-wrap: none;
}
nav > ul > li {
width: 80px;
text-align: center;
}
nav > ul > li.dropdown > ul > * {
display: none;
}
nav > ul > li.dropdown.open > ul > * {
display: block;
}
<nav>
<ul>
<li>Home</li>
<li class="dropdown">Services
<ul>
<li>3D</li>
<li>2D</li>
<li>Websites</li>
<li>IT help</li>
</ul>
</li>
<li>Gallery</li>
<li>Contact</li>
<li>About Me</li>
</ul>
</nav>
Add interaction
Now if you want to actually make the submenu expand, I recommend using JavaScript. In the code snippet above, all you need to do is toggle the class open on any li with the dropdown class.
There are infinite possibilities, but a good place to start is this W3 Schools tutorial on building clickable dropdown menus. Be mindful of accessibility features as well by reading this W3 tutorial on building accessible flyout menues.
Here is a tutorial on building a CSS only accessible dropdown menu; although I recommend sticking to JS solutions, because they are more versatile.
Rudimentary example using JS
const dropdownMenuItems = document.querySelectorAll("li.dropdown");
const toggleDropdown = (e, el) => {
if (e.target.classList.contains("dropdown-control")) {
el.classList.toggle("open");
}
};
dropdownMenuItems.forEach((el) => {
el.addEventListener("click", (e) => toggleDropdown(e, el));
});
ul {
list-style: none;
padding: 0;
}
nav > ul {
display: flex;
flex-wrap: none;
}
nav > ul > li {
width: 80px;
text-align: center;
}
nav > ul > li.dropdown > ul > * {
display: none;
}
nav > ul > li.dropdown.open > ul > * {
display: block;
}
<nav>
<ul>
<li>Home</li>
<li class="dropdown">Services
<ul>
<li>3D</li>
<li>2D</li>
<li>Websites</li>
<li>IT help</li>
</ul>
</li>
<li>Gallery</li>
<li>Contact</li>
<li>About Me</li>
</ul>
</nav>
Closing thoughts
I kept the styling really barebones. You can of course style however you like. It seems like you are mostly asking about how to get the arrangement right.
It probably makes sense to change the Services a tag to a button if it does not behave like a link. This is important for screen readers to know how to treat that element.

Here's how I would do it: It's a little bare, but it works. I would make each li have the class of option and get rid of the divs so that it is more consistent and simpler. Also, you were missing all of your closing li tags, which messed some things up. I also added a simple :hover mechanism so that it will hide and show when you hover over it.
.option {
display: inline-block;
vertical-align: top;
width: 75px;
margin: 0;
padding: 0;
}
.dropdown {
display: none;
padding: 0;
list-style-type: none;
}
.contains-dropdown:hover > .dropdown{
display: block
}
option>li {
display: inline;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<nav>
<ul>
<li class="option">Home</li>
<li class="option contains-dropdown">
Services
<ul class="dropdown">
<li>3D</li>
<li>2D</li>
<li>Websites</li>
<li>IT help</li>
</ul>
</li>
<li class="option">Gallery</li>
<li class="option">Contact</li>
<li class="option">About Me</li>
</ul>
</nav>
</body>
</html>
</nav>

Related

Hovering on menu shows the list of dropdown menu in every menus

I'm a beginner in web developing, when I hover my mouse to the list of my menus the dropdown menu keeps on showing in every menu. What seems to be the problem?
I tried removing the so I can use "ul li ul li" directly in css but it doesn't work and also when I try ".site-header nav ul li:hover .sub-menu-about" there is no output but ".site-header nav ul:hover .sub-menu-about" I've got the same problem even when I use ".site-header ul:hover .sub-menu-about" still the same problem.
Here is my CSS code
.sub-menu-about{
display: none;
}
.site-header ul:hover .sub-menu-about {
display: block;
margin-top: 15px;
margin-left: -15px;
position: absolute;
}
.main-navigation ul:hover .sub-menu-about ul{
display: block;
margin: 10px;
}
and this is my html code
<div class="site-header__menu group">
<nav class="main-navigation">
<ul>
<li>Home</li>
<li>About</li>
<div class="sub-menu-about">
<ul>
<li><a href="#">History</li>
<li><a href="#">Vision</li>
<li><a href="#">Mission</li>
</ul>
</div>
<li>News</li>
<li>Events</li>
</ul>
</nav>
</div>
Once I hover on the about menu, a dropdown list of History, Mission, Vision will be shown. and when I hover on different menus there will be no dropdown menu will be shown
Error No. 1: The submenu should be located inside the <li> tag. Corrected
Error No. 2:
First, you hide the class .sub-menu-about through displays: none, and then you try to show not this class itself, but a list inside it. Corrected
Result
.sub-menu-about {
display: none;
}
.site-header ul:hover .sub-menu-about {
display: block;
margin-top: 15px;
margin-left: -15px;
position: absolute;
}
.main-navigation li:hover .sub-menu-about {
display: block;
margin: 10px;
}
<div class="site-header__menu group">
<nav class="main-navigation">
<ul>
<li>Home</li>
<li>About
<div class="sub-menu-about">
<ul>
<li><a href="#">History</li>
<li><a href="#">Vision</li>
<li><a href="#">Mission</li>
</ul>
</div>
</li>
<li>News</li>
<li>Events</li>
</ul>
</nav>
</div>

display flex creating extra space why

My understanding of flexbox, is that if you display a element as flex, that item become flex container and it direct children will become flex items and these flex items behave as inline block items,
so i am following this logic, and it was working fine, untill i added the last in my css, please read the comment i left the comment in my css code, which line is confusing me.
in short i was expecting similiar outcome, but i am confuse about the space, please see the image to understand as well,
HTML CODE
<ul class="menu">
<li>Home</li>
<li>About</li>
<li class="menu-item-has-children">Services
<ul class="sub-menu">
<li>Plumbing</li>
<li class="menu-item-has-children">Heating
<ul class="sub-menu">
<li>Residential</li>
<li>Commercial</li>
<li>Industrial</li>
</ul>
</li>
<li>Electrical</li>
</ul>
</li>
<li>Pricing</li>
<li>Contact Us</li>
</ul>
CSS CODE
/*basic style no need to pay attention*/
*{font-family:helvetica;
margin:0px;padding:0;
list-style-type:none;
}
ul{margin:5px;}
ul ul a:link{color:red;}
ul ul ul a:link{color:black}
/*displaying them as flex, work fine*/
.menu{display:flex;}
.menu li {flex:1;}
.menu li a {
display:block;
min-width:100%
}
/*this line is confusing to me*/
ul ul li{
display:flex;
}
First image
Second image
By default, flex organizes elements in rows, from left to right. In your case, that means that the two elements inside <li class="menu-item-has-children"> (the link and the sub-menu) will be positioned side by side.
You have to add flex-direction: column to fix your issue:
* {
font-family: helvetica;
margin: 0px;
padding: 0;
list-style-type: none;
}
ul {
margin: 5px;
}
ul ul a:link {
color: red;
}
ul ul ul a:link {
color: black
}
.menu {
display: flex;
}
.menu li {
flex: 1;
}
.menu li a {
display: block;
}
ul ul li {
display: flex;
flex-direction: column; /* <- specify the flex direction here */
}
<ul class="menu">
<li>Home</li>
<li>About</li>
<li class="menu-item-has-children">Services
<ul class="sub-menu">
<li>Plumbing</li>
<li class="menu-item-has-children">Heating
<ul class="sub-menu">
<li>Residential</li>
<li>Commercial</li>
<li>Industrial</li>
</ul>
</li>
<li>Electrical</li>
</ul>
</li>
<li>Pricing</li>
<li>Contact Us</li>
</ul>
The fact that your sub-menu appears to be outside your flex container is caused by the min-width: 100% setting on your .menu li a elements.

Not able to apply display property on li element

i am a newbie to CSS,HTML and trying to understand lists.however something confuses me .As you can see below my HTML i am trying to create a drop down navigation bar.what i don't understand is why would display property won't work on a single li element.
.block1{background-color:#736570;margin:0px;}
ul a {color:white;}
ul li{list-style-type: none; padding:5px;}
.hidden {display:none;}
.home:hover .hidden{display:block;}
.hidden a:hover{background-color: #f1f1f1;}
<body>
<ul class="block1">
<li class="home">Home
<li class="hidden">
contact us
</li>
<li>about<li>
<li>Investor</li>
<li> what we do</li>
</li>
</ul>
</body>
Here is the new css you should use:
.block1{background-color:#736570;margin:0px;}
ul a {color:white;}
ul li{list-style-type: none; padding:5px;}
.hidden{display:none;}
.home:hover + .hidden{display:block;}
li:hover{background-color: #f1f1f1;}
Then your html should look like this:
<body>
<ul class="block1">
<li class="home">Home</li>
<li class="hidden" >
contact us
</li>
<li>about</li>
<li>Investor</li>
<li> what we do</li>
</ul>
</body>
Nothing too wrong with your html, just a mismatch <li>, and the css you want to look at this post: Using only CSS, show div on hover over <a>
Here is the JSFiddle: Example of OP Code
i don't understand is why would display property won't work on a
single li element.
The div with class .home is not the parent of li tag with class hidden. Hence it will never trigger a hover over that. Whenever you trigger a hover over a parent container it trickles down and find its children and does some sort of styling.
In your case, you are trying to use display:none to hide a li and make it display by means of hover.
Consider the snippet below, whenever you hover over the parent container, the li tag is being displayed. (This approach below does not make a drop down menu for you but it is give you some insight how to make that display property change on hover)
.block1 {
background-color: #736570;
margin: 0px;
}
ul a {
color: white;
}
ul li {
list-style-type: none;
padding: 5px;
}
.hidden {
display: none;
}
.block1:hover .hidden {
display: block;
}
.hidden a:hover {
background-color: #f1f1f1;
}
.home
<html>
<body>
<ul class="block1">
<li class="home">Home
<li class="hidden">
contact us
</li>
<li>about
<li>
<li>Investor</li>
<li> what we do</li>
</li>
</ul>
</body>
</html>

how to display a list inline using HTML and CSS [duplicate]

This question already has answers here:
How to make a <ul> display in a horizontal row
(9 answers)
Closed 1 year ago.
I am trying to create a menu using html, I have added my link in an unordered list (ul) has shown below. In my css i added a display:inline; to the links so that they would display in a link like a menu but for some reason it doesn't seem to work.
#menu a {
text-decoration: none;
}
#menu ul {
list-style: none;
}
#menu ul li a {
display: inline;
}
<div id="menu">
<ul>
<li>Home
</li>
<li>About Us
</li>
<li>Special Offers
</li>
<li>Meet Our Staff
</li>
<li>Contact
</li>
</ul>
</div>
You are targeting the anchors, which are already inline by default. I believe you mean to target the list items:
#menu ul li {
display: inline;
}
JSFiddle
You were very close!
The only thing wrong with your code, is that display: inline; should be on your <li> elements instead of your <a> elements :
#menu a {
text-decoration: none;
}
#menu ul {
list-style: none;
}
#menu ul li {
display: inline;
}
<div id="menu">
<ul>
<li>Home
</li>
<li>About Us
</li>
<li>Special Offers
</li>
<li>Meet Our Staff
</li>
<li>Contact
</li>
</ul>
</div>
(see also this Fiddle)
Try this: ul li { float: left; padding-right:10px; }
https://jsfiddle.net/n4aak3nk/1/

h3 and list dropdown menu CSS3

got an html list working as a dropdown menu with CSS when you hover through a < li > element like "Products" in my example. But what I want is the same effect when hover through < h3 > like "Contact" from my example. Is it possible?
Here's the html:
<h3>Contact</h3>
<ul>
<li>Home</li>
<li>About</li>
<li>
Products ▾
<ul>
<li>Laptops</li>
<li>Monitors</li>
<li>Printers</li>
</ul>
</li>
<li>Contact</li>
</ul>
And the CSS code:
ul li ul {
display: none;
}
ul li:hover ul{
display: block; /* display the dropdown */
}
Thank you very much in advance.
On hover you can only control the CSS of the element you hover over, or the CSS of elements within the element you hover over (one of its children).
So you can not make the ul change styles when you hover over the h3 because they 1) are not the same object and 2) do not have a parent-child relationship (they are siblings).
To show the menu when hovering over the h3, you can wrap both of them inside another object (div) and use this for the hover event. To distinguish between the two hovers you can add classnames to both the uls.
See this JSfiddle, or the code below:
<div class="container">
<h3>Contact</h3>
<ul class="menu">
<li>Home</li>
<li>About</li>
<li>
Products ▾
<ul class="submenu">
<li>Laptops</li>
<li>Monitors</li>
<li>Printers</li>
</ul>
</li>
<li>Contact</li>
</ul>
</div>
.container ul{
display: none;
}
.container:hover ul.menu{
display: block;
}
ul li ul.submenu {
display: none;
}
ul li:hover ul{
display: block; /* display the dropdown */
}
In short - you should nest ul inside the h3
<h3>
Contact
<ul>
<li>Home</li>
<li>About</li>
<li>
Products ▾
<ul>
<li>Laptops</li>
<li>Monitors</li>
<li>Printers</li>
</ul>
</li>
<li>Contact</li>
</ul>
</h3>
And in your css:
ul li ul {
display: none;
}
ul li:hover ul{
display: block; /* display the dropdown */
}
h3 > ul {
display: none;
}
h3:hover > ul {
display: block;
}
Here's the demo: https://jsfiddle.net/mscehjLf/1/