I am trying to make a responsive navigation on my Wordpress site where I am building a template from scratch. I have decent experience with HTML and CSS(SCSS) some PHP but not so much Javascript or the Wordpress way.
I am looking to remove the :hover element on my sub menu under the 'services' li and instead have it trigger on click on tablet and mobile devices. I understand it will be similar to how I have done the mobile menu button but I am struggling to figure out the best way to do it.
Can anyone give me an idea please? Thanks in advance.
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
header {
height: 128px;
border-bottom: 1px solid #f0f0f0;
width: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 4000;
background: white;
}
header .nav-container {
max-width: 100em;
margin: auto;
display: flex;
justify-content: space-between;
z-index: 45;
padding: 0 1.5rem;
}
header .nav-container .logo {
width: 14%;
padding-top: 2.8rem;
}
header .nav-container p {
display: none;
}
#media only screen and (max-width: 600px) {
header .nav-container p {
display: flex;
}
}
header .nav-container nav {
padding-top: 2rem;
}
#media only screen and (max-width: 600px) {
header .nav-container nav {
display: none;
}
}
#media only screen and (max-width: 600px) {
header .nav-container nav ul {
flex-direction: column;
display: flex;
}
}
header .nav-container nav ul li {
position: relative;
display: inline-block;
}
header .nav-container nav ul li a {
display: inline-block;
transition: all 0.5s linear;
text-decoration: none;
padding: 16px 10px;
color: #00458B;
}
header .nav-container nav ul li a:hover {
color: #00458B;
}
header .nav-container nav ul li ul {
display: none;
background: white;
position: absolute;
top: 100%;
width: 160px;
padding: 0;
z-index: 500;
}
header .nav-container nav ul li ul li, header .nav-container nav ul li ul a {
width: 100%;
}
header .nav-container nav ul li:hover ul {
display: block;
}
header .nav-container nav ul .menu-item-40 a {
padding: 0;
}
<header>
<div class="nav-container">
<p onclick="myFunction()"> Click</p>
<nav class="nav" role="navigation" id="myDIV">
<ul>
<li class="nav-item">Home
</li>
<li class="nav-item">About us
</li>
<li class="nav-item">Services
<ul class="sub-menu">
<li class="nav-item ">Windows
</li>
<li class="nav-item">Glass
</li>
<li class="nav-item">Doors
</li>
<li class="nav-item">Roofline
</li>
</ul>
</li>
<li class="nav-item">Our Work
</li>
<li class="nav-item">Contact Us
</li>
</ul>
</nav>
</div>
</header>
Wrap it with Media Query so it doesn't work on Mobile and tablet.
header .nav-container nav ul li:hover ul {
display: block;
}
This is only one of many possible solutions, but I think it gives you an idea off how to solve the problem.
First you have to wrap following selector with a media query to disable the hover when your mobile button shows up. In your case it would look like this:
#media only screen and (min-width: 601px) {
header .nav-container nav ul li:hover ul {
display: block;
}
}
To attach the toggle functionality I would suggest to add a js-submenu-toggle class to all a elements which have a submenu as sibling. I prefer to add a js prefix to my classes to mark them as classes that are only used in combination with javascript and have no styling attached to them:
<ul>
...
<li class="nav-item">
Services
<ul class="sub-menu">
...
</ul>
</li>
...
</ul>
For the actual functionality use the toggle function to add and remove an is-active class on click to the submenu element and the matchMedia function to make the toggle functionality only available when your mobile menu button is visible:
document.addEventListener('click', event => {
const element = event.target;
const mediaQuery = window.matchMedia('(max-width: 600px)');
if(element.matches('.js-submenu-toggle') && mediaQuery.matches) {
// Prevents the default behaviour of the `a`-tag with an `href`-attribute
event.preventDefault();
element.nextElementSibling.classList.toggle('is-active');
}
});
The is-active class should look like this:
.is-active {
display: block;
}
Related
I want the navbar to disappear when it reaches 768px and become a button on the right side. The button will open the navbar back, I have added code to make the navbar to disappear at 768px but it doesn't work. Not so sure what is wrong since the button shows 768px. But the navbar does not disappear at 768px.
html
<nav id="Nav" class="navbar nav">
<div class="container flex">
<img src="Week5saasappassets-210323-142515 (1)/Week-5-saas-app-assets/project_logo/logo.svg" alt="Company logo" class="company-logo">
<button class="navbar-toggler" aria-expanded="false" aria-controls="navbarDropdown"><span>☰</span></button>
<div class="nav-parent">
<ul class="navbar-nav">
<li class="nav-link">
Home
</li>
<li class="nav-link">
Features
</li>
<li class="nav-link">
Learn
</li>
<li class="nav-link">
Price
</li>
<li class="nav-link">
Hire us
</li>
</ul>
</div>
</div>
</nav>
css
navbar-toggler{
position: absolute;
right: var(--size-20);
outline: none;
background-color: transparent;
border: 1px solid transparent;
}
.navbar-toggler span{
color: var(--pureblack);
font-size: var(--size-20);
}
[aria-controls="navbarDropdown"]{
display: none;
}
.navbar .container{
top: 0;
right: 0;
left: 0;
z-index: 500;
transition: ease-in-out 0.3s;
display:flex;
align-items: center;
}
.navbar-brand{
cursor: pointer;
}
.nav-parent{
margin-left: auto;
}
.navbar-nav{
display: flex;
align-items: center;
}
.navbar-nav li{
align-items: center;
}
.nav-link a{
margin-right: 2.5rem;
}
responsive
#media screen and (max-width: 768px) {
[aria-controls="navbarDropdown"] {
display: block;
}
[aria-expanded="false"] ~ ul{
display: none;
}
[aria-expanded="true"] ~ ul{
display: block;
}
}
javascript
<script>
const navButton = document.querySelector('button[aria-expanded]');
function toggleNav({ target }){
const expanded = target.getAttribute('aria-expanded') === 'true' || false;
navButton.setAttribute('aria-expanded', !expanded);
}
navButton.addEventListener('click', toggleNav);
</script>
Your css to select the ul via the button,
[aria-expanded="false"] ~ ul{
display: none;
}
[aria-expanded="true"] ~ ul{
display: block;
}
Won't work, here's why. The tilde (~) is a sibling selector. For this selector to work the way you specified, your ul would have to appear after the button, within the same container, like this:
<button ariaexpanded="true"></button>
<ul class="navbar-nav">
<li class="nav-link">
Home
</li>
</ul>
So if your .nav-parent div isn't being used, you could try remove that and it will likely work.
This is my approach when doing mobile menus. Have your media query target a certain container which goes to 100% viewport width and height at your mobile breakpoint. It should also be offset vertically or horizontally out of the view of the user. Then you just need some JS to toggle a 'showing' class which positions the menu on the user's screen:
Your toggle nav function:
function toggleNav({ target }){
const expanded = target.getAttribute('aria-expanded') === 'true' || false;
navButton.setAttribute('aria-expanded', !expanded);
// Toggle nav 'showing' class
if (nav.classList.contains('showing')) {
nav.classList.remove('showing')
} else {
nav.classList.add('showing')
}
}
// Close menu button
closeNavButton.addEventListener('click', () => {
nav.classList.remove('showing')
})
CSS:
/* Don't show the 'close' button on desktop */
.nav-parent button {
display: none;
}
/* Mobile breakpoint */
#media screen and (max-width: 768px) {
[aria-controls="navbarDropdown"] {
display: block;
}
[aria-expanded="false"] ~ ul{
display: none;
}
/* Your menu now takes up 100% of screen, and is offset to the left */
.nav-parent {
opacity: 0;
position: absolute;
height: 100vh;
width: 100vw;
top: 0;
left: -100vw;
transition: all 0.25s ease;
background: white;
}
/* When the showing class is added, it will position itself on the screen */
.nav-parent.showing {
opacity: 1;
left: 0;
}
}
HTML (add a close-menu button)
<div class="nav-parent">
<button>
Close
</button>
<ul class="navbar-nav">
...
</div>
JSfiddle demo
There's lots of room for creativity.
Hi everyone hope you are all well, just wondering if someone could give me hand I have a nav bar that when screen is max-width 750px the nav links turn into toogle menu. My problem is I can't seem to get the toggle menu to open and close when I click on it,I have googled and tried a few different code sorces with no luck.
Any help will be very appreciated.
This is my current code.
$(document).ready(function() {
$("menu-toggle").on("click", function() {
$('nav').toggleClass('showing');
$('.nav ul').toggleClass('showing');
});
});
header .menu-toggle {
display: none;
}
/***** MEDIA QUERIES*****/
#media only screen and (max-width: 750px) {
header {
position: relative;
}
header ul {
width: 100%;
background: #666666;
max-height: 0px;
overflow: hidden;
}
.showing {
max-height: 100em;
}
header ul li {
width: 100%;
}
header ul li ul {
position: static;
display: block;
width: 100%;
}
header ul li ul li a {
padding: 10px;
background: #666666;
color: #ffffff;
padding-left: 50px;
}
header ul li ul li a.logout {
color: #ff0000;
}
header .menu-toggle {
display: block;
position: absolute;
right: 20px;
top: 20px;
font-size: 1.9em;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-
awesome.min.css">
<header>
<div class="logo">
<img src="img/logo.png" alt="logo" />
</div>
<i class="fa fa-align-justify menu-toggle"></i>
<ul class="nav">
<li>Home</li>
<li>About</li>
<!--<li>Login</li> -->
<li>
<a href="#">
<i class="fa fa-user"></i> Nathan Ashbury
<i class="fa fa-chevron-down"></i>
</a>
<ul>
<li>Dashboard</li>
<li>Logout</li>
</ul>
</li>
</ul>
</header>
Modify the jquery .menu-toggle to toggle onclick() function
$(document).ready(function () {
$(".menu-toggle").on("click", function () {
$('.nav').toggleClass('showing');
$('.nav ul').toggleClass('showing');
});
});
Your nav is a class, use $('.nav').
You have not written CSS for the class name .showing for .nav or .nav ul. So, nothing will happen even if you click.
For my webpage (Github Page), I want to make my menu sensible to the size of the screen, such that it collapses when they are too small and the elements do not fit. I am planning to add the following solution: w3schools, using a "burguer" icon to join all the elements when the screens are small.
I am able to create the menu with the different elements, to add the "burguer" icon, and then to hide it by default when the screen is big. However, the media queries and the js function must be wrong, because when I do my screen small, the "burguer" icon appears, but the other elements do not dissapear, and cliking on the "burguer" does nothing. I guess there is a mistakes or confussion with the id names somewhere. Could it be?
In the example from w3schools uses the div tab, but I am not. Is it indispensable for the example to work?
/* Toggle between adding and removing the "responsive" class to topnav when the user clicks on the icon */
function myFunction() {
var x = document.getElementById("nav");
if (x.className === "header_nav") {
x.className += " responsive";
} else {
x.className = "header_nav";
}
}
/* Header_nav ----- DRAFT */
#page-wrapper {
padding-top: 3.5em;
}
#header_nav {
background: rgba(0, 0, 0, 0);
box-shadow: 0 0 0.25em 0 rgba(0, 0, 0, 0);
cursor: default;
height: 3.5em;
left: 0;
line-height: 3.5em;
position: absolute;
top: 0;
width: 100%;
z-index: 100;
}
#header_nav .icon {
display: none;
}
#header_nav h1 {
height: inherit;
left: 1.25em;
line-height: inherit;
margin: 0;
position: absolute;
top: 0;
}
#header_nav nav {
position: absolute;
right: 1em;
top: 0;
}
#header_nav nav ul {
margin: 0;
}
#header_nav nav ul li {
display: inline-block;
margin-left: 1em;
}
#header_nav nav ul li a,
#header_nav nav ul li span {
border: 0;
color: inherit;
display: inline-block;
height: inherit;
line-height: inherit;
outline: 0;
}
#header_nav nav ul li a.button,
#header_nav nav ul li span.button {
height: 2em;
line-height: 2em;
padding: 0 1.25em;
}
#header_nav nav ul li a:not(.button):before,
#header_nav nav ul li span:not(.button):before {
margin-right: 0.5em;
}
#header_nav nav ul li.active>a,
#header_nav nav ul li.active>span {
color: #e44c65;
}
#header_nav nav ul li>ul {
display: none;
}
body.landing #page-wrapper {
padding-top: 0;
}
body.landing #header_nav {
background: transparent;
box-shadow: none;
position: absolute;
}
/* When the screen is less than 600 pixels wide, hide all links, except for the first one ("Home"). Show the link that contains should open and close the topnav (.icon) */
#media screen and (max-width: 600px) {
#header_nav a:not(:first-child) {
display: none;
}
#header_nav a.icon {
float: right;
display: block;
}
}
/* The "responsive" class is added to the topnav with JavaScript when the user clicks on the icon. This class makes the topnav look good on small screens (display the links vertically instead of horizontally) */
#media screen and (max-width: 600px) {
#header_nav.responsive {
position: relative;
}
#header_nav.responsive a.icon {
position: absolute;
right: 0;
top: 0;
}
#header_nav.responsive a {
float: none;
display: block;
text-align: left;
}
}
<html>
<head>
<title>Eduardo Alvarado</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<link rel="stylesheet" href="assets/css/main.css" />
<noscript><link rel="stylesheet" href="assets/css/noscript.css" /></noscript>
<!-- Load an icon library to show a hamburger menu (bars) on small screens -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body class="is-preload">
<!-- Header Navigation Menu -->
<section id="header_nav">
<nav id="nav">
<ul>
<li>
<a href="index">
<p style="color:white">Home</p>
</a>
</li>
<li>
<a href="">
<p style="color:white">Research</p>
</a>
</li>
<li>
<a href="">
<p style="color:white">Game-dev</p>
</a>
</li>
<li>
<a href="photography">
<p style="color:white">Photography</p>
</a>
</li>
<li><i class="fa fa-bars"></i></li>
</ul>
</nav>
</section>
The whole code can be found in the repo (Github Repo).
Can you see maybe the error that I am not able to spot? Why the example from w3school is not applicable?
I would really appreciate your help here. Thank you very much in advance!
Here's a small reproducible solution based on your code:
https://jsfiddle.net/hneromu4/5/
I added a class fixed to the link elements that were supposed to stay when we resized the window:
<section id="header_nav">
<nav id="nav">
<ul>
<li class="fixed">Home</li>
<li>Research</li>
<li>Game-dev</li>
<li>Photography</li>
<li class="fixed hamburguer"><i class="fa fa-bars"></i></li>
</ul>
</nav>
</section>
I also tweaked your css and js.
In your CSS and HTML I have made some alterations as your hamburger menu was inside the same thing which you were trying to hide which is not really a good idea I have also adjusted your CSS slightly as you were setting a position to relative but not setting display to block. Hope this helps!
CSS (line 2525 - 2547):
#media screen and (max-width: 600px) {
#nav {display: none;}
#header_nav a.icon {
float: right;
display: block;
}
}
/* The "responsive" class is added to the topnav with JavaScript when the user clicks on the icon. This class makes the topnav look good on small screens (display the links vertically instead of horizontally) */
#media screen and (max-width: 600px) {
#nav.responsive {position: relative;display: block;}
#header_nav.responsive a.icon {
position: absolute;
right: 0;
top: 0;
}
#nav.responsive a {
float: none;
display: block;
text-align: left;
}
}
HTML:
<!-- Header Navigation Menu -->
<section id="header_nav">
<a class="icon" onclick="myFunction()"><i class="fa fa-bars"></i></a><nav id="nav" class="header_nav">
<ul>
<li><p style="color:white">Home</p></li>
<li><p style="color:white">Research</p></li>
<li><p style="color:white">Game-dev</p></li>
<li><p style="color:white">Photography</p></li>
</ul>
</nav>
</section>
I have a dropdown navigation bar, and when elements like buttons or images are too high up on the page, the navigation bar pushes the elements to the right side when drop-down options appear. How do I stop this?
Navbar:
<nav id="nav1">
<ul>
<li>Home</li>
<li onmouseover = "DropDown1()" onmouseout="DropUp1()">Images<ul class="DropUp" id="Droplist1" >
<li class="DropDown"><a id="Droplist1" href="#">Test1</a></li>
<li class="DropDown">Test2</li>
<li class="DropDown">Test3</li></ul>
</li>
<li onmouseover = "DropDown2()" onmouseout="DropUp2()">Adverts<ul id="Droplist2" class="DropUp">
<li class="DropDown">Test1</li>
<li class="DropDown">Test2</li></ul>
</li>
<li>Data Validation</li>
<li>Security</li>
</ul>
</nav>
CSS:
nav#nav1 li a {
display: block;
padding: 3px 8px;
background-color: #5e8ce9;
color: #fff;
text-decoration: none;
}
nav#nav1 li {
list-style: none;
float: left;}
.DrowDown {
display: block;
position: absolute;
margin: 0;
padding: 0;
float: none;
}
nav#nav1 li:hover li {
float: none; }
nav#nav1 li:hover li a {
background-color: #69f;
border-bottom: 1px solid #fff;
color: #000; }
#navbar li li a:hover {
background-color: #8db3ff; }
nav#nav1 ul li a:hover { background: #686868 ; }
nav#nav1 ul li a:active { background: #F0F0F0; }
JavaScript functions for dropdown:
function DropDown2() {
var t = document.getElementById("Droplist2");
t.className = "DropDown";
}
function DropDown1() {
var t = document.getElementById("Droplist1");
t.className = "DropDown";
}
function DropUp2() {
var t = document.getElementById("Droplist2");
t.className = "DropUp";
}
function DropUp1() {
var t = document.getElementById("Droplist1");
t.className = "DropUp";
}
If you are wondering why I took such a difficult route for making the navigation bar, it's because I have to use JavaScript.
Here is JS fiddle example: http://jsfiddle.net/fNPvf/10015/
The window is small in the fiddle, and the effect is slightly different, but notice how when you hover over "Data Validation" the dropdown menu pushes the text/image/body downwards?
You need absolute positioning and a higher z-index for either the containing <div> or the <ul> itself. Just add this to your code and adjust the z-index as needed:
nav#nav1 ul{
position: absolute;
top: 0;
z-index: 9;
}
See working demo here
I am making a drop-up using li nested in ul but am not able to set the width of li to dynamically match the width of the ul.
Please note that the li elements are constricted within a drop-up list.
The below looks like too much css but in essence it's just about the ul and li.
THE CSS
<style type="text/css" media="screen, tv, projection">
/* - - - ADxMenu: BASIC styles - - - */
/* remove all list stylings
.menu, .menu ul {
margin: 0;
padding: 0;
border: 0;
list-style-type: none;
display: block;
}
*/
.menu li {
margin: 0;
padding: 0;
border: 0;
display: block;
float: left; /* move all main list items into one row, by floating them */
position: relative; /* position each LI, thus creating potential IE.win overlap problem */
z-index: 5; /* thus we need to apply explicit z-index here... */
}
.menu li:hover {
z-index: 10000; /* ...and here. this makes sure active item is always above anything else in the menu */
white-space: normal;/* required to resolve IE7 :hover bug (z-index above is ignored if this is not present)
see http://www.tanfa.co.uk/css/articles/pure-css-popups-bug.asp for other stuff that work */
}
.menu li li {
float: none;/* items of the nested menus are kept on separate lines */
}
.menu ul {
visibility: hidden; /* initially hide all submenus. */
position: absolute;
z-index: 10;
left: 0; /* while hidden, always keep them at the bottom left corner, */
bottom: 0; /* to avoid scrollbars as much as possible */
}
.menu li:hover>ul {
visibility: visible; /* display submenu them on hover */
bottom: 100%; /* 1st level go above their parent item */
}
.menu li li:hover>ul { /* 2nd+ levels go on the right side of the parent item */
bottom: 0;
left: 100%;
}
/* -- float.clear --
force containment of floated LIs inside of UL */
.menu:after, .menu ul:after {
content: ".";
height: 0;
display: block;
visibility: hidden;
overflow: hidden;
clear: both;
}
.menu, .menu ul { /* IE7 float clear: */
min-height: 0;
}
.menu ul ul {
padding: 30px 30px 30px 10px;
margin: 0 0 -30px -10px;
}
/* - - - ADxMenu: DESIGN styles - - - */
.menu, .menu ul li {
color: #eee;
background: #000;
}
.menu ul {
background: #000;
width: 11em;
}
.menu a {
text-decoration: none;
padding: .4em 1em;
display: block;
position: relative;
font-family:BlairMdITCTTMedium;
color:#848484;
font-size:11px;
}
.menu a:hover, .menu li:hover>a {
color: #ccc;
}
.menu li li { /* create borders around each item */
border: 1px solid #000;
}
.menu ul>li + li { /* and remove the top border on all but first item in the list */
border-top: 0;
}
.menu li li:hover>ul { /* inset 2nd+ submenus, to show off overlapping */
bottom: 5px;
left: 90%;
}
/* Fix for IE5/Mac \*//*/
.menu a {
float: left;
}
/* End Fix */
/*]]>*/
</style>
**THE HTML CODE**
<ul class="menu">
<li style="width:80px;">
<a id="menu1" title="View all posts filed under Accessories" href="http://monique-relander.be/objects/accessories/">Accessories</a>
<ul>
<li>Home</li>
<li>Feeds</li>
<li>Archive</li>
</ul>
</li>
<li style="width:80px;">
<a title="View all posts filed under Furniture" href="http://monique-relander.be/objects/furniture/">Furniture</a>
<ul>
<li>Home</li>
<li>Feeds</li>
<li>Archive</li>
</ul>
</li>
<li style="width:80px;">
<a title="View all posts filed under Lighting" href="http://monique-relander.be/objects/lighting/">Lighting</a>
<ul>
<li>Home</li>
<li>Feeds</li>
<li>Archive</li>
</ul>
</li>
<li style="width:80px;">
<a title="View all posts filed under Mirrors" href="http://monique-relander.be/objects/mirrors/">Mirrors</a>
<ul>
<li>Home</li>
<li>Feeds</li>
<li>Archive</li>
</ul>
</li>
<li class="none" style="width:140px;">
<a title="View all posts filed under NEW ARRIVALS" href="http://monique-relander.be/objects/new-arrivals/">New Arrivals</a></li>
<li style="width:130px;">
<a title="View all posts filed under Sold Gallery" href="http://monique-relander.be/objects/sold-gallery/">Sold Gallery</a></li>
<li class="cat-item right">
Contact</li>
</ul>
The width of the li seems to be the same as the ul by default.
Atleast based on my experiments here http://jsfiddle.net/dwCsW/
If you remove the ul width it will be 100%, and by setting ul width the li will follow.
So there must be something else in your code removing that.
You could either give the li's a percentage width in the css... there are 7 of them, right? so maybe make each 10% wide, put 4% between each one and 3% at the beginning and end? Or, you could use JavaScript and detect the page resize event, then get the page/ul width and set the width of each li item using some good ol' fashioned number crunchin'!