I'm trying to hide a mobile nav menu when the user resizes the screen past a certain point (767px). I thought this would be fairly straight-forward, but I can't get it to work. Any suggestions?
ps My constrainNav function is being called in the body tag (not shown).
// Toggle between hamburger and full mobile menu //
const nav = document.getElementById("mobile-nav");
const hamburger = document.getElementById("hamburger");
const width = window.innerWidth;
function navToggle() {
if (nav.style.display === "") {
nav.style.display = "block";
} else {
nav.style.display = "";
}
}
// Keep mobile-nav visible only when 767px or less
function constrainNav() {
if (nav && width > 767) {
nav.style.display = "none";
}
}
<nav class="nav">
<div id="navbar" class="nav__navbar"">
<div class="nav__left">
<img src="src/assets/img/Grieve-logo.png" class="nav__img" alt="grieve logo">
</div>
<div class="nav__right">
<ul class="nav__list">
<li class="nav__list-item"><a class="nav__list__link" href="#">Wines</a></li>
<li class="nav__list-item"><a class="nav__list__link" href="#">Vineyard</a></li>
<li class="nav__list-item"><a class="nav__list__link" href="#">About</a></li>
<li class="nav__list-item"><a class="nav__list__link" href="#">Winemaker</a></li>
<li class="nav__list-item"><a class="nav__list__link" href="#">Visit</a></li>
<li class="nav__list-item"><a class="nav__list__link" href="#">Buy</a></li>
</ul>
<i class="fa fa-bars"></i>
</div>
<div class="nav__navbar nav__navbar--mobile" id="mobile-nav">
<div class="nav__left nav__left--mobile">
<img src="src/assets/img/XXXXXX-logo.png" class="nav__img" alt="XXXXX logo">
<i class="fa fa-bars"></i>
</div>
<ul class="nav__list--mobile">
<li class="nav__list__item--mobile"><a class="nav__list__link--mobile" href="#">Wines</a></li>
<li class="nav__list__item--mobile"><a class="nav__list__link--mobile" href="#">Vineyard</a></li>
<li class="nav__list__item--mobile"><a class="nav__list__link--mobile" href="#">About</a></li>
<li class="nav__list__item--mobile"><a class="nav__list__link--mobile" href="#">Winemaker</a></li>
<li class="nav__list__item--mobile"><a class="nav__list__link--mobile" href="#">Visit</a></li>
<li class="nav__list__item--mobile"><a class="nav__list__link--mobile" href="#">Buy</a></li>
</ul>
</div>
</div>
</nav>
.nav {
position: sticky; // * curious to see how this works once we get to browser testing.
top: 0;
margin-top: -3px; // * necessary maybe? Not sure how to get rid of that small gap above the nav.
height: 100%;
&__navbar {
width: 100%;
overflow: hidden;
height: 3rem;
background-color: $colorPrimary;
display: flex;
justify-content: space-between;
padding: 0 1.5rem;
align-items: center;
&--mobile {
display: none;
position: absolute;
top: -17.625rem;
left: 0;
background-color: $colorSecondary;
max-width: 100%;
height: auto;
}
}
&__left {
color: $colorWhite;
margin: 0.75rem 0 0 0;
&--mobile {
display: flex;
justify-content: space-between;
}
}
&__img {
width: 5.625rem;
}
&__right {
margin: 0;
}
&__hamburger {
display: none;
color: $colorWhite;
margin: 0;
#include respond(med) {
display: block;
}
}
&__list {
list-style: none;
display: flex;
text-transform: uppercase;
justify-content: center;
#include respond(med) {
display: none;
}
&--mobile {
display: flex;
flex-direction: column;
list-style: none;
padding: 8rem 0;
align-items: center;
}
&__link {
text-decoration: none;
color: $colorWhite;
cursor: pointer;
text-transform: uppercase;
font-size: 1rem;
margin: 0 1rem;
#media (max-width: 40.625rem) {
margin: 0 0.5rem;
}
&--mobile {
text-decoration: none;
color: $colorWhite;
cursor: pointer;
text-transform: uppercase;
font-size: 1rem;
margin: 0 1rem;
#include respond(med) {
font-size: 2rem;
}
}
}
&__item {
&--mobile {
padding: 2rem;
}
}
}
}
I think this should be enough code. I can provide more. Thanks!
use css media query, in this case you dont need javascript.
#media screen and (min-width: 767px) {
.nav {
display: none
}
}
Related
Why is the menu bar not visible in tablet mode. I have to click on the colored part to see it. It works well in mobile mode but has problems in tablet mode. I checked everything but did not understand how the collapsible__content class does not work in tablet mode.
Now in tablet mode, the navigation is not visible and I have to click on the gray bar to make the menus appear, while in tablet mode, you do not need to click on the menu to be seen.
index.html
<header>
<nav class="nav collapsible">
<a class="nav__brand" href="#">Gustoso</a>
<svg class="icon icon--white nav__toggler">
<use href="images/sprite.svg#menu"></use>
</svg>
<ul class="list nav__list collapsible__content">
<li class="nav__item">
Welcome<span class="between__nav">~</span>
</li>
<li class="nav__item">
Menu<span class="between__nav">~</span>
</li>
<li class="nav__item">
reservations<span class="between__nav">~</span>
</li>
<li class="nav__item">
News<span class="between__nav">~</span>
</li>
<li class="nav__item">
Contact
</li>
</ul>
</nav>
</header>
<script src="js/main.js"></script>
style.css
.list {
list-style-type: none;
padding-left: 0;
}
/* Navigation Bar */
header {
background: rgba(86, 83, 76, 0.5294117647058824);
}
.nav {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
align-items: center;
padding: 0.6rem 1rem;
}
.nav__list {
width: 100%;
margin: 0;
}
.nav__item {
padding: 0.9rem 0.2rem;
border-bottom: 1px solid #826c6c;
}
.nav__item > a:hover {
font-weight: bolder;
}
.nav__item > a {
color: var(--color-heading);
text-transform: uppercase;
font-size: 1.7rem;
}
.nav__item > a span {
display: none;
}
.between__nav {
margin: auto 0.9rem;
font-size: 1.4rem;
font-weight: 400;
}
.nav__brand {
font-family: scriptina, Arial, Helvetica, sans-serif;
font-size: 3rem;
letter-spacing: 9px;
line-height: 24px;
color: #ffffff;
transform: translateY(-11px);
}
.nav__toggler {
opacity: 0.5;
cursor: pointer;
transition: all 0.15s;
}
.nav.collapsible--expanded .nav__toggler {
opacity: 1;
box-shadow: 0 0 0 3px #666;
border-radius: 5px;
transform: rotate(-90deg);
}
#media screen and (min-width: 768px) {
.nav__toggler {
display: none;
}
.nav__list {
max-height: 100%;
opacity: 1;
width: auto;
display: flex;
font-size: 1.6rem;
}
.nav__item {
border: 0;
}
.nav__item > a span {
display: inline-flex;
}
}
/* Collapsibles */
.collapsible__content {
max-height: 0;
opacity: 0;
overflow: hidden;
transition: all 0.3s;
}
.collapsible--expanded .collapsible__content {
max-height: 100vh;
opacity: 1;
}
main.js
const collapsibles = document.querySelectorAll(".collapsible");
collapsibles.forEach((item) =>
item.addEventListener("click", function () {
this.classList.toggle("collapsible--expanded");
})
);
I am building up my skills by designing a mini web pag
so I started the navigation bar .
The button "Template" is supposed to change the view of the and display the lists but when I click it nothing happens.
Can anyone help me ?
The code:
html:
<div class="menu-toggle">
<h1 id="logo">PROTOCOL</h1>
<li class="right table" id="table"><a class="list template" href="#template" >☰</a></li>
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</div>
<ul id="navigate" class="navigate">
<li><a class="list home" href="#home"> Home</a></li>
<li><a class="list" href="#conntacting">Contact us</a></li>
<li class="right"><a class="list sign-up" href="#signing">Sign up</a></li>
<li class="right"><a class="list" href="#logging">Log in</a></li>
</ul>
</nav>
CSS:
I designed my navigation bar to be displayed when the user press the "template" button
and hide it again by pressing the same button.
#media screen and ( max-width : 675px){
.container{
position: relative;
}
.menu-toggle{
text-align: center;
float: none;
display: block;
}
.template{
display: inline;
float: right;
padding: 0 40px;
margin: auto;
}
li.table{
left: 80px;
height: 20px;
}
.nav{
height: 90px;
}
.template:hover{
display: inline;
float: right;
padding: 0 40px;
margin: auto;
}
.navigate,.active{
text-align: center;
display: grid;
grid-template-columns: auto;
background-color: #b00000;
margin: 0;
width: 100%;
position: absolute;
top:90px;
transition: all 0.5 ease;
left: 100%;
}
li.right{
display: table;
padding: 0;
}
.menu-toggle.bar{
width: 25px;
height: 3px;
margin: 5px auto;
transition: all 0.3s ease-in-out;
box-sizing: border-box;
}
.active{
text-align: center;
display: grid;
grid-template-columns: auto;
background-color: #b00000;
margin: 0;
width: 100%;
position: absolute;
top:90px;
transition: all 0.5 ease;
}
}
JavaScript:
I brought the button "template" and "ul" by it ids
var template = document.getElementById('template');
var nav = document.getElementById('navigate');
template.onclick = function () {
if (nav.className === ('navigate')) {
nav.className += 'active';
} else {
nav.className = 'navigate';
};
You can use classList.toggle method.
Also, to tidy up things, I've removed the list buttons, changed menu font color to white, and removed the duplicated CSS on classes navigate and active: now .active just displays the navigation menu.
(The navigation menu was exploding the width when opened, and it was clobbering the menu icon, so I just removed position: absolute; and width: 100% from it)
Far from done here. Try to change things in steps, and to study the css rules on MDN, instead of doing many things at once.
var template = document.querySelector('.template');
var nav = document.querySelector('.navigate');
template.onclick = function() {
nav.classList.toggle('active');
};
#media screen and ( max-width: 675px) {
.container {
position: relative;
}
.menu-toggle {
text-align: center;
float: none;
display: block;
}
.template {
display: inline;
float: right;
padding: 0 40px;
margin: auto;
}
li.table {
left: 80px;
height: 20px;
}
.nav {
height: 90px;
}
.template:hover {
display: inline;
float: right;
padding: 0 40px;
margin: auto;
}
.navigate {
text-align: center;
display: none;
background-color: #b00000;
list-style: none;
margin: 0;
left: 0;
top: 90px;
transition: all 0.5 ease;
}
a.list:not(.template) {
text-decoration: none;
color: white;
}
li.right {
display: table;
padding: 0;
}
.menu-toggle.bar {
width: 25px;
height: 3px;
margin: 5px auto;
transition: all 0.3s ease-in-out;
box-sizing: border-box;
}
.active {
display: grid;
grid-template-columns: auto;
}
<div class="menu-toggle">
<h1 id="logo">PROTOCOL</h1>
<li class="right table" id="table"><a class="list template" href="#template">☰</a></li>
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</div>
<nav id="navigate">
<ul class="navigate">
<li><a class="list home" href="#home"> Home</a></li>
<li><a class="list" href="#contacting">Contact us</a></li>
<li class="right"><a class="list sign-up" href="#signing">Sign up</a></li>
<li class="right"><a class="list" href="#logging">Log in</a></li>
</ul>
</nav>
your code has many mistakes please create button having template class.
however i updated your javascript for current use
template.onclick = function () {
if (nav.className === 'navigate') {
nav.classList.remove('navigate')
nav.className = 'active';
}
else {
nav.classList.remove('active')
nav.className = 'navigate';
}
}
}
I have taken over the code from this post. As I have explained there, I have basically no HTML knowledge, yet I have this HTML part of my project that I have to finish.
So, the code creates a bar with a drop-down menu, but I want to extend it to have an icon next to the names. I have looked at these examples but I can't figure out how to combine them. Is there someone who could help?
const projectsTab = document.getElementById('projects')
const tabName = projectsTab.querySelector('.tab-name')
const projectLinks = document.querySelector('.project-links')
projectsTab.addEventListener('click', e => {
const isOpen = projectLinks.classList.contains('open')
if (isOpen) projectLinks.classList.remove('open')
else projectLinks.classList.add('open')
})
// link event listeners
const links = [...projectLinks.children] // turn this into an array
links.forEach(link => link.addEventListener('click', e => {
tabName.innerText = link.innerText
}))
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Segoe UI', sans-serif;
}
nav {
position: fixed;
width: 100%;
height: 50px;
background: #222;
top: 0;
left: 0;
color: white;
display: flex;
}
nav>* {
flex: 1;
}
#logo {
padding-left: 20px;
font-size: 30px;
text-transform: uppercase;
letter-spacing: 2px;
display: flex;
justify-content: flex-start;
align-items: center;
}
nav ul {
display: flex;
list-style: none;
height: 100%;
}
nav ul li {
position: relative;
flex: 1;
background: #222;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: 0.2s;
}
nav ul li:hover {
background: #555;
}
.project-links {
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
left: 0;
top: 100%;
width: 100%;
background-color: white;
color: black;
/* This is the height of this div + height of the nav bar */
transform: translateY(-135%);
transition: 0.2s;
z-index: -1;
}
.project-links.open {
transform: translateY(0);
}
.project-link {
height: 50px;
display: flex;
align-items: center;
padding-left: 20px;
text-decoration: none;
color: white;
cursor: pointer;
transition: 0.2s;
background: #222;
color: white;
}
.project-link:hover {
background: #555;
}
<nav>
<div id="logo">Logo</div>
<ul>
<li>About</li>
<li id="projects">
<span class="tab-name">Projects</span>
<div class="project-links">
<a class="project-link" href="#">Link 1</a>
<a class="project-link" href="#">Link 2</a>
<a class="project-link" href="#">Link 3</a>
</div>
</li>
<li>Contact</li>
</ul>
</nav>
Assuming you want to use Font Awesome icons, just add the proper i tag referencing the right icon beside the text in the corresponding a tags.
const projectsTab = document.getElementById('projects')
const tabName = projectsTab.querySelector('.tab-name')
const projectLinks = document.querySelector('.project-links')
projectsTab.addEventListener('click', e => {
const isOpen = projectLinks.classList.contains('open')
if (isOpen) projectLinks.classList.remove('open')
else projectLinks.classList.add('open')
})
// link event listeners
const links = [...projectLinks.children] // turn this into an array
links.forEach(link => link.addEventListener('click', e => {
tabName.innerText = link.innerText
}))
document.addEventListener("click", e => {
if(!projectsTab.contains(e.target)){
projectLinks.classList.remove("open");
}
})
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Segoe UI', sans-serif;
}
nav {
position: fixed;
width: 100%;
height: 50px;
background: #222;
top: 0;
left: 0;
color: white;
display: flex;
}
nav>* {
flex: 1;
}
#logo {
padding-left: 20px;
font-size: 30px;
text-transform: uppercase;
letter-spacing: 2px;
display: flex;
justify-content: flex-start;
align-items: center;
}
nav ul {
display: flex;
list-style: none;
height: 100%;
}
nav ul li {
position: relative;
flex: 1;
background: #222;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: 0.2s;
}
nav ul li:hover {
background: #555;
}
.project-links {
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
left: 0;
top: 100%;
width: 100%;
background-color: white;
color: black;
/* This is the height of this div + height of the nav bar */
transform: translateY(-135%);
transition: 0.2s;
z-index: -1;
}
.project-links.open {
transform: translateY(0);
}
.project-link {
height: 50px;
display: flex;
align-items: center;
padding-left: 20px;
text-decoration: none;
color: white;
cursor: pointer;
transition: 0.2s;
background: #222;
color: white;
}
.project-link:hover {
background: #555;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<nav>
<div id="logo">Logo</div>
<ul>
<li>About</li>
<li id="projects">
<span class="tab-name">Projects</span>
<div class="project-links">
<a class="project-link" href="#"><i class="fa fa-envelope"></i> Link 1</a>
<a class="project-link" href="#"><i class="fa fa-envelope"></i> Link 2</a>
<a class="project-link" href="#"><i class="fa fa-envelope"></i> Link 3</a>
</div>
</li>
<li>Contact</li>
</ul>
</nav>
To close the dropdown when the user clicks elsewhere, add an event listener for click and check whether the target is a subchild of projectsTab.
Since your dropdown menu elements are already flex containers, you can simply add an image at the beginning of each of them, give them a class (icon) and change a bit the padding. Here I put icon { padding: 3px; } and I removed the 20px padding at the beginning of menu elements, because it squished the images against the text.
I also added some JavaScript to close the menu when you click elsewhere.
const projectsTab = document.getElementById('projects')
const tabName = projectsTab.querySelector('.tab-name')
const projectLinks = document.querySelector('.project-links')
projectsTab.addEventListener('click', e => {
const isOpen = projectLinks.classList.contains('open')
if (isOpen) projectLinks.classList.remove('open')
else projectLinks.classList.add('open')
})
addEventListener('click', e => {
var target = e.target;
if (!(target.classList.contains('project-link') || target.classList.contains('project-link') || target.classList.contains('tab-name') || target.id == "projects")) {
projectLinks.classList.remove('open');
} else {
e.stopPropagation();
}
});
// link event listeners
const links = [...projectLinks.children] // turn this into an array
links.forEach(link => link.addEventListener('click', e => {
tabName.innerText = link.innerText
}))
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Segoe UI', sans-serif;
}
nav {
position: fixed;
width: 100%;
height: 50px;
background: #222;
top: 0;
left: 0;
color: white;
display: flex;
}
nav>* {
flex: 1;
}
#logo {
padding-left: 20px;
font-size: 30px;
text-transform: uppercase;
letter-spacing: 2px;
display: flex;
justify-content: flex-start;
align-items: center;
}
nav ul {
display: flex;
list-style: none;
height: 100%;
}
nav ul li {
position: relative;
flex: 1;
background: #222;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: 0.2s;
}
nav ul li:hover {
background: #555;
}
.project-links {
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
left: 0;
top: 100%;
width: 100%;
background-color: white;
color: black;
/* This is the height of this div + height of the nav bar */
transform: translateY(-135%);
transition: 0.2s;
z-index: -1;
}
.project-links.open {
transform: translateY(0);
}
.project-link {
height: 50px;
display: flex;
align-items: center;
padding-left: 5px;
text-decoration: none;
color: white;
cursor: pointer;
transition: 0.2s;
background: #222;
color: white;
}
.project-link:hover {
background: #555;
}
.icon {
padding-right: 3px;
}
<nav>
<div id="logo">Logo</div>
<ul>
<li>About</li>
<li id="projects">
<span class="tab-name">Projects</span>
<div class="project-links">
<a class="project-link" href="#"><img class="icon" src="http://lorempixel.com/20/20/cats/">Link 1</a>
<a class="project-link" href="#"><img class="icon" src="http://lorempixel.com/20/20/cats/">Link 2</a>
<a class="project-link" href="#"><img class="icon" src="http://lorempixel.com/20/20/cats/">Link 3</a>
</div>
</li>
<li>Contact</li>
</ul>
</nav>
This is actually pretty easy just like the example you linked to first add the link to the icon library inside the <head></head> tag of your html:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
then add the <i/> tag inside the <a></a> tag of your drop down. Your html code should look like so
<nav>
<div id="logo">Logo</div>
<ul>
<li>About</li>
<li id="projects">
<span class="tab-name">Projects</span>
<div class="project-links">
<a class="project-link" href="#"><i class="fa fa-home"/>Link 1</a>
<a class="project-link" href="#"><i class="fa fa-search"/>Link 2</a>
<a class="project-link" href="#"><i class="fa fa-globe"/>Link 3</a>
</div>
</li>
<li>Contact</li>
</ul>
</nav>
Im setting up a onclick dropdown navigation bar for the mobile part of my website, The problem im having is when it takes a double click in order for it to drop down. The result I want is for it to drop down on the first click.
The only thing I've tried so far is a Javascript function that I will show in my code.
function myFunction() {
var x = document.getElementById("submenu1");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
function myFunction_2() {
var y = document.getElementById("submenu2");
if (y.style.display === "none") {
y.style.display = "block";
} else {
y.style.display = "none";
}
}
.main-nav {
display: flex;
}
.main-nav ul {
display: flex;
flex-wrap: wrap;
flex: 1;
list-style: none;
}
.main-nav li {
text-align: center;
position: relative;
width: 100%;
border-bottom: 1px solid white;
}
#submenu1 .submenu1-li:first-of-type {
border-top: 1px solid white;
}
.main-nav a {
display: flex;
display: block;
align-items: center;
justify-content: center;
flex: 1;
color: #fff;
background-color: #000;
padding: 5% 0%;
}
.submenu1-li {
position: absolute;
top: 0px;
}
#submenu1 {
display: none;
flex-direction: column;
position: absolute;
width: 100%;
}
.submenu2-li {
position: absolute;
top: 0px;
}
#submenu2 {
display: none;
flex-direction: column;
position: absolute;
width: 100%;
}
#submenu2 .submenu2-li:first-of-type {
border-top: 1px solid white;
}
#active {
background-color: #ffffff;
color: #000000;
height: 100%;
}
#submenu1 a:hover {
color: black;
background-color: white;
}
#desktop-port-move:hover #submenu2 {
display: block;
}
<nav class="main-nav">
<ul>
<li>
<a id="hide" href="javascript:void(0)" onclick="myFunction()">Menu
<span class="arrow">▼</span>
</a>
<ul id="submenu1">
<li class="submenu1-li">
<a id="active" href="home.html">Home</a>
</li>
<li class="submenu1-li">
About
</li>
<li id="desktop-contact-move" class="submenu1-li" >
Contact
</li>
<li id="desktop-port-move" class="submenu1-li" style:"order: 1;">
<a href="javascript:void(0)" onclick="myFunction_2();">Portfolio
<span class="arrow">▼</span>
</a>
<ul id="submenu2">
<li class="submenu2-li">
Designs
</li>
<li class="submenu2-li">
Websites
</li>
<li class="submenu2-li">
Photography
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
I expect the output to be a dropdown menu that responds on first click.
but the output im getting is a dropdown menu that responds on the second click, which is wrong for what I want.
Thanks in advance
and blessings to those who help
The reason it's not showing on the first click is that this condition
if (x.style.display === "none")
is false since you've set display: none; in CSS stylesheet. So a really quick way to fix this would be to add display: none; inline:
<ul id="submenu1" style="display:none;">
But a cleaner way would be to use classes to control menu visibility. See the snippet below.
function myFunction() {
var x = document.getElementById("submenu1");
x.classList.toggle('hidden');
}
.main-nav {
display: flex;
}
.main-nav ul {
display: flex;
flex-wrap: wrap;
flex: 1;
list-style: none;
}
.main-nav li {
text-align: center;
position: relative;
width: 100%;
border-bottom: 1px solid white;
}
#submenu1 .submenu1-li:first-of-type {
border-top: 1px solid white;
}
.main-nav a {
display: flex;
display: block;
align-items: center;
justify-content: center;
flex: 1;
color: #fff;
background-color: #000;
padding: 5% 0%;
}
.submenu1-li {
position: absolute;
top: 0px;
}
#submenu1 {
flex-direction: column;
position: absolute;
width: 100%;
}
#submenu1.hidden {
display: none;
}
.submenu2-li {
position: absolute;
top: 0px;
}
#submenu2 {
display: none;
flex-direction: column;
position: absolute;
width: 100%;
}
#submenu2 .submenu2-li:first-of-type {
border-top: 1px solid white;
}
#active {
background-color: #ffffff;
color: #000000;
height: 100%;
}
#submenu1 a:hover {
color: black;
background-color: white;
}
#desktop-port-move:hover #submenu2 {
display: block;
}
<nav class="main-nav">
<ul>
<li>
<a id="hide" href="javascript:void(0)" onclick="myFunction()">Menu
<span class="arrow">▼</span>
</a>
<ul id="submenu1" class="hidden">
<li class="submenu1-li">
<a id="active" href="home.html">Home</a>
</li>
<li class="submenu1-li">
About
</li>
<li id="desktop-contact-move" class="submenu1-li" >
Contact
</li>
<li id="desktop-port-move" class="submenu1-li" style:"order: 1;">
<a href="javascript:void(0)" onclick="myFunction_2();">Portfolio
<span class="arrow">▼</span>
</a>
<ul id="submenu2">
<li class="submenu2-li">
Designs
</li>
<li class="submenu2-li">
Websites
</li>
<li class="submenu2-li">
Photography
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
Ok so here the problem is that the x.style.display returns blank string because that property is defined in stylesheet.
1st solution is to use inline css
2nd is apply another check for blank string like this.
function myFunction() {
var x = document.getElementById("submenu1");
if (x.style.display === "none" || x.style.display === "") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
function myFunction_2() {
var y = document.getElementById("submenu2");
if (y.style.display === "none" || y.style.display === "") {
y.style.display = "block";
} else {
y.style.display = "none";
}
}
.main-nav {
display: flex;
}
.main-nav ul {
display: flex;
flex-wrap: wrap;
flex: 1;
list-style: none;
}
.main-nav li {
text-align: center;
position: relative;
width: 100%;
border-bottom: 1px solid white;
}
#submenu1 .submenu1-li:first-of-type {
border-top: 1px solid white;
}
.main-nav a {
display: flex;
display: block;
align-items: center;
justify-content: center;
flex: 1;
color: #fff;
background-color: #000;
padding: 5% 0%;
}
.submenu1-li {
position: absolute;
top: 0px;
}
#submenu1 {
display: none;
flex-direction: column;
position: absolute;
width: 100%;
}
.submenu2-li {
position: absolute;
top: 0px;
}
#submenu2 {
display: none;
flex-direction: column;
position: absolute;
width: 100%;
}
#submenu2 .submenu2-li:first-of-type {
border-top: 1px solid white;
}
#active {
background-color: #ffffff;
color: #000000;
height: 100%;
}
#submenu1 a:hover {
color: black;
background-color: white;
}
#desktop-port-move:hover #submenu2 {
display: block;
}
<nav class="main-nav">
<ul>
<li>
<a id="hide" href="javascript:void(0)" onclick="myFunction()">Menu
<span class="arrow">▼</span>
</a>
<ul id="submenu1">
<li class="submenu1-li">
<a id="active" href="home.html">Home</a>
</li>
<li class="submenu1-li">
About
</li>
<li id="desktop-contact-move" class="submenu1-li" >
Contact
</li>
<li id="desktop-port-move" class="submenu1-li" style:"order: 1;">
<a href="javascript:void(0)" onclick="myFunction_2();">Portfolio
<span class="arrow">▼</span>
</a>
<ul id="submenu2">
<li class="submenu2-li">
Designs
</li>
<li class="submenu2-li">
Websites
</li>
<li class="submenu2-li">
Photography
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
More information about the problem at : Fixing the Mobile Double-Click Link Issue
Let's say we have a navigation div which contains elements. Below navigation div there is some bar that must expand to the width where it matches one of the navigation elements (3rd one in this case).
<div id="main_navigator">
<div id="main_navigator_upper">
<a id="main_navigator_logo" src="/"></a>
<ul id="main_navigator_r1">
<li>
<a class="main_nav_btn">BTN 1</a>
</li>
<li>
<a class="main_nav_btn">BTN 2</a>
</li>
<li>
<a class="main_nav_btn">BTN 3</a>
</li>
<li>
<a class="main_nav_btn">BTN 4</a>
</li>
<li id="main_navigator_l1">
<div id="main_navigator_s1"></div>
</li>
<li>
<ul id="main_navigator_regbox">
<li>
<p id="regbox_signin">sign in</p>
</li>
<li>
<div id="main_navigator_regbox_s1"></div>
</li>
<li>
<a id="regbox_signup" href="sign_up">sign up</a>
</li>
</ul>
</li>
</ul>
</div>
<div id="main_navigator_bottom">
<div id="main_navigator_progression"></div>
</div>
</div>
From this code, main_navigator_progression div must expand its width so it matches BTN 3.
You can see the concept here.
I've written a simple JS code, but it doesn't seem to be neat and doesn't always work:
function initializeProgressorPos() {
document.getElementById("main_navigator_progression").setAttribute("style", ("width: " + (document.getElementsByClassName("main_nav_btn")[2].getBoundingClientRect().x - document.getElementsByClassName("main_nav_btn")[2].getBoundingClientRect().width) + "px"))
}
initializeProgressorPos();
$(window).resize(function() {
initializeProgressorPos();
});
Is there any way to create such a function that works even when browser is scaled? What could be wrong with my code? Is there any chance that this can be done with pure css?
As you have floatted the element to the right, first you have to get the width of document, then exclude the width from left of document to the right of element from that amount:
function initializeProgressorPos() {
var elementRight=$(document).width()- $('.main_nav_btn:eq(2)').offset().left - $('.main_nav_btn:eq(2)').width();
$("#main_navigator_progression").css({"width": elementRight + "px"});
}
initializeProgressorPos();
$(window).resize(function() {
initializeProgressorPos();
});
body {
margin: 0;
overflow-y: scroll;
}
#main_navigator {
position: fixed;
background-color: black;
width: 100%;
}
#main_navigator_upper {
position: relative;
display: flex;
flex-direction: row;
}
#main_navigator_logo {
width: 416px;
height: 120px;
background-color: white;
}
#main_navigator_r1 {
display: flex;
flex-direction: row;
align-items: center;
flex-grow: 1;
flex-shrink: 1;
padding: 0;
padding-right: 5%;
text-align: center;
margin-top: 0px;
height: 98px;
list-style-type: none;
}
#main_navigator_r1 li {
flex-grow: 1;
flex-shrink: 1;
/* flex-basis: 0; */
flex-basis: auto; /* new */
}
#main_navigator_l1 {
flex-grow: 0.1 !important;
}
#main_navigator_r1 li .main_nav_btn {
color: white;
display: block;
height: 100%;
font-family: "nexa_bold";
font-size: 0.9em;
text-decoration: none;
}
#main_navigator_s1 {
display: inline-block;
width: 2px;
height: 35px;
background-color: #B28039;
}
#main_navigator_regbox {
position: relative;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
list-style-type: none;
margin: 0px;
padding: 0px;
}
#main_navigator_regbox li {
display: inline-block;
flex-grow: 0.1;
flex-shrink: 0.1;
}
#regbox_signin {
display: block;
cursor: pointer;
white-space: nowrap;
text-decoration: none;
color: #B28039;
font-size: 0.9em;
font-family: "nexa_light";
}
#regbox_signup {
display: block;
white-space: nowrap;
text-decoration: none;
color: white;
font-size: 0.9em;
font-family: "nexa_light";
}
#main_navigator_regbox_s1 {
display: inline-block;
width: 1.4px;
height: 13.5px;
background-color: white;
}
#main_navigator_bottom {
background-color: black;
height: 24px;
}
#main_navigator_progression {
position: relative;
background-color: #B28039;
height: 100%;
width: 416px;
float: right;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<body>
<div id="main_navigator">
<div id="main_navigator_upper">
<a id="main_navigator_logo" src="/"></a>
<ul id="main_navigator_r1">
<li>
<a class="main_nav_btn">BTN 1</a>
</li>
<li>
<a class="main_nav_btn">BTN 2</a>
</li>
<li>
<a class="main_nav_btn">BTN 3</a>
</li>
<li>
<a class="main_nav_btn">BTN 4</a>
</li>
<li id="main_navigator_l1">
<div id="main_navigator_s1"></div>
</li>
<li>
<ul id="main_navigator_regbox">
<li>
<p id="regbox_signin">sign in</p>
</li>
<li>
<div id="main_navigator_regbox_s1"></div>
</li>
<li>
<a id="regbox_signup" href="sign_up">sign up</a>
</li>
</ul>
</li>
</ul>
</div>
<div id="main_navigator_bottom">
<div id="main_navigator_progression"></div>
</div>
</div>
</body>
</html>
This is a proof of concept.
You can use a combination of a custom HTML5 data-* attribute and an ::after pseudo-element on your navigation menu (and a dash of javascript) to indicate which menu item you have most recently selected.
Despite the dash of javascript, most of the work is done using CSS.
Working Example:
var menu = document.querySelector('nav ul');
var menuItems = [... menu.getElementsByTagName('li')];
function selectMenu() {
menu.dataset.selectedMenu = (menuItems.indexOf(this) + 1);
}
for (var i = 0; i < menuItems.length; i++) {
menuItems[i].addEventListener('click', selectMenu, false);
}
nav ul {
display: flex;
position: relative;
margin: 0;
padding: 0;
}
nav li {
flex: 0 0 60px;
padding: 12px 12px 24px;
color: rgb(255, 255, 255);
background-color: rgb(255, 0, 0);
list-style-type: none;
cursor: pointer;
}
nav ul::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
height: 12px;
background-color: rgba(0, 0, 0, 0.5);
transition: width 0.6s linear;
}
nav ul[data-selected-menu="1"]::after {
width: 80px;
}
nav ul[data-selected-menu="2"]::after {
width: 160px;
}
nav ul[data-selected-menu="3"]::after {
width: 240px;
}
nav ul[data-selected-menu="4"]::after {
width: 320px;
}
nav ul[data-selected-menu="5"]::after {
width: 400px;
}
<nav>
<ul data-selected-menu="1">
<li class="active">Menu 1</li>
<li>Menu 2</li>
<li>Menu 3</li>
<li>Menu 4</li>
<li>Menu 5</li>
</ul>
</nav>