I'm having a tough time with a mobile sub-menu on a nav menu I'm building for my website. I set it up so the sub-menu can be accessed by hovering the parent list item on desktop. This then shows a popup with the menu items. On mobile, however, users can access the sub-menu by clicking it, which, preferably, would open the menu and push down the other top level list items much like an accordion would.
My problem is that, when the menu opens on mobile view, it overlaps the other menu items and doesn't push them down like I want it to. I've tried looking up solutions and have tried to mess with CSS positioning to get it to work and I just can't figure it out.
My mobile nav menu opens in a sidebar that's actually a ul with an absolute position. Initially, I thought that was what the issue was, but I put a w3schools accordion in the middle of my menu as an experiment (not as a long term answer) and it pushed the other items down. So, I'm kinda thinking it's something else causing the problem because it seems like it is possible, based on my experiment, to get the other menu items to shift down when a menu or panel opens. I appreciate any ideas or help.
Here's my current menu code:
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function subOpen() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.sub-menu-link')) {
var dropdowns = document.getElementsByClassName("sub-menu-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
//Mobile menu toggle code
const menuBtn=document.querySelector(".menu-btn");let menuOpen=!1;menuBtn.addEventListener("click",()=>{menuOpen?(menuBtn.classList.remove("open"),menuOpen=!1,document.documentElement.style.overflow="scroll",document.body.scroll="yes"):(menuBtn.classList.add("open"),menuOpen=!0,document.documentElement.style.overflow="hidden",document.body.scroll="no")})
body {
margin: 0;
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #333;
background-color: #fff;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
text-decoration:none;
}
.header-cont,
.nav-link {
align-items: center;
}
.header-nav,
.nav-item {
height: 60px;
}
.header {
background: #fff;
box-shadow: 0 0 10px -3px rgb(0 0 0 / 50%);
}
.header-cont {
display: flex;
max-width: 1350px;
margin: auto;
justify-content: space-between;
padding: 0 1rem 0 1rem;
box-sizing: border-box;
}
.nav-link,
.sub-menu-link {
padding: 0 1rem 0 1rem;
font-weight: 600;
color: #0f0f0f !important;
cursor:pointer;
}
.header-menu li:last-child {
margin-bottom: 0;
padding-bottom: 0;
}
.only-mobile {
display: none !important;
}
.nav-item,
.nav-link {
display: inline-block;
}
.nav-item {
line-height: 60px;
}
.drop-chevron {
margin-left: 10px;
height: 13px;
fill: #0f0f0f;
}
.nav-item:hover svg {
fill: #00007a !important;
/* transform: rotate(180deg);*/
}
.nav-item:hover {
background-color: #00007a0d;
transition: background-color 0.3s;
}
.nav-link:hover,
.sub-menu-link:hover {
color: #00007a !important;
transition: 0.3s;
text-decoration: none !important;
}
.sub-menu {
position: relative !important;
}
.sub-menu-link {
display: inline-block !important;
text-decoration: none !important;
}
#check,
.checkbtn {
display: none;
}
.sub-menu-content {
display: none;
margin-top: -0.1rem;
background-color: #fff !important;
box-shadow: 0 6px 14px -1px rgb(0 5 20 / 15%);
border-radius: 3px;
overflow: hidden;
position: absolute;
width: 200px;
z-index: 1000;
}
.sub-menu-content ul{
list-style-type: none;
line-height: 30px;
}
.sub-item {
width: 200px;
margin-left: -0.5rem;
}
.sub-menu-content li:last-child {
border-bottom: 1px solid transparent !important;
padding-bottom: 0.1rem !important;
margin-bottom: -0.2rem;
}
.sub-menu-content a {
color: #0f0f0f;
width: 100%;
padding: 0.8rem;
margin-left: -2rem;
text-decoration: none;
display: block;
text-align: left;
border-left: solid 4px transparent;
}
.sub-menu-content a:hover {
text-decoration: none;
border-left: 4px solid #ff9f1c;
background-color: #00007a0d;
color: #00007a !important;
}
.checkbtn {
font-size: 20px;
color: #00007a;
float: right;
line-height: 60px;
margin-right: 1rem;
cursor: pointer;
}
@media (max-width: 1025px) {
selector .header-logo {
margin-top: 0.1rem;
padding-top: 0;
}
.header-cont {
justify-content: space-between;
}
.only-mobile,
.sub-menu-link {
display: block !important;
}
.checkbtn,
.nav-link,
.sub-menu {
display: block;
}
.drop-chevron {
display: inline-flex;
position:absolute;
right:17px;
top:22px;
}
.sub-menu-content {
padding:0;
background-color: white;
display: none;
overflow: auto!important;
box-shadow:none;
border-radius:0;
width:100%;
}
.sub-item {
border-top:none;
margin-left:-1rem;
margin-top:0rem;
margin-bottom:0px;
box-sizing: border-box;
line-height: 3rem;
border-bottom: solid 1px #B5B5B5;
width:100%;
}
.sub-menu-content li:last-child {
padding-bottom:0rem!important;
margin-bottom:0rem;
}
.sub-menu-content a {
color: #0f0f0f;
width:100%;
padding:5px;
margin-left:0rem;
text-decoration: none;
display: block;
border-left:none;
}
.sub-menu-content a:hover {
text-decoration:none;
border-left:none;
background-color: #00007a0d;
color:#00007a!important;
}
.header-menu {
position: absolute;
margin-top: 60px;
width: 80%;
height: 100vh;
background: #e8e8e8;
left: -100%;
text-align: left;
transition: 0.5s;
margin-right: 0;
padding: 0;
box-shadow: rgb(18 18 18 / 8%) 4px 4px 12px 0;
overflow:auto
}
.header-menu li:first-child {
margin-top: 0;
}
.header-menu :last-child {
padding-bottom: 0 !important;
}
.nav-item {
border-top: none;
margin-left: 0;
box-sizing: border-box;
border-bottom: 1px solid #b5b5b5;
width: 100%;
text-align: left;
line-height: 60px;
height: 60px;
display: block;
}
.nav-link:hover,
.sub-menu-link:hover {
background: #00007a0d;
transition-duration: 0.25s;
}
#check:checked ~ ul {
left: 0;
}
}
.menu-btn {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 22px;
height: 60px;
cursor: pointer;
transition: 0.5s ease-in-out;
}
.menu-btn__burger,
.menu-btn__burger::after,
.menu-btn__burger::before {
width: 22px;
height: 2.5px;
background: #00007a;
border-radius: 3px;
transition: 0.3s ease-in-out;
}
.menu-btn__burger::after,
.menu-btn__burger::before {
content: "";
position: absolute;
}
.menu-btn__burger::before {
transform: translateY(-6.5px);
}
.menu-btn__burger::after {
transform: translateY(6.5px);
}
.menu-btn.open .menu-btn__burger {
background: 0 0;
box-shadow: none;
}
.menu-btn.open .menu-btn__burger::before {
transform: rotate(45deg);
}
.menu-btn.open .menu-btn__burger::after {
transform: rotate(-45deg);
}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {
display:block;
}
.active {
color:#00007a!important;
}
@media(min-width: 1025px){
.sub-menu:hover .sub-menu-content {
display: block;
}
}
<div class="header">
<div class="header-cont">
<div class="header-logo">
<a aria-hidden="true" href="/">
LOGO
</a>
</div>
<nav class="header-nav">
<input type="checkbox" id="check">
<label for="check" class="checkbtn">
<div class="menu-btn">
<div class="menu-btn__burger"></div>
</div>
</label>
<ul class="header-menu">
<li class="nav-item">
<div class="sub-menu">
<a onclick="subOpen()" class="sub-menu-link">link 1<svg class="drop-chevron" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/></svg></a>
<div id="myDropdown" class="sub-menu-content">
<ul>
<li class="sub-item"><a href="#">sub link 1</a></li>
<li class="sub-item"><a href="#">sub link 2</a></li>
<li class="sub-item"><a href="#">sub link 3</a></li>
<li class="sub-item"><a href="#">sub link 4</a></li>
</ul>
</div>
</div>
</li>
<li class="nav-item"><a href="#" class="nav-link">link 2</a></li>
<li class="nav-item"><a href="#" class="nav-link">link 3</a></li>
<li class="nav-item"><a href="#" class="nav-link">link 4</a></li>
</ul>
</nav>
</div>
</div>
You have to understand the importance of HTML structure because everything starts from there.
Don't always use the same class name then select its children by the same class to style them, it's very confusing and you may get lost when editing or debugging. So give each element a class and use it.
For the problem you mentioned, to make it push other elements, you need to do two things:
a. change its location in the HTML b. give it a relative position in CSS.
After this, it won't show up on hover on the desktop but will appear on click and that's because of problem number 2 I mentioned earlier. So I will leave that for you to fix.
I commented its old location in HTML so you can see where the new location is.
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function subOpen() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.sub-menu-link')) {
var dropdowns = document.getElementsByClassName("sub-menu-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
//Mobile menu toggle code
const menuBtn=document.querySelector(".menu-btn");
let menuOpen=!1;
menuBtn.addEventListener("click",()=>{menuOpen?(menuBtn.classList.remove("open"),menuOpen=!1,document.documentElement.style.overflow="scroll",document.body.scroll="yes"):(menuBtn.classList.add("open"),menuOpen=!0,document.documentElement.style.overflow="hidden",document.body.scroll="no")})
body {
margin: 0;
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #333;
background-color: #fff;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
text-decoration:none;
}
.header-cont,
.nav-link {
align-items: center;
}
.header-nav,
.nav-item {
height: 60px;
}
.header {
background: #fff;
box-shadow: 0 0 10px -3px rgb(0 0 0 / 50%);
}
.header-cont {
display: flex;
max-width: 1350px;
margin: auto;
justify-content: space-between;
padding: 0 1rem 0 1rem;
box-sizing: border-box;
}
.nav-link,
.sub-menu-link {
padding: 0 1rem 0 1rem;
font-weight: 600;
color: #0f0f0f !important;
cursor:pointer;
}
.header-menu li:last-child {
margin-bottom: 0;
padding-bottom: 0;
}
.only-mobile {
display: none !important;
}
.nav-item,
.nav-link {
display: inline-block;
}
.nav-item {
line-height: 60px;
}
.drop-chevron {
margin-left: 10px;
height: 13px;
fill: #0f0f0f;
}
.nav-item:hover svg {
fill: #00007a !important;
/* transform: rotate(180deg);*/
}
.nav-item:hover {
background-color: #00007a0d;
transition: background-color 0.3s;
}
.nav-link:hover,
.sub-menu-link:hover {
color: #00007a !important;
transition: 0.3s;
text-decoration: none !important;
}
.sub-menu {
position: relative !important;
}
.sub-menu-link {
display: inline-block !important;
text-decoration: none !important;
}
#check,
.checkbtn {
display: none;
}
.sub-menu-content {
display: none;
margin-top: -0.1rem;
background-color: #fff !important;
box-shadow: 0 6px 14px -1px rgb(0 5 20 / 15%);
border-radius: 3px;
overflow: hidden;
position: absolute;
width: 200px;
z-index: 1000;
}
.sub-menu-content ul{
list-style-type: none;
line-height: 30px;
}
.sub-item {
width: 200px;
margin-left: -0.5rem;
}
.sub-menu-content li:last-child {
border-bottom: 1px solid transparent !important;
padding-bottom: 0.1rem !important;
margin-bottom: -0.2rem;
}
.sub-menu-content a {
color: #0f0f0f;
width: 100%;
padding: 0.8rem;
margin-left: -2rem;
text-decoration: none;
display: block;
text-align: left;
border-left: solid 4px transparent;
}
.sub-menu-content a:hover {
text-decoration: none;
border-left: 4px solid #ff9f1c;
background-color: #00007a0d;
color: #00007a !important;
}
.checkbtn {
font-size: 20px;
color: #00007a;
float: right;
line-height: 60px;
margin-right: 1rem;
cursor: pointer;
}
@media (max-width: 1025px) {
selector .header-logo {
margin-top: 0.1rem;
padding-top: 0;
}
.header-cont {
justify-content: space-between;
}
.only-mobile,
.sub-menu-link {
display: block !important;
}
.checkbtn,
.nav-link,
.sub-menu {
display: block;
}
.drop-chevron {
display: inline-flex;
position:absolute;
right:17px;
top:22px;
}
.sub-menu-content {
padding:0;
background-color: white;
display: none;
position: relative;
overflow: auto!important;
box-shadow:none;
border-radius:0;
width:100%;
}
.sub-item {
border-top:none;
margin-left:-1rem;
margin-top:0rem;
margin-bottom:0px;
box-sizing: border-box;
line-height: 3rem;
border-bottom: solid 1px #B5B5B5;
width:100%;
}
.sub-menu-content li:last-child {
padding-bottom:0rem!important;
margin-bottom:0rem;
}
.sub-menu-content a {
color: #0f0f0f;
width:100%;
padding:5px;
margin-left:0rem;
text-decoration: none;
display: block;
border-left:none;
}
.sub-menu-content a:hover {
text-decoration:none;
border-left:none;
background-color: #00007a0d;
color:#00007a!important;
}
.header-menu {
position: absolute;
margin-top: 60px;
width: 80%;
height: 100vh;
background: #e8e8e8;
left: -100%;
text-align: left;
transition: 0.5s;
margin-right: 0;
padding: 0;
box-shadow: rgb(18 18 18 / 8%) 4px 4px 12px 0;
overflow:auto
}
.header-menu li:first-child {
margin-top: 0;
}
.header-menu :last-child {
padding-bottom: 0 !important;
}
.header-menu > li > ul {
display: block!important;
height:0px!important;
visibility:hidden!important;
opacity:0!important;
transition:0.2s ease!important;
}
.nav-item {
border-top: none;
margin-left: 0;
box-sizing: border-box;
border-bottom: 1px solid #b5b5b5;
width: 100%;
text-align: left;
line-height: 60px;
height: 60px;
display: block;
}
.nav-link:hover,
.sub-menu-link:hover {
background: #00007a0d;
transition-duration: 0.25s;
}
#check:checked ~ ul {
left: 0;
}
.sub-menu-content:hover .nav-item { margin-top: 6rem; }
}
.menu-btn {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 22px;
height: 60px;
cursor: pointer;
transition: 0.5s ease-in-out;
}
.menu-btn__burger,
.menu-btn__burger::after,
.menu-btn__burger::before {
width: 22px;
height: 2.5px;
background: #00007a;
border-radius: 3px;
transition: 0.3s ease-in-out;
}
.menu-btn__burger::after,
.menu-btn__burger::before {
content: "";
position: absolute;
}
.menu-btn__burger::before {
transform: translateY(-6.5px);
}
.menu-btn__burger::after {
transform: translateY(6.5px);
}
.menu-btn.open .menu-btn__burger {
background: 0 0;
box-shadow: none;
}
.menu-btn.open .menu-btn__burger::before {
transform: rotate(45deg);
}
.menu-btn.open .menu-btn__burger::after {
transform: rotate(-45deg);
}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {
display:block;
}
.active {
color:#00007a!important;
}
@media(min-width: 1025px){
.sub-menu:hover .sub-menu-content {
display: block;
}
}
<div class="header">
<div class="header-cont">
<div class="header-logo">
<a aria-hidden="true" href="/">
LOGO
</a>
</div>
<nav class="header-nav">
<input type="checkbox" id="check">
<label for="check" class="checkbtn">
<div class="menu-btn">
<div class="menu-btn__burger"></div>
</div>
</label>
<ul class="header-menu">
<li class="nav-item">
<div class="sub-menu">
<a onclick="subOpen()" class="sub-menu-link">link 1<svg class="drop-chevron"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path
d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
</svg></a>
<!-- <div id="myDropdown" class="sub-menu-content">
<ul>
<li class="sub-item"><a href="#">sub link 1</a></li>
<li class="sub-item"><a href="#">sub link 2</a></li>
<li class="sub-item"><a href="#">sub link 3</a></li>
<li class="sub-item"><a href="#">sub link 4</a></li>
</ul>
</div> -->
</div>
</li>
<div id="myDropdown" class="sub-menu-content">
<ul>
<li class="sub-item"><a href="#">sub link 1</a></li>
<li class="sub-item"><a href="#">sub link 2</a></li>
<li class="sub-item"><a href="#">sub link 3</a></li>
<li class="sub-item"><a href="#">sub link 4</a></li>
</ul>
</div>
<li class="nav-item"><a href="#" class="nav-link">link 2</a></li>
<li class="nav-item"><a href="#" class="nav-link">link 3</a></li>
<li class="nav-item"><a href="#" class="nav-link">link 4</a></li>
</ul>
</nav>
</div>
</div>