Home > Mobile >  Hamburger menu responsiveness issue
Hamburger menu responsiveness issue

Time:11-22

I am trying to make a hamburger menu, in which when a screen with more than 600px is used the hamburger menu is show in the form of a navbar and if the screen is smaller than 600px then it is shown as a hamburger menu.

I did the coding and the menu works perfectly as intended. However, once the menu is toggled and then toggled off, and the screen size is increased, the navbar appears out of its place.

THis is the correct format

This is when the website loads ^

This is the issue

This happens when the hamburger is used and the screen size is increased. Also, this was my first try at hamburger menu's I did it on my own, if possible then can you share some references from which I can learn.

Here is the HTML

<header>
        <h2>Hamburger Menu => </h2>
        <nav>
            <ul class="navbar">
                <li><a href="#">Home</a></li>
                <li><a href="#">Google</a></li>
                <li><a href="#">Youtube</a></li>
                <li><a href="#">Stackoverflow</a></li>
            </ul>
            <div class="cross"><i class="fas fa-times"></i></div>
            <div class="hamburger"><i class="fas fa-bars"></i></div>
        </nav>
    </header>

Here is the CSS

*{
    margin: 0;
    padding: 0;
}

body{
    background: #ccc;
}

/* header */
header{
    width: 100%;
    min-height: 70px;
    display: flex;
    justify-content: space-between;
    background: #000033;
    color: #ff3300;
    align-items: center;
}

h2{
    margin: 0 0 0 1rem;
    text-shadow: 1px 1px 1px #ffad99;
}
/* navbar */
.navbar{
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    align-items: center;
    margin: 0 1rem 0 0;
}

/* links */
li{
    list-style: none;
}

a{
    color: #ff3300;
    text-decoration: none;
    text-shadow: 1px 1px 4px #ffad99;
    box-sizing: border-box;
}

a:hover{
    box-sizing: border-box;
    font-weight: bold;
    text-shadow: 1px 1px 1px #ffad99;
}

/* cross */
.cross{
    display: block;
    margin: 0 2rem 0 0;
    font-size: 1.5em;
    cursor: pointer;
}

.cross{
    display: none;
}

/* hamburger */
.hamburger{
    display: none;
}

/* media query for mobile */

@media(max-width:600px){
    .navbar{
        /* display: none; */
        position: absolute;
        width: 100vw;
        transform: translateX(-189%);
        top: 20vh;
        transition-duration: 2s;
        flex-direction: column;
        background: #000;
        height: 100vh;
        box-sizing: border-box;
    }

    li{
        margin: 0.4em 0.4rem ;
        padding: 0.9rem 5rem;
        border-bottom: 2px solid #fff;
        border-radius: 3px;
        box-sizing: border-box;
    }

    .hamburger{
        display: block;
        margin: 0 2rem 0 0;
        font-size: 1.5em;
        cursor: pointer;
    }
}

/* js classes */
.show{
    display: block;
}

.hide{
    display: none;
}

And here is the JAVASCRIPT

// * variables
const hamburger = document.querySelector('.hamburger');
const cross = document.querySelector('.cross');
const menu = document.querySelector('.navbar');

// functions
const showNav = () => {
    menu.style.transform = 'translateX(-89%)';
}

const hideNav = () => {
    menu.style.transform = 'translateX(-189%)'
}

// hamburger click event 
hamburger.addEventListener('click', () => {
    hamburger.classList.add('hide')
    hamburger.classList.remove('show')

    cross.classList.remove('hide')
    cross.classList.add('show')

    showNav();
});

cross.addEventListener('click', () => {
    cross.classList.remove('show')
    cross.classList.add('hide')

    hamburger.classList.remove('hide')

    hideNav();
});

All answers will be greatly appreciated. I Would like to tell my problem again, When the hamburger menu is used and then closed and after that if the screen is resized to be greater than the @media value, it messes up the navbar. Can I get a fix to this please?

my code is a little inefficient I am pretty new to javascript so an answer with basic syntax will be greatly appreciated.

CodePudding user response:

It is because the transform that is getting applied in showNav() is still there so the ul element will always be shifted to the left after calling the function.

One way to solve this is to instead make a .show-nav inside the @media after the .navbar:

@media (max-width: 600px) {

  .navbar {
    ...
  }

  .show-nav {
    transform: translateX(-89%);
  }

  ...

}

Then update the show and hide functions to just add and remove that class:

const showNav = () => {
  menu.classList.add('show-nav')
}

const hideNav = () => {
  menu.classList.remove('show-nav')
}

Here is a working example with the suggested changes:

// * variables
const hamburger = document.querySelector('.hamburger')
const cross = document.querySelector('.cross')
const menu = document.querySelector('.navbar')

// functions
const showNav = () => {
  menu.classList.add('show-nav')
}

const hideNav = () => {
  menu.classList.remove('show-nav')
}

// hamburger click event
hamburger.addEventListener('click', () => {
  hamburger.classList.add('hide')
  hamburger.classList.remove('show')

  cross.classList.remove('hide')
  cross.classList.add('show')

  showNav()
})

cross.addEventListener('click', () => {
  cross.classList.remove('show')
  cross.classList.add('hide')

  hamburger.classList.remove('hide')

  hideNav()
})
* {
  margin: 0;
  padding: 0;
}

body {
  background: #ccc;
}


/* header */

header {
  width: 100%;
  min-height: 70px;
  display: flex;
  justify-content: space-between;
  background: #000033;
  color: #ff3300;
  align-items: center;
}

h2 {
  margin: 0 0 0 1rem;
  text-shadow: 1px 1px 1px #ffad99;
}


/* navbar */

.navbar {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: center;
  margin: 0 1rem 0 0;
}


/* links */

li {
  list-style: none;
}

a {
  color: #ff3300;
  text-decoration: none;
  text-shadow: 1px 1px 4px #ffad99;
  box-sizing: border-box;
}

a:hover {
  box-sizing: border-box;
  font-weight: bold;
  text-shadow: 1px 1px 1px #ffad99;
}


/* cross */

.cross {
  display: block;
  margin: 0 2rem 0 0;
  font-size: 1.5em;
  cursor: pointer;
}

.cross {
  display: none;
}


/* hamburger */

.hamburger {
  display: none;
}


/* media query for mobile */

@media (max-width: 600px) {
  .navbar {
    /* display: none; */
    position: absolute;
    width: 100vw;
    transform: translateX(-189%);
    top: 20vh;
    transition-duration: 2s;
    flex-direction: column;
    background: #000;
    height: 100vh;
    box-sizing: border-box;
  }
  .show-nav {
    transform: translateX(-89%);
  }
  li {
    margin: 0.4em 0.4rem;
    padding: 0.9rem 5rem;
    border-bottom: 2px solid #fff;
    border-radius: 3px;
    box-sizing: border-box;
  }
  .hamburger {
    display: block;
    margin: 0 2rem 0 0;
    font-size: 1.5em;
    cursor: pointer;
  }
  /* js classes */
  .show {
    display: block;
  }
  .hide {
    display: none;
  }
}
<header>
  <h2>Hamburger Menu =></h2>
  <nav>
    <ul class="navbar">
      <li><a href="#">Home</a></li>
      <li><a href="#">Google</a></li>
      <li><a href="#">Youtube</a></li>
      <li><a href="#">Stackoverflow</a></li>
    </ul>
    <div class="cross"><i class="fas fa-times"></i>X</div>
    <div class="hamburger"><i class="fas fa-bars"></i>|||</div>
  </nav>
</header>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related