This question already has answers here:
Understanding CSS selector priority / specificity
(4 answers)
Closed 1 year ago.
i was trying to make a toggle button for tablets/phones but it isn't working. The javascript class gets called when i click the toggle button so i don't know what is wrong...
My head where i load my js using defer function to avoid placing it at the end of the body
<script defer src="assets/js/index.js"></script>
const navToggle = document.querySelector(".nav-toggle");
const navMenu = document.querySelector(".nav-menu");
navToggle.addEventListener("click", () => {
navMenu.classList.toggle("nav-menu_visible");
});
/*my toggle button propertys on desktops*/
.header .nav .nav-toggle {
color: white;
background: none;
border: none;
font-size: 1.875em;
padding: 0 1.250em;
line-height: 60px;
cursor: pointer;
display: none;
}
/*for phones*/
#media (max-width: 1024px) {
.header .nav .nav-toggle {
display: block;
}
.header .nav .nav-menu {
flex-direction: column;
align-items: center;
background-color: #2c3e50;
position: fixed;
left: 0;
top: 60px;
width: 100%;
height: calc(100vh - 60px);
/*100%*/
overflow-y: auto;
padding: 1.250em 0;
left: 100%;
transition: left 0.3s;
}
.nav-menu_visible {
left: 0;
}
}
<header class="header">
<nav class="nav">
Portafolio
<button class="nav-toggle">
<i class="fas fa-bars"></i>
</button>
<ul class="nav-menu">
<li class="nav-menu-item">Inicio</li>
<li class="nav-menu-item">Sobre Mí</li>
<li class="nav-menu-item">Habilidades</li>
<li class="nav-menu-item">Conocimientos</li>
<li class="nav-menu-item">Proyectos</li>
<li class="nav-menu-item">Contacto</li>
</ul>
</nav>
</header>
I don't know why my menu isn't moving from left 0 to left 100% (it isn't showing :/)
It doesn't work because of CSS. Your specificity of nav-menu is much more as you have declared as.
.header .nav .nav-menu // 0 3 0
(x y x) => (id, class, tag)
Either you increase the specificity of .nav-menu_visible or decrease the specificity of .nav-menu
1) Decrease the specificity to 0 1 0 as
.nav-menu // 0 1 0
const navToggle = document.querySelector(".nav-toggle");
const navMenu = document.querySelector(".nav-menu");
navToggle.addEventListener("click", () => {
navMenu.classList.toggle("nav-menu_visible");
});
body {
background-color: black;
}
.header .nav .nav-toggle {
color: white;
background: none;
border: none;
font-size: 1.875em;
padding: 0 1.250em;
line-height: 60px;
cursor: pointer;
display: none;
}
/*for phones*/
#media (max-width: 1024px) {
.header .nav .nav-toggle {
display: block;
}
.nav-menu {
flex-direction: column;
align-items: center;
background-color: #2c3e50;
position: fixed;
left: 0;
top: 60px;
width: 100%;
height: calc(100vh - 60px);
/*100%*/
overflow-y: auto;
padding: 1.250em 0;
left: 100%;
transition: left 0.3s;
}
.nav-menu_visible {
left: 0;
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet"/>
<header class="header">
<nav class="nav">
Portafolio
<button class="nav-toggle">
<i class="fas fa-bars"></i>
</button>
<ul class="nav-menu">
<li class="nav-menu-item">Inicio</li>
<li class="nav-menu-item">Sobre Mí</li>
<li class="nav-menu-item">Habilidades</li>
<li class="nav-menu-item">Conocimientos</li>
<li class="nav-menu-item">Proyectos</li>
<li class="nav-menu-item">Contacto</li>
</ul>
</nav>
</header>
2) You can also increase the specificity to match with nav-menu as
.header .nav .nav-menu_visible { // 0 3 0
const navToggle = document.querySelector(".nav-toggle");
const navMenu = document.querySelector(".nav-menu");
navToggle.addEventListener("click", () => {
navMenu.classList.toggle("nav-menu_visible");
});
body {
background-color: black;
}
.header .nav .nav-toggle {
color: white;
background: none;
border: none;
font-size: 1.875em;
padding: 0 1.250em;
line-height: 60px;
cursor: pointer;
display: none;
}
/*for phones*/
#media (max-width: 1024px) {
.header .nav .nav-toggle {
display: block;
}
.header .nav .nav-menu {
flex-direction: column;
align-items: center;
background-color: #2c3e50;
position: fixed;
left: 0;
top: 60px;
width: 100%;
height: calc(100vh - 60px);
/*100%*/
overflow-y: auto;
padding: 1.250em 0;
left: 100%;
transition: left 0.3s;
}
.header .nav .nav-menu_visible {
left: 0;
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet" />
<header class="header">
<nav class="nav">
Portafolio
<button class="nav-toggle">
<i class="fas fa-bars"></i>
</button>
<ul class="nav-menu">
<li class="nav-menu-item">Inicio</li>
<li class="nav-menu-item">Sobre Mí</li>
<li class="nav-menu-item">Habilidades</li>
<li class="nav-menu-item">Conocimientos</li>
<li class="nav-menu-item">Proyectos</li>
<li class="nav-menu-item">Contacto</li>
</ul>
</nav>
</header>
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
#myDIV {
width: 100%;
padding: 50px 0;
text-align: center;
background-color: lightblue;
margin-top: 20px;
}
<button onclick="myFunction()">Portafolio</button>
<nav id="myDIV">
<ul class="nav-menu">
<li class="nav-menu-item">Inicio</li>
<li class="nav-menu-item">Sobre Mí</li>
<li class="nav-menu-item">Habilidades</li>
<li class="nav-menu-item">Conocimientos</li>
<li class="nav-menu-item">Proyectos</li>
<li class="nav-menu-item">Contacto</li>
</ul>
</nav>
Related
I am using the onclick method for turning my navbar on/off the problem that I'm having is when I adjust my screen size to mobile view my nav auto turns on.
I'm not very good at JavaScript. I have just started learning it so just fiddled around and absolutely nothing worked for me. Someone told me to put aria-expanded on my HTML so also tried that:
function closeNav() {
document.getElementById("nav_bar").style.height = "0%";
document.getElementById("open-btn").style.display = "inline-block";
document.getElementById("close-btn").style.display = "none";
}
function openNav() {
document.getElementById("nav_bar").style.height = "100%";
document.getElementById("open-btn").style.display = "none";
document.getElementById("close-btn").style.display = "inline-block";
}
body {
background: url(images/bg-img-01.jpg) no-repeat;
background-size: cover;
}
*,
*::after,
*::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#nav_bar {
background: radial-gradient( ellipse at top, rgba(196, 199, 200, 0.8), rgba(250, 255, 255, 0.02) 60%, rgba(0, 0, 0, 0) 1%);
position: fixed;
top: 0;
width: 100%;
}
#nav_bar>img {
display: none;
}
.nav {
background: none;
overflow: hidden;
display: flex;
margin-inline: auto;
flex-direction: row;
justify-content: space-around;
align-items: center;
list-style: none;
width: 65%;
left: 20%;
padding: 1.4em;
}
.list-item {
text-decoration: none;
color: #CBD5DF;
font-weight: bolder;
}
.list-item {
position: relative;
}
.list-item::before {
position: absolute;
content: "";
background-color: #535792;
height: 4px;
width: 0%;
top: 25px;
transition: all .3s ease-in;
}
.list-item:hover::before {
width: 100%;
}
.list-item:hover {
color: #C4C7C8;
}
#close-btn,
#open-btn {
display: none;
}
#media only screen and (max-width:768px) {
#nav_bar>img {
display: block;
position: absolute;
width: 10em;
left: 20%;
top: 10%;
}
#nav_bar {
width: 100%;
position: fixed;
z-index: 1;
top: 0;
overflow: hidden;
transition: 0.5s;
}
.nav {
position: relative;
display: flex;
flex-direction: column;
gap: 1.2rem;
top: 20%;
width: 100%;
text-align: center;
margin-top: 30px;
}
.list-item {
text-decoration: none;
display: block;
color: #ffdada;
font-size: 1.5rem;
transition: 0.3s;
}
#close-btn,
#open-btn {
display: block;
position: absolute;
right: 25px;
top: 20px;
font-size: 2rem;
color: #818181;
transition: all 0.3s;
}
#close-btn:hover {
color: #fff;
}
<body>
<div id="nav_bar">
<a href="#" id="close-btn">
<i aria-expanded="false" onclick="closeNav()" class="bi bi-x-lg"></i>
</a>
<img src="assests/images/moon.png" alt="" />
<div class="nav">
<a class="list-item" href="#">Home</a>
<a class="list-item" href="#">About Me</a>
<a class="list-item" href="#">Projects</a>
<a class="list-item" href="#">C.V</a>
<a class="list-item" href="#">Contact</a>
</div>
</div>
<a aria-expanded="false" href="#" id="open-btn" onclick="openNav()"><i class="bi bi-list"></i
></a>
<script src="assests/nav.js"></script>
</body>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
Make use of the classList.toggle function that adds/remove a class from the Navbar. In this example, I add or remove the class d-none that has the property: display: none in CSS. With that you can hide or show the navbar by pressing the same button with a single line of code:
const BUTTON = document.querySelector('#toggle_navBar');
const NAV = document.querySelector('nav');
BUTTON.addEventListener('click', function() {
NAV.classList.toggle('d-none');
});
body {
background: url(images/bg-img-01.jpg) no-repeat;
background-size: cover;
}
*,
*::after,
*::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
nav {
background: radial-gradient( ellipse at top, rgba(196, 199, 200, 0.8), rgba(250, 255, 255, 0.02) 60%, rgba(0, 0, 0, 0) 1%);
position: sticky;
top: 0;
width: 100%;
}
menu {
background: none;
overflow: hidden;
display: flex;
margin-inline: auto;
flex-direction: row;
justify-content: space-around;
align-items: center;
list-style: none;
width: 65%;
left: 20%;
padding: 1.4em;
}
nav li a {
text-decoration: none;
color: #CBD5DF;
font-weight: bolder;
position: relative;
}
nav li a::before {
position: absolute;
content: "";
background-color: #535792;
height: 4px;
width: 0%;
top: 25px;
transition: all .3s ease-in;
}
nav li a:hover::before {
width: 100%;
}
nav li a:hover {
color: #C4C7C8;
}
.d-none {
display: none;
}
<nav>
<img src="assests/images/moon.png" alt="" />
<menu>
<li><a class="list-item" href="#">Home</a></li>
<li><a class="list-item" href="#">About Me</a></li>
<li><a class="list-item" href="#">Projects</a></li>
<li><a class="list-item" href="#">C.V</a></li>
<li><a class="list-item" href="#">Contact</a></li>
</menu>
</nav>
<button id="toggle_navBar">Toggle NavBar</button>
A few changes I made were for semantic reasons. You should use semantic tags if possible and have accessibility in mind. Accessibility is also part of SEO-ratings!
I think the basic idea would be to have a button toggle some variable and then update the UI according to the value of that variable.
You can do this in several ways, but here is an example of a simple way to do it:
// Get your toggle button element
const toggle = document.querySelector(".nav-toggle");
// Get your nav element
const nav = document.querySelector(".nav");
// Create a variable to hold the state of your nav
let navIsOpen = false;
// Listen for clicks on your nav toggle button
toggle.addEventListener('click', () => {
// Update the nav state variable
navIsOpen = !navIsOpen;
// run a function that will update the nav "styles"
updateNav();
})
// This function will update the UI state according to the value of the navIsOpen variable. Here you can update all things you need, like your navbar, your toggle button, ...
function updateNav() {
navIsOpen
?
nav.classList.add('nav--is-open') :
nav.classList.remove('nav--is-open');
}
.nav {
margin-top: 1rem;
padding: 1rem;
background-color: lightgrey;
}
.nav--is-open {
background-color: purple;
color: white;
}
<button class="nav-toggle">Toggle nav</button>
<nav class="nav">
Your nav here
</nav>
I have a navbar having a gradient type background(slightly black, to transparent).
I wanted the navbar to turn completely black when scrolling, and I wrote the necessary JavaScript code, but the color changes only when I remove that background color gradient from the CSS, otherwise, it doesn't work. Is there a solution for this?
HTML Code:
<section id="header" class="headerr">
<img src="images/logo.png" class="logo">
<div>
<ul id="navbar">
<li><a class="active" href="why.html">Why Snap Smile</a></li>
<li>Solutions</li>
<li>Pricing</li>
<li>About</li>
<li>Gallery</li>
<li><i class="fa-solid fa-headset fa-2x"></i></li>
</ul>
</div>
CSS code:
body {
font-family: 'Montserrat', sans-serif;
width: 100%;
margin: 0;
background-color: #121212;
}
/* Header Section */
#header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 80px;
background: rgb(0,0,0);
background: linear-gradient(180deg, rgba(0,0,0,0.6629026610644257) 0%, rgba(9,9,121,0) 57%);
z-index: 999;
position: sticky;
top: 0;
left: 0;
}
.headerr__black{
background-color: #121212;
}
#navbar {
display: flex;
align-items: center;
justify-content: space-between;
}
#navbar li {
list-style: none;
padding: 0 20px;
position: relative;
}
#navbar li a {
text-decoration: none;
font-size: 1rem;
font-weight: 600;
color: #ffffff;
transition: 200ms ease-in-out;
}
#navbar li a:hover,
#navbar li a.active {
color: #e50914;
}
#navbar li a.active::after,
#navbar li a:hover::after {
content: "";
width: 30%;
height: 3px;
background: #e50914;
position: absolute;
bottom: -6px;
left: 20px;
}
.logo {
width: 10rem;
}
JavaScript Code:
const nav=document.getElementById('header');
window.addEventListener('scroll',function(){
if(window.scrollY >= 100){
nav.classList.add('headerr__black');
}
else{
nav.classList.remove('headerr__black');
}
});
I think this may happen because #header selector (id selector) has a higher priority than .header__black (class selector).
Can you try to update your style, so the .headerr__black styles have higher priority ? For example:
/*
* Now the selector specificity is {id} + {class},
* Which is higher than just {id} for #header
*/
#header.headerr__black {
background-color: #121212;
}
Doc - https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
I'm building site navigation. If I tab into a category and hit enter nothing happens. If I press the spacebar I get a flash of the subnav but then it disappears.
I am using a button element to trigger the subnav instead of an anchor tag. If I switch to an anchor tag then it works.
What is causing this to happen in my Javascript and is there a way to make this better?
I've put the entire nav on codepen here: https://codepen.io/sibarad/pen/gORqevp?editors=1010
Here is a basic example of the html:
<ul class="site-menu header-container--nav-mobile">
<li class="site-menu__item site-menu__item--has-submenu">
<button tabindex="0" aria-expanded="false">Nav Link 1
<span class="site-menu__submenu-icon">
<svg aria-hidden="true" width="16" height="16">
<use xlink:href="#mobile-nav-arrow" />
</svg>
</span>
</button>
<!-- Main Nav Item 1 Sub-item -->
<ul class="site-menu__submenu" id="dt_nav-accountbilling">
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
</ul><!-- /Main Nav Item 1 Sub-item -->
</li><!-- /Main Nav Item 1 -->
Here is my JS:
// Submenu Hide/Show Mobile and Desktop
const items = document.querySelectorAll(".site-menu__item--has-submenu");
const subButton = document.querySelectorAll(".site-menu__item--has-submenu button");
// Activate Submenu
function toggleItem() {
if (this.classList.contains("submenu-active")) {
this.classList.remove("submenu-active");
} else if (site_menu.querySelector(".submenu-active")) {
site_menu.querySelector(".submenu-active").classList.remove("submenu-active");
this.classList.add("submenu-active");
this.setAttribute('aria-expanded', 'true');
} else {
this.classList.add("submenu-active");
this.setAttribute('aria-expanded', 'false');
}
}
// Event Listeners
for (let item of items) {
if (item.querySelector(".site-menu__submenu")) {
item.addEventListener("click", toggleItem, false);
item.addEventListener("keypress", toggleItem, false);
}
}
// Close Submenu From Anywhere
function closeSubmenu(e) {
let isClickInside = site_menu.contains(e.target);
if (!isClickInside && site_menu.querySelector(".submenu-active")) {
site_menu.querySelector(".submenu-active").classList.remove("submenu-active");
}
}
// Event listener for Close Submenu
document.addEventListener("click", closeSubmenu, false);
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
//if esc key was not pressed in combination with ctrl or alt or shift
const isNotCombinedKey = !(event.ctrlKey || event.altKey || event.shiftKey);
if (isNotCombinedKey) {
closeSubmenu(false);
}
}
});
The offending code is here:
for (let item of items) {
if (item.querySelector(".site-menu__submenu")) {
item.addEventListener("click", toggleItem, false);
<!-- this will be triggered as well, reversing your toggle -->
item.addEventListener("keypress", toggleItem, false);
}
}
You are adding 2 listeners that will both trigger on pressing space etc.
You do not need the second listener as you used a <button> which will treat Space etc. as a click event!
Removing the second listener will make the drop down work as expected.
for (let item of items) {
if (item.querySelector(".site-menu__submenu")) {
item.addEventListener("click", toggleItem, false);
}
}
Fixed code and fiddle
/////////////
// Site header/navigation
////////////
(function() {
'use strict';
// Hamburger Animation toggle
const hamburger = document.querySelector('.js-primary-nav__toggle');
const hamburger_text = document.querySelector('.js-primary-nav__toggle-text');
// Mobile Container for Nav Content
const site_menu = document.querySelector('.main-site-menu');
hamburger.addEventListener('click', () => {
hamburger.classList.toggle('toggle-active');
if (hamburger_text.textContent === "Menu") {
hamburger_text.textContent = "Close";
site_menu.classList.add('is-active');
hamburger.setAttribute('aria-expanded', 'true');
document.body.classList.toggle('lock-scroll');
} else {
hamburger_text.textContent = "Menu";
site_menu.classList.remove('is-active');
hamburger.setAttribute('aria-expanded', 'false');
document.body.classList.toggle('lock-scroll');
}
});
// Submenu Hide/Show Mobile and Desktop
const items = document.querySelectorAll(".site-menu__item--has-submenu");
const subButton = document.querySelectorAll(".site-menu__item--has-submenu button");
// Activate Submenu
function toggleItem() {
if (this.classList.contains("submenu-active")) {
this.classList.remove("submenu-active");
} else if (site_menu.querySelector(".submenu-active")) {
site_menu.querySelector(".submenu-active").classList.remove("submenu-active");
this.classList.add("submenu-active");
this.setAttribute('aria-expanded', 'true');
} else {
this.classList.add("submenu-active");
this.setAttribute('aria-expanded', 'false');
}
}
// Event Listeners
for (let item of items) {
if (item.querySelector(".site-menu__submenu")) {
item.addEventListener("click", toggleItem, false);
//item.addEventListener("keypress", toggleItem, false);
}
}
// Close Submenu From Anywhere
function closeSubmenu(e) {
let isClickInside = site_menu.contains(e.target);
if (!isClickInside && site_menu.querySelector(".submenu-active")) {
site_menu.querySelector(".submenu-active").classList.remove("submenu-active");
}
}
// Event listener for Close Submenu
document.addEventListener("click", closeSubmenu, false);
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
//if esc key was not pressed in combination with ctrl or alt or shift
const isNotCombinedKey = !(event.ctrlKey || event.altKey || event.shiftKey);
if (isNotCombinedKey) {
closeSubmenu(false);
}
}
});
}());
body {
font-size: 16px;
line-height: 1.5;
font-family: "Open Sans", "Segoe UI", Tahoma, sans-serif;
}
.os-container--max-width, .header-container--nav-mobile, .header-container {
max-width: 1272px;
margin-right: auto;
margin-left: auto;
padding-left: 12px;
padding-right: 12px;
}
.os-container--fluid {
max-width: 100%;
margin-right: auto;
margin-left: auto;
}
.os-flex-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-left: -8px;
margin-right: -8px;
}
#media (min-width: 672px) {
.os-flex-grid {
margin-left: -12px;
margin-right: -12px;
}
}
.os-flex--stack-mobile {
flex-direction: column;
}
#media (min-width: 672px) {
.os-flex--stack-mobile {
flex-direction: row;
}
}
.os-flex-grid__col {
padding-left: 8px;
padding-right: 8px;
-ms-flex: 1 1 0px;
flex-basis: auto;
flex-grow: 1;
min-width: 0;
max-width: 100%;
position: relative;
width: 100%;
}
#media (min-width: 672px) {
.os-flex-grid__col {
flex-basis: 0;
padding-left: 12px;
padding-right: 12px;
}
}
.os-flex-grid__col--12, .cms-flex-grid__col--12 {
flex-basis: 100%;
}
.os-flex-grid__col--9, .cms-flex-grid__col--9 {
flex-basis: 75%;
}
.os-flex-grid__col--6 {
flex-basis: 50%;
}
.os-flex-grid__col--4 {
flex-basis: 33.3333333333%;
}
.os-flex-grid__col--3 {
flex-basis: 25%;
}
.os-flex-grid__col--2 {
flex-basis: 16.6666666667%;
}
.site-header {
background-color: #fff;
list-style: none;
}
.site-header a {
color: #0e75c4;
}
#media (min-width: 1056px) {
.site-header {
margin-bottom: 42px;
}
}
.site-nav {
display: flex;
flex-direction: column;
align-items: normal;
justify-content: flex-start;
width: 100%;
position: relative;
z-index: 3;
}
#media (min-width: 1056px) {
.site-nav {
display: block;
}
}
#media (min-width: 1056px) {
.header-container {
position: relative;
z-index: 5;
}
}
.header-container--nav-mobile {
padding-left: 1.25rem;
padding-right: 1.25rem;
}
#media (min-width: 1056px) {
.header-container--nav-mobile {
padding-left: inital;
padding-right: inital;
}
}
.header-main {
box-shadow: 0 4px 8px -2px rgba(18, 32, 42, 0.12);
padding-top: 16px;
padding-bottom: 16px;
}
#media (min-width: 1056px) {
.header-main {
box-shadow: none;
padding-top: 32px;
padding-bottom: 32px;
}
}
.header-main__items {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.header-logo img {
width: 100%;
max-width: 131px;
}
#media (min-width: 672px) {
.header-logo img {
max-width: 260px;
}
}
.header-component-wrap {
display: flex;
flex-direction: row;
align-items: flex-end;
}
.header-component-wrap a {
text-decoration: none;
}
.header-component-wrap a:hover {
text-decoration: underline;
}
.header-component-wrap svg {
fill: #213848;
margin-bottom: 8px;
width: 20px;
height: 20px;
}
#media (min-width: 1056px) {
.header-component-wrap svg {
margin-bottom: 0;
margin-right: 8px;
width: 20px;
height: 20px;
}
}
#media (min-width: 1056px) {
.header-component-wrap {
align-items: center;
}
}
.header-main__text {
text-decoration: none;
color: #0e75c4;
font-size: 10px;
font-weight: 600;
letter-spacing: 1.25px;
}
.header-main__text:hover {
text-decoration: underline;
color: #0e75c4;
}
#media (min-width: 1056px) {
.header-main__text {
font-size: 16px;
font-weight: 600;
letter-spacing: normal;
}
}
.site-menu,
.site-menu__submenu {
list-style-type: none;
}
.site-menu {
margin: 0 auto;
background-color: #213848;
display: flex;
flex-direction: column;
align-items: flex-start;
padding-top: 24px;
padding-bottom: 24px;
overflow-y: auto;
}
#media (min-width: 1056px) {
.site-menu {
flex-wrap: nowrap;
flex-direction: row;
align-items: stretch;
justify-content: flex-start;
padding: 0;
padding-right: 8px;
padding-left: 8px;
position: relative;
top: 0;
height: auto;
overflow-y: visible;
border-radius: 6px;
}
}
.main-site-menu {
transition: 0.3s;
position: absolute;
top: 80px;
width: 100%;
left: 0;
left: 0;
opacity: 0;
overflow-x: hidden;
visibility: hidden;
height: 100vh;
background-color: #213848;
padding-bottom: 9.75rem;
}
#media (min-width: 1056px) {
.main-site-menu {
position: relative;
top: 0;
left: 0;
transition: none;
opacity: 1;
visibility: visible;
overflow-x: initial;
height: auto;
padding-bottom: 0;
background-color: transparent;
}
}
.main-site-menu.is-active {
opacity: 1;
visibility: visible;
}
.site-menu__item {
position: relative;
display: inline-block;
margin-bottom: 16px;
width: 100%;
}
#media (min-width: 1056px) {
.site-menu__item {
margin-bottom: 0;
width: auto;
}
}
.site-menu__item a {
display: block;
color: #fff !important;
}
.site-menu__item > a {
font-weight: 600;
font-size: 18px;
}
#media (min-width: 1056px) {
.site-menu__item > a {
padding: 24px 16px;
}
}
#media (min-width: 1272px) {
.site-menu__item > a {
padding: 24px;
}
}
.site-menu__item > a:hover {
cursor: pointer;
}
#media (min-width: 1056px) {
.site-menu__item > a:hover {
background-color: #0e75c4;
}
}
.site-menu__item--has-submenu {
border-bottom: 1px solid #2f4656;
}
#media (min-width: 1056px) {
.site-menu__item--has-submenu {
border-bottom: none;
}
}
#media (min-width: 1056px) {
.site-menu__item.site-menu__button {
margin-left: auto;
}
}
.site-menu__item--has-submenu button {
background-color: transparent;
outline: none;
border: none;
color: #fff;
padding-top: 24px;
padding-bottom: 24px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
font-size: 16px;
font-weight: 600;
transition: 0.333333333s ease-in-out;
}
.site-menu__item--has-submenu button:hover {
cursor: pointer;
}
#media (min-width: 1056px) {
.site-menu__item--has-submenu button:hover {
background-color: #2f4656;
color: #61bef0;
}
}
.site-menu__item--has-submenu button:focus {
outline: 1px solid #128ddd;
}
#media (min-width: 1056px) {
.site-menu__item--has-submenu button {
padding-top: 16px;
padding-bottom: 16px;
padding-left: 24px;
padding-right: 24px;
font-size: 14px;
}
}
#media (min-width: 1240px) {
.site-menu__item--has-submenu button {
padding-top: 20px;
padding-bottom: 20px;
padding-left: 24px;
padding-right: 24px;
font-size: 16px;
}
}
.site-menu__submenu-icon svg {
width: 16px;
height: 9.33px;
}
#media (min-width: 1056px) {
.site-menu__submenu-icon {
display: none;
}
}
.mobile-nav-arrow {
width: 16px;
height: 9.33px;
transition: 0.3s;
fill: #128ddd;
}
.site-menu__submenu {
font-size: 16px;
background-color: #2f4656;
padding-top: 8px;
padding-right: 24px;
padding-bottom: 8px;
padding-left: 24px;
min-width: 100%;
border-radius: 6px;
transition: max-height 0.4s 0s ease-in-out;
display: none;
max-height: 0;
left: -999rem;
flex-direction: column;
}
#media (min-width: 1056px) {
.site-menu__submenu {
font-size: 14px;
position: absolute;
top: 100%;
left: 0;
margin-left: 0;
min-width: 302px;
display: flex;
flex-direction: column;
border-radius: 0;
border-bottom-right-radius: 6px;
border-bottom-left-radius: 6px;
visibility: hidden;
padding-top: 16px;
padding-bottom: 8px;
}
}
#media (min-width: 1240px) {
.site-menu__submenu {
font-size: 16px;
}
}
#media (min-width: 1056px) {
.site-menu__item--has-submenu:nth-child(7) > .site-menu__submenu {
min-width: 185px;
}
}
#media (min-width: 1240px) {
.site-menu__item--has-submenu:nth-child(7) > .site-menu__submenu {
min-width: 295px;
}
}
#media (min-width: 1272px) {
.site-menu__item--has-submenu:nth-child(7) > .site-menu__submenu {
min-width: 302px;
}
}
.submenu-active .site-menu__submenu {
display: flex;
max-height: inherit;
left: auto;
}
#media (min-width: 1056px) {
.submenu-active .site-menu__submenu {
visibility: visible;
}
}
#media (min-width: 1056px) {
.submenu-active {
background-color: #2f4656;
}
}
.submenu-active > button {
color: #61bef0;
}
.site-menu__submenu-col {
position: relative;
width: 100%;
flex-basis: 0;
flex-grow: 1;
min-width: 0;
max-width: 100%;
list-style-position: inside;
}
#media (min-width: 1056px) {
.site-menu__subitem {
display: inline-block;
}
}
.site-menu__subitem a {
padding-top: 16px;
padding-bottom: 16px;
display: inline-block;
text-decoration: none;
}
.site-menu__subitem a:hover {
text-decoration: underline;
cursor: pointer;
}
#media (min-width: 1056px) {
.site-menu__subitem a {
padding: 0;
margin-bottom: 24px;
}
}
.site-menu__item--mobile-search {
display: block;
}
#media (min-width: 1056px) {
.site-menu__item--mobile-search {
display: none;
}
}
.site-menu__item--mobile-search input {
width: 100%;
padding: 12px;
background-image: url(../images/search-icon.svg);
background-repeat: no-repeat;
background-position: 98% center;
border: 1px solid #687782;
box-shadow: inset 0px 4px 0px #ebebeb;
border-radius: 6px;
}
.primary-nav__toggle {
outline: 0;
border: 0;
background: transparent;
background-color: transparent;
display: inline-block;
cursor: pointer;
padding: 0;
margin: 0;
height: 48px;
}
#media (min-width: 1056px) {
.primary-nav__toggle {
display: none;
}
}
.primary-nav__toggle-bar {
display: block;
width: 24px;
height: 2px;
background-color: #213848;
margin: 6px auto;
transition: 0.4s;
border-radius: 1px;
}
.primary-nav__toggle-bar--bottom {
margin-bottom: 4px;
}
.toggle-active .primary-nav__toggle-bar--top {
transform: rotate(-45deg) translate(-7px, 6px);
}
.toggle-active .primary-nav__toggle-bar--middle {
opacity: 0;
}
.toggle-active .primary-nav__toggle-bar--bottom {
transform: rotate(45deg) translate(-5px, -5px);
}
.lock-scroll {
overflow: hidden;
position: fixed;
width: 100%;
}
<header class="site-header site-header--home">
<nav class="site-nav" role="navigation" aria-label="main menu">
<!-- main header -->
<div class="header-main">
<div class="header-container header-main__items">
<a class="header-logo" href="">Logo</a>
<div class="header-component-wrap">
<!-- Mobile Hamburger Toggle -->
<button class="primary-nav__toggle js-primary-nav__toggle" aria-expanded="false">
<span class="primary-nav__toggle-bar primary-nav__toggle-bar--top"></span>
<span class="primary-nav__toggle-bar primary-nav__toggle-bar--middle"></span>
<span class="primary-nav__toggle-bar primary-nav__toggle-bar--bottom"></span>
<span class="header-main__text js-primary-nav__toggle-text">Menu</span>
</button><!-- /Mobile Hamburger Toggle -->
</div>
</div>
</div>
<!-- Site Navigation Wrappers -->
<div class="header-container">
<div class="main-site-menu">
<!-- Site Nav -->
<ul class="site-menu header-container--nav-mobile">
<!-- Main Nav Item 1 -->
<li class="site-menu__item site-menu__item--has-submenu">
<button tabindex="0" aria-expanded="false">Nav Link 1
<span class="site-menu__submenu-icon">
<svg aria-hidden="true" width="16" height="16">
<use xlink:href="#mobile-nav-arrow" />
</svg>
</span>
</button>
<!-- Main Nav Item 1 Sub-item -->
<ul class="site-menu__submenu" id="dt_nav-accountbilling">
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
</ul><!-- /Main Nav Item 1 Sub-item -->
</li><!-- /Main Nav Item 1 -->
<!-- Main Nav Item 2 -->
<li class="site-menu__item site-menu__item--has-submenu">
<button tabindex="0" aria-expanded="false">Nav Link 2
<span class="site-menu__submenu-icon">
<svg aria-hidden="true" width="16" height="16">
<use xlink:href="#mobile-nav-arrow" />
</svg>
</span>
</button>
<!-- Main Nav Item 2 Sub-item -->
<ul class="site-menu__submenu" id="dt_nav-savemoney">
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
</ul><!-- /Main Nav Item 2 Sub-item -->
</li><!-- /Main Nav Item 2 -->
<!-- Main Nav Item 3 -->
<li class="site-menu__item site-menu__item--has-submenu">
<button tabindex="0" aria-expanded="false">Nav Link 3
<span class="site-menu__submenu-icon">
<svg aria-hidden="true" width="16" height="16">
<use xlink:href="#mobile-nav-arrow" />
</svg>
</span>
</button>
<!-- Main Nav Item 3 Sub-item -->
<ul class="site-menu__submenu" id="dt_nav-outagesstorms">
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
</ul><!-- /Main Nav Item 3 Sub-item -->
</li><!-- /Main Nav Item 3 -->
<!-- Main Nav Item 4 -->
<li class="site-menu__item site-menu__item--has-submenu">
<button tabindex="0" aria-expanded="false">Nav Link 4
<span class="site-menu__submenu-icon">
<svg aria-hidden="true" width="16" height="16">
<use xlink:href="#mobile-nav-arrow" />
</svg>
</span>
</button>
<!-- Main Nav Item 4 Sub-item -->
<ul class="site-menu__submenu" id="dt_nav-safety">
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
<li class="site-menu__subitem">Subnav</li>
</ul><!-- /Main Nav Item 4 Sub-item -->
</li><!-- /Main Nav Item 4 -->
</ul><!-- /Site Nav -->
</div>
</div><!-- /Site Navigation Wrappers -->
</nav>
</header><!-- /Begin ES Site Header -->
I have a simple website with a simple navigation bar, but it seems like a very daunting task after much research.
When hovering over any of the buttons, it will display a dropdown to show more options.
I have got that working fine, but how would I go about making the dropdown stay when I hover over the contents of the dropdown?
Basically when the cursor leaves the navigation's bar button and onto the dropdown menu, it doesn't disappear.
I read that it's possible with jQuery, but I want to do it in JavaScript alone if it's possible, even if it's lengthy.
The navbar's hover itself works, but whatever I tried to keep the dropdown there when hovering on it, keeps bugging everything out.
This is the code I have, and that I have tried:
document.getElementById("server").onmouseover = function() {
serverMouseOver()
};
document.getElementById("server").onmouseout = function() {
serverMouseOut()
};
function serverMouseOver() {
document.getElementById("serverdropdownbox").className += "animated fadeIn";
};
function serverMouseOut() {
document.getElementById("serverdropdownbox").className += "animated fadeOut";
};
document.getElementById("serverdropdownbox").onmouseover = function() {
serverDropdownMouseOver()
};
document.getElementById("serverdropdownbox").onmouseout = function() {
serverDropdownMouseOut()
};
function serverDropdownMouseOver() {
document.getElementById("serverdropdownbox").style.opacity = "1";
};
function serverDropdownMouseOut() {
document.getElementById("serverdropdownbox").style.opacity = "0";
};
#navbarbox
{
clear: both;
display: block;
width: 100vw;
height: 3.5vw;
padding: 0vw 0 0 0;
margin: 0;
}
#navbar, #navbar ul
{
width: 100vw;
height: 3.5vw;
display: flex;
padding: 0 0 0 0;
margin: 0;
}
#navbar span
{
height: 3.5vw;
display: block;
transform: skewX(15deg);
}
#navbar li
{
color: white;
list-style: none;
display: inline-block;
padding: 1vw 3.95vw 1vw 3.95vw;
margin: auto;
text-align: center;
color: red;
font-size: 2.3vw;
font-family: Jura;
height: 2.5vw;
transform: skewX(-15deg);
}
#serverdropdownbox
{
display: block;
opacity: 0;
float: left;
color: white;
background-color: darkblue;
width: 0;
}
#serverdropdowncontent
{
list-style-type: none;
width: 16vw;
margin: 1vw 0 0 10.1vw;
}
#serverdropdowncontent li
{
border: 1px solid white;
font-size: 25px;
text-align: center;
padding: 1vw 0 1vw 0;
background-color: white;
}
#server
{
background-color: blue;
}
#communitydropdownbox
{
display: block;
float: left;
color: white;
background-color: darkblue;
width: 0;
}
#communitydropdowncontent
{
list-style-type: none;
width: 19.7vw;
margin: 1vw 0 0 26vw;
}
#communitydropdowncontent li
{
border: 1px solid white;
font-size: 25px;
text-align: center;
padding: 1vw 0 1vw 0;
}
#community
{
background-color: brown;
}
#storedropdownbox
{
display: block;
float: left;
color: white;
background-color: darkblue;
width: 0;
}
#storedropdowncontent
{
list-style-type: none;
width: 13.6vw;
margin: 1vw 0 0 45.65vw;
}
#storedropdowncontent li
{
border: 1px solid white;
font-size: 25px;
text-align: center;
padding: 1vw 0 1vw 0;
}
#store
{
background-color: blue;
}
#downloadsdropdownbox
{
display: block;
float: left;
color: white;
background-color: darkblue;
width: 0;
}
#downloadsdropdowncontent
{
list-style-type: none;
width: 19.8vw;
margin: 1vw 0 0 59.2vw;
}
#downloadsdropdowncontent li
{
border: 1px solid white;
font-size: 25px;
text-align: center;
padding: 1vw 0 1vw 0;
}
#downloads
{
background-color: brown;
}
#contactdropdownbox
{
display: block;
float: left;
color: white;
background-color: darkblue;
width: 0;
}
#contactdropdowncontent
{
list-style-type: none;
width: 16vw;
margin: 1vw 0 0 78.9vw;
}
#contactdropdowncontent li
{
border: 1px solid white;
font-size: 25px;
text-align: center;
padding: 1vw 0 1vw 0;
}
#contact
{
background-color: blue;
}
.animated
{
animation-duration: 1s;
animation-fill-mode: both;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.fadeIn {
animation-name: fadeIn;
}
#keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.fadeOut {
animation-name: fadeOut;
}
<head>
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Jura" />
<body>
<!--Giga logo, top left-->
<img id="gigalogo" src="images/gigalogo.png">
<!--Steam logo, top right-->
<div id="steamlogomainbox">
<img id="steamlogo" src="images/steamlogo.png">
</div>
<!--navigation barrrrrr-->
<div id="navbarbox">
<ul id="navbar">
<li style="background-color: purple;"><span>Home</span></li>
<li id="server"><span>Servers</span></li>
<li id="community"><span>Community</span></li>
<li id="store"><span>Store</span></li>
<li id="downloads"><span>Downloads</span></li>
<li id="contact"><span>Contact</span></li>
</ul>
</div>
<div id="serverdropdownbox">
<ul id="serverdropdowncontent">
<li id="serverdropdownli">Server List</li>
<li id="serverdropdownli">GigaDB</li>
<li id="serverdropdownli">CS:GO</li>
</ul>
</div>
<div id="communitydropdownbox">
<ul id="communitydropdowncontent">
<li>Events</li>
<li></li>
</ul>
</div>
<div id="storedropdownbox">
<ul id="storedropdowncontent">
<li>Credits</li>
<li>Items</li>
<li>VIP</li>
</ul>
</div>
<div id="downloadsdropdownbox">
<ul id="downloadsdropdowncontent">
<li>TF2</li>
<li>CS:GO</li>
<li>Minecraft</li>
</ul>
</div>
<div id="contactdropdownbox">
<ul id="contactdropdowncontent">
<li>Contact Us</li>
<li>Staff</li>
<li>Steam Group</li>
<li>Appeal Ban</li>
<li>Links</li>
</ul>
</div>
First of all - your HTML structure is invalid. ul tag can have only li as direct child, not a. So ul > a > li must be replaced to ul > li > a.
Second - you don't need JS for such simple menu. Have ul > li > ul as sub-menu and use :hover on ul > li to show your sub-menu.
ul {
padding: 0;
}
li {
white-space: nowrap;
list-style: none;
}
#menu > li {
position: relative;
display: inline-block;
}
#menu > li > ul {
position: absolute;
left: 0;
top: 100%;
min-width: 100%;
opacity: 0;
transition: opacity 200ms ease-in-out;
}
#menu > li:hover > ul {
opacity: 1;
}
<ul id="menu">
<li>Home</li>
<li>
<span>Servers</span>
<ul>
<li>Server 1</li>
<li>Server 2</li>
<li>Server 3</li>
</ul>
</li>
</ul>
I have a responsive navigation which is fixed at the top and goes from horizontal to vertical if screensize is <=800 px wide.
Now I'm trying to move the currently active link to the top of the navigation if the screen size is <=800 px wide, but I can't seem to find a way.
I tried Javascript but it won't keep the currently active link at the top since the page refreshes or changes when a link is clicked.
I tried to put the loop in an if-statement but that doesn't work, so I removed the if-statement.
I would really appreciate it if someone could help me solve this problem.
Here's the Javascript:
/*------------------------move active link to top------------------------*/
function moveLink(){
var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
var list = document.getElementById('nav').childNodes;
for (var i = 0; i < list.length; i++) {
list[i].addEventListener('click',function()
{nav.insertBefore(this, nav.childNodes[0])});
}
}
Here's the navigation html:
<nav>
<ul id="nav" class="topNav">
<li><a onclick="moveLink()" href="/">Placeholder1</a></li>
<li><a onclick="moveLink()" href="Placeholder1.html">Placeholder1</a></li>
<li><a onclick="moveLink()" href="Placeholder1.html">Placeholder1</a></li>
<li><a onclick="moveLink()" class="active" href="licenses.html">Placeholder1 / FAQ</a></li>
<li><a onclick="moveLink()" href="Placeholder1.html">Placeholder1</a></li>
<li><a onclick="moveLink()" href="contact.php">Placeholder1</a></li>
<li class="icon"><a href="javascript:void(0);" onclick="myFunction()">
<img alt="open menu" src="graphics/menu.png" style="height: 30px; width: 30px;"></a>
</li>
</ul>
I have two stylesheets and the menu opens and closes via Javascript.
Here's my mobile css:
/*------------------------navigation------------------------*/
.topNav {
z-index: 1;
list-style-type: none;
margin: 0 auto;
padding: 0;
overflow: hidden;
position: fixed;
top: 0;
width: 100%;
font-size: 0px;
background-color: rgba(0,0,0,0.8);
box-shadow: 0px 0px 8px 0px rgba(0,0,0,0.75);
}
.topNav li {
display: inline;
}
.topNav li a {
font-size: 12px;
display: inline-block;
color: #fff;
text-decoration: none;
transition: color 0.2s ease-in-out;
line-height: 38px;
padding: 0px 0px 0px 20px;
}
.topNav li a:hover {
color: #777;
}
.topNav li a.active {
color: #999;
}
/*------------------------responsive navigation closed------------------------*/
.topNav li:not(:first-child) {
display: none;
}
.topNav li.icon {
float: right;
display: inline-block;
height: 38px;
vertical-align: middle;
transition: opacity 0.2s ease-in-out;
margin: 4px 5px 0px 0px;
width: 30px;
height: 30px;
padding-right: 20px;
}
.icon:hover {
opacity: 0.5;
}
/*------------------------responsive navigation opened------------------------*/
.topNav.responsive {
position: fixed;
top: 0px;
}
.topNav.responsive li.icon {
margin: 0 0 0 0;
position: absolute;
top: 4px;
right: 25px;
width: 30px;
height: 30px;
padding-right: 0px;
z-index: 1;
}
.topNav.responsive li.icon:hover {
opacity: 0.5;
}
.topNav.responsive li {
float: none;
display: inline;
}
.topNav.responsive li a {
display: block;
}
thanks in advance,
Ken
I think you could do this just using CSS using flexbox and order property.
#media (max-width: 800px) {
nav ul {
display: flex;
flex-direction: column;
}
.active {
order: -1;
}
}
order: -1 ensures that the list item will move to the top of the column.
I moved the class active to the li, instead of the a, to make this work a little easier.
codepen
snippet
body {
font-family: sans-serif;
}
nav {
background: grey;
padding: 20px;
}
nav ul {
list-style-type: none;
}
nav ul li {
display: inline-block;
margin-right: 8px;
}
nav ul li:last-child {
margin-right: 0;
}
nav ul li a {
text-decoration: none;
color: white;
}
#media (max-width: 800px) {
nav ul {
display: flex;
flex-direction: column;
}
.active {
order: -1;
}
}
<nav>
<ul id="nav" class="topNav">
<li><a onclick="moveLink()" href="/">BEATS</a></li>
<li><a onclick="moveLink()" href="sounds.html">SOUNDS</a></li>
<li><a onclick="moveLink()" href="services.html">SERVICES</a></li>
<li class="active"><a onclick="moveLink()" href="licenses.html">LICENSES / FAQ</a></li>
<li><a onclick="moveLink()" href="downloads.html">DOWNLOADS</a></li>
<li><a onclick="moveLink()" href="contact.php">CONTACT</a></li>
</ul>
</nav>