I have the HTML structure below for a menu,
I try to keep the color of the background div when the user navigates in the sub list
any ideas ?
ThankYou.
.color1 > div:hover {
background-color: yellow;
}
.sub{
display: none;
}
.globalList:hover .sub {
display: block !important;
}
<html>
<body>
<ul class="MyList">
<li class="globalList color1">
<div>Menu1</div>
<ul class="sub">
<li class="Sub1"><div>Sublist1</div></li>
<li class="Sub2"><div>Sublist2</div></li>
</ul>
</li>
<li>
<div>Menu2</div>
<ul>
<li></li>
<li></li>
</ul>
</li>
</ul>
</body>
</html>
Have the hover style on the li tag instead
.color1:hover > div {
background-color: yellow;
}
Unless you also wanted the submenu to have the bg color, in that case move it inside your div
Something like this?
.color1 > div:hover {
background-color: yellow;
}
.sub{
display: none;
}
.globalList:hover .sub {
display: block !important;
}
<html>
<body>
<ul class="MyList">
<li class="globalList color1">
<div>Menu1
<ul class="sub">
<li class="Sub1"><div>Sublist1</div></li>
<li class="Sub2"><div>Sublist2</div></li>
</ul>
<!-- MOVE </> DIV OVER HERE! -->
</div>
</li>
<li>
<div>Menu2</div>
<ul>
<li></li>
<li></li>
</ul>
</li>
</ul>
</body>
</html>
Related
js
const navItems = document.querySelectorAll('.navbar__items')
const dropDown = document.querySelectorAll('.dropdown')
dropDown.forEach(element => {
element.addEventListener('click',()=>{
{
navItems.forEach(nav =>{
nav.classList.toggle('drop')
})
}
})
})
HTML
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
</ul>
CSS
.navbar{
position: relative;
}
.navbar__items{
position: absolute;
display: none;
}
.drop{
display: block;
}
I have a navbar and each of these navbar items have dropdown items. I want to show these dropdown items when I click on the 'dropdown' class. But the problem is when I click on one of them all the dropdowns are visible. How do I show only the list I've clicked on?
Enter the below code
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.dropbtn {
background-color: #3498DB;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #2980B9;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {background-color: #ddd;}
.show {display: block;}
</style>
</head>
<body>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Click</button>
<div id="myDropdown" class="dropdown-content">
Clicked
Clicked
Clicked
</div>
</div>
<script>
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
</script>
</body>
</html>
As mentioned in comments it is better to use Event Delegation technique.
The algorithm is quite simple:
Add listener on the parent element
On click check if dropdown-opener was clicked
Get drop-down which I need to open
Close other dropdowns
Open dropdown from 3.
const allDropdowns = document.querySelectorAll('.navbar__items')
const DROP_CLASS = 'drop';
const navbar = document.querySelector('.navbar');
navbar.addEventListener('click', ({target}) => {
if (!target.classList.contains('dropdown')) return;
const parent = target.parentNode;
const navItems = parent
.querySelector('.navbar__items');
allDropdowns.forEach(el => el !== navItems && el.classList.remove(DROP_CLASS));
if (navItems) {
navItems.classList.toggle(DROP_CLASS);
}
});
.navbar{
position: relative;
}
.navbar__items{
position: absolute;
left: 80px;
display: none;
}
.drop{
display: block;
}
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
</ul>
Use the event target to get the parentNode, then use the parentNode to query the hidden element as all your elements are grouped in the same parent/child grouping. Also you can set an initial class for hidden, display: none; in each element and add it on click. A forEach loop sets each elements display to none using the hidden class on click.
const navItems = document.querySelectorAll('.navbar__items')
const dropDown = document.querySelectorAll('.dropdown')
// callback function that passes in the event => e from your listener
function showDropdown (e){
// set each navbar__items element display: none using hidden class
navItems.forEach(el => el.classList.add('hidden'))
// query the specific .navbar__items in the event.targets group
let dd = e.target.parentNode.querySelector('.navbar__items')
// remove the hidden class a nd show the dropdown for this event.target
dd.classList.remove('hidden')
}
// iterate over the dropdown element
dropDown.forEach(element => {
// function showDropdown on click
element.addEventListener('click', showDropdown)
})
.navbar {
position: relative;
}
.navbar__items {
position: absolute;
left: 75px;
}
.hidden {
display: none;
}
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items hidden">
<li>clicked 1</li>
<li>clicked 1</li>
<li>clicked 1</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items hidden">
<li>clicked 2</li>
<li>clicked 2</li>
<li>clicked 2</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items hidden">
<li>clicked 3</li>
<li>clicked 3</li>
<li>clicked 3</li>
</ul>
</li>
</ul>
Rather than using addEventlistener you should add onclick method in html to every drop-down with same method name but change the ul class name with for each drop-down and then pass class name in method and then toggle the drop-down with parameter class name.
For example,
function onClick(item) {
if (document.getElementsByClassName(item).classList.contains('hidden')) {
document.getElementsByClassName('dropdown').classList.remove('hidden');
}
if (!document.getElementsByClassName(item)[0].classList.contains('hidden')) {
document.getElementsByClassName('dropdown').classList.add('hidden');
}
}
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown" onclick="onClick('navbar_items1')">click</div>
<ul class="navbar__items1 hidden">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown" onclick="onClick('navbar_items2')">click</div>
<ul class="navbar__items2 hidden">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown" onclick="onClick('navbar_items3')">click</div>
<ul class="navbar__items3 hidden">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
</ul>
Perhaps this is an easy matter, but I still couldn't find a solution. I tried following example from internet using menu arrow on drop-down. The problem is that all the sub-menus go down to the bottom (show), while should only show clicked menu's submenu.
<html>
<head>
<script type="text/javascript" src="jquery-1.9.1.min.js"></script>
<style>
.sub-menu ul > li {
z-index:-1;
opacity:0;
display:none;
}
.drop {
display: inline-block;
transition: all .25s
}
.slicknav_nav.active li > .drop {
transform: rotate(180deg)
}
.slicknav_nav.active li > .sub-menu > ul > li{
z-index:1;
opacity:1;
display:block;
}
</style>
</head>
<body>
<div class="slicknav_menu">
<ul class="slicknav_nav">
<li>
Movies
<a class="drop">▼</a>
<div class="sub-menu">
<ul>
<li>In Cinemas Now</li>
<li>Coming Soon</li>
<li>On DVD/Blu-ray</li>
<li>Showtimes & Tickets</li>
</ul>
</div>
</li>
<li>
Movies2
<a class="drop">▼</a>
<div class="sub-menu">
<ul>
<li>In Cinemas Now</li>
<li>Coming Soon</li>
<li>On DVD/Blu-ray</li>
<li>Showtimes & Tickets</li>
</ul>
</div>
</li>
</ul>
</div>
<script>
$(".slicknav_nav").click(function() {
$(this).hasClass("active") ?
$(".slicknav_nav").removeClass("active") :
($(".slicknav_nav").removeClass("active"), $(this).addClass("active"));
});
</script>
</body>
</html>
Can some one solve the problem? I hope it does not change the structure.
You have couple of issues in your code:
Add click handler on li instead of ul.
Toggle active class on li.
In click handler, remove active class from all lis, then just add to current li.
Updated Code:
$(".slicknav_nav li").click(function() {
$(".slicknav_nav li").removeClass('active');
$(this).addClass('active');
});
.sub-menu {
z-index: -1;
opacity: 0;
display: none;
}
.drop {
display: inline-block;
transition: all .25s;
}
.slicknav_nav li.active > .drop {
transform: rotate(180deg);
}
.slicknav_nav li.active > .sub-menu {
z-index: 1;
opacity: 1;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="slicknav_menu">
<ul class="slicknav_nav">
<li>
Movies<a class="drop">▼</a>
<div class="sub-menu">
<ul>
<li>In Cinemas Now</li>
<li>Coming Soon</li>
<li>On DVD/Blu-ray</li>
<li>Showtimes & Tickets</li>
</ul>
</div>
</li>
<li>
Movies2<a class="drop">▼</a>
<div class="sub-menu">
<ul>
<li>In Cinemas Now</li>
<li>Coming Soon</li>
<li>On DVD/Blu-ray</li>
<li>Showtimes & Tickets</li>
</ul>
</div>
</li>
</ul>
</div>
Fiddle DEMO
I have a css menu I would like to make accessible through keyboard interaction. I want to be able to tab through each link including sub menu links.
If the dropdown focus moves on to the next parent link dropdown then the previous dropdown should hide.
Updated Fiddle
HTML
<ul>
<li class="custom-MainMenu-TopNav-li">
<div>
<span>Parent link 1</span>
<div>
<ul class="custom-MainMenu-SubNav-dropdown">
<li>Sub Link</li>
<li>Sub Link</li>
</ul>
</div>
</div>
</li>
<li class="custom-MainMenu-TopNav-li">
<div>
<span>Parent link 2</span>
<div>
<ul class="custom-MainMenu-SubNav-dropdown">
<li>Sub Link</li>
<li>Sub Link</li>
</ul>
</div>
</div>
</li>
</ul>
JavaScript
accessibleDropdown();
function accessibleDropdown(){
jQuery('.custom-MainMenu-TopNav-li a').each(function(){
jQuery(this).focus(function(){
jQuery(this).addClass('focused');
var menuParent = jQuery(this).parent().next().find('ul');
jQuery(menuParent).css('display','block');
});
jQuery(this).blur(function(){
jQuery(this).removeClass('focused');
});
});
}
I am not sure what is your desired outcome and need for this result, but hopefully this will help you out.
I had to redo your example due to naming convention and approach, but I assume this is what you wanted...
Here's a demo, just in case...
JSFiddle
HTML
<ul class="navbar">
<li class="navbar-item">
Parent Link
<ul class="navbar-sub">
<li class="navbar-sub-item">
One
</li>
<li class="navbar-sub-item">
Two
</li>
<li class="navbar-sub-item">
Three
</li>
</ul>
</li>
<li class="navbar-item">
Parent Link
<ul class="navbar-sub">
<li class="navbar-sub-item">
One
</li>
<li class="navbar-sub-item">
Two
</li>
<li class="navbar-sub-item">
Three
</li>
</ul>
</li>
<li class="navbar-item">
Parent Link
<ul class="navbar-sub">
<li class="navbar-sub-item">
One
</li>
<li class="navbar-sub-item">
Two
</li>
<li class="navbar-sub-item">
Three
</li>
</ul>
</li>
<li class="navbar-item">
Parent Link
<ul class="navbar-sub">
<li class="navbar-sub-item">
One
</li>
<li class="navbar-sub-item">
Two
</li>
<li class="navbar-sub-item">
Three
</li>
</ul>
</li>
</ul>
CSS
body {
margin: 10px;
}
.navbar,
.navbar .navbar-sub {
list-style: none;
margin: 0;
padding: 0;
}
.navbar > .navbar-item {
float: left;
}
.navbar > .navbar-item:last-child {
margin-right: 0;
}
.navbar > .navbar-item.active > .navbar-sub {
display: block;
}
.navbar > .navbar-item a {
text-decoration: none;
}
.navbar > .navbar-item > a {
background-color: #999;
padding: 10px 20px;
color: #696969;
display: block;
}
.navbar > .navbar-item > a:hover,
.navbar > .navbar-item > a:focus,
.navbar > .navbar-item.active > a {
background-color: #ccc;
}
.navbar .navbar-sub {
display: none;
}
.navbar .navbar-sub > .navbar-sub-item > a {
color: #ccc;
display: block;
padding: 5px 10px;
text-align: center;
background-color: #696969;
}
.navbar .navbar-item.active .navbar-sub-item > a:hover,
.navbar .navbar-item.active .navbar-sub-item > a:focus {
background-color: #999;
}
jQuery
$('.navbar').on('mouseenter focusin', '.navbar-item > a', function () {
$(this)
.parent('.navbar-item')
.addClass('active')
.siblings('.navbar-item')
.removeClass('active')
});
here you go, simple jquery :)
// display drop down box when mouse is over
$(".custom-MainMenu-TopNav-li a").mouseover(function(){
$(this).find(".custom-MainMenu-SubNav-dropdown").css("display", "block");
});
// hide drop down box when mouse leaves
$(".custom-MainMenu-TopNav-li a").mouseleave(function(){
$(this).find(".custom-MainMenu-SubNav-dropdown").css("display", "none");
});
This basically displays/hide each the dropdown when the mouse is over/leaves the parent div.
I don't think it would be a good idea to display the dropbown menu on focus, cause i believe you can only focus on certain elements like inputs.
Hope this helps!
Here's what I'm trying to make:
Click on "PORTFOLIO";
Pushes everything down smoothly;
New links fade-in smoothly;
Click on "PORTFOLIO" again, do everything in reverse;
My current code;
$(function () {
$('[data-toggle]').on('click', function () {
var id = $(this).data("toggle"),
$object = $(id),
className = "open";
if ($object) {
if ($object.hasClass(className)) {
$object.removeClass(className)
} else {
$object.addClass(className)
}
}
});
});
#list {
display: none;
}
#list.open {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<ul>
<li>Home </li>
<li>A Empresa </li>
<li>Portfolio
<ul id="list">
<li>Comerciais </li>
<li>Residenciais </li>
<li>Institucionais </li>
<li>Edifícios </li>
</ul>
</li>
<li>Contato </li>
</ul>
</nav>
It's possible to accomplish this without JS, only with CSS? I have no clue whatsoever how to do the animation part, I tried CSS Transitions propriety, but didn't work.
Also, any tips for the markup and JS? I don't thinks I'm doing it the "right way"... any tips would be appreciated.
With only CSS you may use :focus and eventually pointer-events if you want a toggle effect :
#list {
max-height: 0;
overflow: hidden;
transition: 0.5s linear;
}
a:focus+#list {
max-height: 15em;
}
/* only select that link , here using the href attribute */
a[href="nowhere"]:focus {
pointer-events: none;
}
<nav>
<ul>
<li>Home </li>
<li>A Empresa </li>
<li>Portfolio
<ul id="list">
<li>Comerciais </li>
<li>Residenciais </li>
<li>Institucionais </li>
<li>Edifícios </li>
</ul>
</li>
<li>Contato </li>
</ul>
</nav>
You can even do this very little CSS without class nor id :
ul a +ul {
max-height:0;
overflow:hidden;
transition:0.5s linear;
}
ul a:focus + ul {
max-height:15em;
}
/* only select that link , here using the href attribute */
a[href="nowhere"]:focus {
pointer-events: none;
}
<nav>
<ul>
<li>Home
<ul>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
</li>
<li>A Empresa
<ul>
<li>item</li>
<li>item</li>
</ul>
</li>
<li><a href="#nowhere" >Portfolio</a>
<ul>
<li>Comerciais </li>
<li>Residenciais </li>
<li>Institucionais </li>
<li>Edifícios </li>
</ul>
</li>
<li>Contato
<ul>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
</li>
</ul>
</nav>
I have created the menu only using css please check the following fiddle https://jsfiddle.net/dwgpqncw/2/ also the code for the same is posted below
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>css menu</title>
<style>
*{margin:0; padding:0;}
ul{font-family:Arial, Helvetica, sans-serif;}
ul li ul{height:0px; transition:500ms all;-webkit-transition:500ms all;-moz-transition:500ms all;-o-transition:500ms all;overflow:hidden;}
ul li ul li{ transition:1300ms all;-webkit-transition:1300ms all;-moz-transition:1300ms all;-o-transition:1300ms all;opacity:0}
a{color:#000; text-transform:uppercase;}
ul li ul li a{color:red;}
/*set the height to 0 and on focus set the height to pixels calculation based on the line height*/
ul li .expandable +ul:nth-child(1),ul li .expandable +ul:nth-child(1),ul li .expandable +ul:nth-child(1),ul li .expandable +ul:nth-child(1){height:0px;overflow:hidden;}
ul li ul li{line-height:30px;font-size:16px;}
ul li .expandable{font-size:20px; line-height:35px; text-decoration:none; padding-left:20px; }
ul li .expandable:hover{text-decoration:underline;}
ul li ul li:before{padding-left:20px; content:"-"; font-size:16px; margin-left:20px}
ul li .expandable:focus{color:red;}
ul li .expandable:focus +ul:nth-child(1){height:90px;}
ul li .expandable:focus +ul:nth-child(2){height:120px;}
ul li .expandable:focus +ul:nth-child(3){height:60px;}
ul li .expandable:focus +ul:nth-child(4){height:120px;}
ul li .expandable:focus +ul:nth-child(1) li,ul li .expandable:focus +ul:nth-child(2) li,ul li .expandable:focus +ul:nth-child(3) li,ul li .expandable:focus +ul:nth-child(4) li{opacity:1;}
</style>
</head>
<body>
<ul>
<li>
Home
<ul>
<li>Home link 1</li>
<li>Home link 2</li>
<li>Home link 3 </li>
</ul>
</li>
<li>
A Empressa
<ul>
<li>Empressa link 1</li>
<li>Empressa link 2</li>
<li>Empressa link 3 </li>
<li>Empressa link 4 </li>
</ul>
</li>
<li>
Protfolio
<ul>
<li>Protfolio link 1</li>
<li>Protfolio link 2</li>
</ul>
</li>
<li>
Contato
<ul>
<li>Contato link 1</li>
<li>Contato link 2</li>
<li>Contato link 3 </li>
<li>Contato link 4 </li>
</ul>
</li>
</ul>
</body>
</html>
I have a project that requires me to add drop-down navigation. I am using GUMBY and have added the drop-downs.
The problem I am having is as you rollover each main navigation link- the sub-links drop-down but once you mouse over the sub-links - the main navigation color switches back. I've tried to stylize a mouse out event but that doesn't work.
How can I keep the main nav link the same color when you mouseover the sub-links?
http://ffresearch.com/who-we-are-dropdown.html
<style type="text/css">
#nav-orange li a:hover, #nav-orange li:hover a {
background-color: #fac55f !important;
color: white;
}
a.drkgreen:hover { background-color: #1f9390 !important; }
a.ltgreen:hover { background-color: #b3d88c !important; }
a.orange { background-color: #ffffff !important; }
a.orange:hover { background-color: #fac55f !important; }
a.ltblue { background-color: #ffffff !important; }
a.ltblue:hover { background-color: #26bfd0 !important; }
a.grey:hover { background-color: #8a949b !important; }
a.red:hover { background-color: #f16767 !important; }
a.red { background-color: #ffffff !important; }
</style>
<div class="navbar" gumby-fixed="top" id="nav1" style="background-image: url(img/white_banner_shadow4.png); background-position:bottom; background-repeat:repeat;">
<div class="row" >
<a class="toggle" gumby-trigger="#nav1 > .row > ul" href="#"><i class="icon-menu"></i></a>
<h1 class="four columns logo">
<a href="index.html">
<img src="img/FFR-logo3.png" gumby-retina />
</a>
</h1>
<ul class="eight columns" style="margin-top:30px;">
<li class="active">Our Difference</li>
<li style="background-color:#b3d88c; color:#FFF !important;" >Who We Are
<span class="not_mobile"><div class="dropdown">
<ul>
<li>Our Mission</li>
<li>Our Leadership</li>
</ul>
</div></span>
</li>
<li id="nav-orange">What We Do
<span class="not_mobile"><div class="dropdown">
<ul >
<li >Overview</li>
<li>Unique Research Services</li>
</ul>
</div></span>
</li>
<li>Our Capabilities
<span class="not_mobile"><div class="dropdown">
<ul>
<li>Experience</li>
<li>Qualitative</li>
<li>Quantitative</li>
<li>Support Services</li>
</ul>
</div></span>
</li>
<li>Connect</li>
<li>Tips and Tools
<span class="not_mobile"><div class="dropdown">
<ul>
<li>ProTalk™</li>
<li>Best Practice Tips</li>
</ul>
</div></span>
</li>
</ul>
</div>
</div>
in your CSS
change .navbar ul li > a:hover to .navbar ul li:hover > a
and a.orange:hover to li:hover > a.orange
and like so ..
Hope this will help you ..