Home > Enterprise >  How can I turn my navbar into Hamburger menu for mobile using responsive design?
How can I turn my navbar into Hamburger menu for mobile using responsive design?

Time:12-16

How could I turn this navbar I made using CSS into Hamburger menu for mobile ? It needs to be responsive. I first tried using bootstrap but I'd like it to use CSS

Here's my codepen : enter image description here

Then, you can assign a class to ul and populate it as follows:

.list {
  display: grid;
  grid-auto-flow: column;
  list-style-type: none;
  column-gap: 20px;
  padding: 0;
}

Here you're telling to <ul> element that all the <li> elements inside of it, should compose a grid of n columns as many <li> elements and that you want 20px of space between each of them. The property column-gap works only if you set display: grid. The padding should always be 0 or the browser will add some padding by default. You don't want it so you specify 0.

enter image description here

Now, you can use a powerful combo to set the width of the list items by creating a class and assigning it to your <li> elements:

.listItem {
  width: min-content;
  white-space: nowrap;
}

Here you're just telling to the list items that their width should be automatic, based on the words length. With white-space: nowrap you're telling to the list items that you never want the text to start a new line after a space. For example, "GUIDES ET ASTUCES" will always be placed on a single line. At the same time you're also setting the width for each column of the grid created before.

Now, create a button and wrap it together with the logo in a new div:

    <div >
      <img src="images/GameStar-Blanc.png" alt="logo" >
      <button >Menu</button>
    </div>

Basically, this will be your mobile header with the logo on the left and the button on the right. The menu will be placed below.

Create a global CSS rule and tell the button you never want to display it:

.hamburger {
  display: none;
}

Now for the mobile menu, you should change the appearance of the <nav> container and all its child element that you want to change. From now on your code should be wrapped around a media query, place the media queries at the bottom of your CSS file or at least, below the rules defined before:

@media screen and (max-width: 800px) {
  // CSS code
}

Create another CSS rule targeting all the devices with a max resolution of 800px:

@media screen and (max-width: 800px) {
    .hamburger {
      display: block;
    }
}

In short, you just said: "The menu button should always be hidden, but when a device has a width from 0 to 800px, I want to display it.

Now create another rule inside the media query @media screen and (max-width: 800px) and do the same you did for the header:

.mobileHeader {
  width: 100%;
  display: flex;
  justify-content: space-between;
}

Basically you want that a certain width, the header is something like:

enter image description here

Now you should have two elements inside your <header>, <div> and <nav>, let's create a rule and tell the header that you would like to display those elements one below the other:

.header {
  flex-direction: column;
  padding: 20px;
}

Basically it is just like grid-auto-flow: row for grids.

Now do the same for the list, this time you want the opposite, you want that all the items will compose a grid with n rows and just one column:

.list {
  grid-auto-flow: row;
  list-style-type: none;
  row-gap: 40px;
  column-gap: 0;
  justify-items: center;
}

With justify-items: center you're instructing the list to center the list items. It works only with display: grid, since you set display: grid in a global rule, you don't need to write it again as long as you don't need to change it.

enter image description here

Now assign a class to your <nav> and enter another rule in the media query:

.menu {
   display: none;
}

Since your menu should be hidden when an user visits the website on mobile, it should be set on display: none by default.

Now, set a rule to target only devices with a width of 801 px and more with (min-width: 801px):

@media screen and (min-width: 801px) {
  .menu {
    display: block !important;
  }
}

No matter what, you always want the menu to be displayed for devices which have a resolution wider than 800px.

Now, if you shrink your window the mobile menu should be vanished and here you need a bit of JS to open and close it, I am not going into the details since your question is totally related to CSS and I will only confuse you by going deeper but you will find everything in the pen I made for you.

https://codepen.io/alienopolis/pen/NWapXWZ

Finally, I would recommend you to take this free tutorial which covers everything you need to know about responsive design with CSS:

https://www.freecodecamp.org/news/css-flexbox-and-grid-tutorial/

HTML

<header >
  <div >
    <img src="images/GameStar-Blanc.png" alt="logo" >
    <button onclick={openMenu()} >Menu</button>
  </div>
  <nav >
    <ul >
      <li ><a href="#">A LA UNE </a></li>
      <li><a href="#">L'ACTUALITE</a></li>
      <li><a href="#">GUIDES ET ASTUCES</a></li>
      <li><a href="#">PROCHAINEMENT</a></li>
    </ul>
  </nav>
</header>

CSS

body {
  width: 90%;
  height: 800px;
}

.header {
  display: flex;
  width: 100%;
  justify-content: space-between;
  background: #583760;
  align-items: center;
  padding: 20px 60px;
}


.logo {
  color: white;
}

.list {
  display: grid;
  grid-auto-flow: column;
  list-style-type: none;
  column-gap: 40px;
}

.listItem {
  width: min-content;
  white-space: nowrap;
}

nav a {
  color: white;
  font-weight: bold;
  text-decoration: none;
  text-transform: uppercase;
}

nav a:hover {
  color: black;
}

.hamburger {
  display: none;
}

@media screen and (min-width: 801px) {
  .menu {
    display: block !important;
  }
}

@media screen and (max-width: 800px) {

  .header {
    flex-direction: column;
    padding: 20px;
  }

  .mobileHeader {
    width: 100%;
    display: flex;
    justify-content: space-between;
  }

  .hamburger {
    display: block;
  }

  .menu {
    display: none;
  }

  .list {
    grid-auto-flow: row;
    list-style-type: none;
    row-gap: 40px;
    column-gap: 0;
    justify-items: center;
  }
}

JS

const menu = document.querySelector(".menu");
let open;

function openMenu() {
  if (open) {
    menu.style.display = "none";
    open = false;
  } else if (!open) {
    menu.style.display = "block";
    open = true;
  }
}
  • Related