Issue
I made a small multilevel navbar using vanilla JS and HTML & CSS. I cant seem to get the click one working. So the task is, have the navbar have hover if it is desktop version, and have click if it is a mobile version. Below will be my JS, CSS and HTML codes. I made a JS code so that it opens when I click, but cant seem to open its child element, which is another ul
, I tried everything and cant seem to get around it. I made a hover effect for the desktop version, but I just cant figure out how to do the JS version
let menu = document.querySelector(".menu ul");
menu = menu.children;
for (let i = 0; i < menu.length; i++) {
console.log(menu[i]);
menu[i].addEventListener("click", function() {
menu[i].firstElementChild.classList.toggle("show");
console.log(menu[i].firstElementChild);
});
}
.menu {
--menu-height: 40px;
box-sizing: border-box;
position: fixed;
top: 0;
left: 0;
width: 100vw;
}
.menu ul {
list-style: none;
padding: 16px;
margin: 0;
}
.menu ul li,
.menu ul li a {
opacity: 0.8;
color: #ffffff;
cursor: pointer;
transition: 200ms;
text-decoration: none;
white-space: nowrap;
font-weight: 700;
}
.menu ul li a,
.menu ul li a a {
display: flex;
align-items: center;
height: 100%;
width: 100%;
}
.menu ul li {
padding-right: 36px;
}
.menu ul li::before {
content: "";
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid #ffa500;
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
}
.menu ul .link::before {
padding-right: 0;
display: none;
}
.menu > ul {
display: flex;
height: var(--menu-height);
align-items: center;
background-color: #000000;
}
.menu > ul li {
position: relative;
margin: 0 8px;
}
.menu > ul li ul {
visibility: hidden;
opacity: 0;
padding: 0;
min-width: 160px;
background-color: #333;
position: absolute;
top: 45px;
left: 50%;
transform: translateX(-50%);
transition: 200ms;
transition-delay: 200ms;
}
.menu > ul li ul li {
margin: 0;
padding: 8px 16px;
display: flex;
align-items: center;
justify-content: flex-start;
height: 30px;
padding-right: 40px;
}
.menu > ul li ul li::before {
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 5px solid #ffa500;
}
.menu > ul li ul li ul {
top: -2%;
left: 100%;
transform: translate(0);
}
.show {
display: flex;
}
.hide {
display: none;
}
@media screen and (min-width: 1200px) {
.menu ul li:hover,
.menu ul li a:hover {
opacity: 1;
}
.menu > ul li ul li:hover {
background: black;
}
.menu > ul li:hover > ul {
opacity: 1;
visibility: visible;
transition-delay: 0ms;
}
}
@media screen and (max-width: 1200px) {
.menu {
height: 100vh;
top: 0;
left: 0;
width: 20vw;
}
.menu ul {
flex-direction: column;
height: 100vh;
}
.menu ul li {
margin: 1rem 0;
}
.menu ul li ul {
visibility: hidden;
opacity: 0;
padding: 0;
min-width: 160px;
background-color: #333;
position: absolute;
top: 0px;
left: 200%;
transform: translateX(-50%);
transition: 200ms;
transition-delay: 200ms;
height: fit-content;
}
}
<div class="menu">
<ul>
<li>
Parent 1
<ul>
<li class="link">
<a href="">Child 1</a>
</li>
<li class="link">
<a href="">Child 2</a>
</li>
<li>
Nested child
<ul>
<li class="link">
<a href="">Something</a>
</li>
<li class="link">
<a href="">Something</a>
</li>
</ul>
</li>
</ul>
</li>
<li>
Parent 2
<ul>
<li class="link">
<a href="">Basic link 1</a>
</li>
<li class="link">
<a href="">Basic link 2</a>
</li>
<li>
Nested child 2
<ul>
<li class="link">
<a href="">Basic nested link 1</a>
</li>
<li class="link">
<a href="">Basic nested link 2</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="link">Simple Link</li>
<li class="link">Another Link</li>
</ul>
</div>
Solution
Your JS code seem to do just fine. Add this style under the mobile media query:
.menu ul.show {
visibility: visible;
opacity: 1;
}
You are toggling the show class for the sub-menu upon clicking but not changing it's visibility and opacity property which initially has value hidden and 0 respectively hence, not showing upon click.
Moreover, instead of directly using menu item text inside top level li tags, I would do something like below for the ease of style, manipulation and semantics:
<li>
<span class="menu--item">Link</span>
<ul class="children">
<li>Child Link</li>
<li>Child Link</li>
</ul>
</li>
Answered By - Dorji Tshering
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.