Hamburger menu with React and Tailwind Css
For better redability check this post on medium
Looking for a quick, simple, stylish and responsive menu?
Here is a guide on how to achieve a responsive hamburger-style menu with React and Tailwind.
If you want to jump to the code directly, here is the link
I assume you do have already a react project on your own.
If you don’t you can quickly create one with:
npx create-react-app folderWhereToSetUpTheReactProject
Tailwind Css
Tailwind Css is a popular UI framework that allows adding style just through Html classes.
The idea is that there is a class for any css property you will ever need, in this way you don’t need to write any style.
Disclaimer: Personal Opinion ahead
A lot of people use these kinds of frameworks with the idea they help them build the UI quicker.
I feel that often takes me more time to learn the framework than to write the css myself.
Also, if I encounter an issue, I must find a solution related to that specific framework when maybe a general solution would be easier to find.
I’m not saying these frameworks are bad. It widely depends on the project requirements, the team, the skills level and so on.
I just would like to advise that these frameworks don’t magically solve all your css and timing problems. Take into account you will still need time to learn the framework and you will still need to have a decent understanding of CS
How Tailwind works?
From their official page:
Tailwind CSS works by scanning all of your HTML files, JavaScript components, and any other templates for class names, generating the corresponding styles and then writing them to a static CSS file.
Basically, it read any class found in Html or JS files, generates the css for it and then writes a static css file.
Therefore if we are working with React, it means we can simply configure tailwind, write classes in the JSX, include one style file and everything will work fine.
Set up Tailwind Css with React
Tailwind Css documentation is well done and gives us various guides to set up Tailwind in a different environment. For a react app we can pick the example with Create React App:tailwind docs
What we will need to do is, firstly install all the required dependencies and create the required configuration file:
// Terminal
> npm install -D tailwindcss postcss autoprefixer
> npx tailwindcss init
If you check in your project folder, you should now have a tailwind.config.js
file.
To this file, we add a path in the content: []
array.
Add ./src/**/*.{js,jsx,ts,tsx}
to tell tailwind to scan for all the file in the src
folder that has js, jsx, ts, tsx
extension.
// tailwind.config.js
module.exports = { content: [
'./src/**/*.{js,jsx,ts,tsx}'
], theme: { extend: {}, }, plugins: [],}
Last, add tailwind directives to a cssfile.
If you created the project with CRA, you can add this to the src/index.css
.
Otherwise, you just need to add these directives to any css file you have in the project. It should be a parent css style, so the one that includes all the others.
This file needs to be included in index.js or App.js or however your app container component is called. In this way we are sure all the children’s components are included in Tailwind Css.
// src/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
Now you can add some tailwind classes to any of your component and see if it works properly:
// App.js
<h1 className="text-3xl font-bold underline">
Hello world!
</h1>
and then simply start the project
// Terminal
> npm start
Responsive Hamburger Menu — Tailwind
First, let’s see how the HTML/Tailwind part is coded, we will add React later to it.
So here is the code that shows the hamburger icon on mobile and the menu items on bigger screens.
In whatever component we want to display our menu, we will have this JSX:
<div className="flex items-center justify-between border-b border-gray-400 py-8">
<a href="/">
<img src="https://designbygio.it/images/logo.png" alt="logo" />
</a>
<nav>
<section className="MOBILE-MENU flex lg:hidden">
<div
className="HAMBURGER-ICON space-y-2"
>
<span className="block h-0.5 w-8 animate-pulse bg-gray-600"></span>
<span className="block h-0.5 w-8 animate-pulse bg-gray-600"></span>
<span className="block h-0.5 w-8 animate-pulse bg-gray-600"></span>
</div>
<div>
<div
className="absolute top-0 right-0 px-8 py-8"
>
<svg
className="h-8 w-8 text-gray-600"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />
</svg>
</div>
<ul className="NAVIGATION-MOBILE-OPEN flex flex-col items-center justify-between min-h-[250px]">
<li className="border-b border-gray-400 my-8 uppercase">
<a href="/about">About</a>
</li>
<li className="border-b border-gray-400 my-8 uppercase">
<a href="/portfolio">Portfolio</a>
</li>
<li className="border-b border-gray-400 my-8 uppercase">
<a href="/contact">Contact</a>
</li>
</ul>
</div>
</section>
<ul className="DESKTOP-MENU hidden space-x-8 lg:flex">
<li>
<a href="/about">About</a>
</li>
<li>
<a href="/portfolio">Portfolio</a>
</li>
<li>
<a href="/contact">Contact</a>
</li>
</ul>
</nav>
</div>
The classes written in uppercase are just an indicator added by me to show which UI item that element hold.
Each class added here is a specific Tailwind class that gives a specific style: px-8 gives horizontal padding, mb-8 gives margin bottom, flex is to set display flex, and so on.
Thanks to those classes we can hide and show the mobile and desktop menu:
Near MOBILE-MENU you can see lg:hidden which means please hide this DIV on a big screen.
On DESKTOP-MENU there is a hidden class. When is just the class name without mediaquery indication, it means it will start from 0px with. So mobile or the smallest mediaquery.
Then we say lg:flex to show it on bigger mediaquery, exactly when we hide the mobile menu.
Hamburger Menu — React
Let’s now add functionality to open and close the mobile menu.
To do so, we need to use the useState hook.
First, I import it (line 3), then I define the value and the setter of the state and I initiate the isNavOpen with a value of false — Because at first, the mobile menu is close.
Then on line 17, I toggle the state on every click — whenever the user clicks on the hamburger icon I want to change the boolean from true to false and the other way around. So if it is close it will open, if it is open it will close.
Last, on line 27 I set the isNavOpen state to false . This is triggered by a click from the user on the ‘X’ icon and is used to close the mobile menu.
// full code link
import { useState } from "react"; // import state
export default function Header() {
const [isNavOpen, setIsNavOpen] = useState(false); // initiate isNavOpen state with false
return (
<div className="flex items-center justify-between border-b border-gray-400 py-8">
<a href="/">
<img src="https://designbygio.it/images/logo.png" alt="logo" />
</a>
<nav>
<section className="MOBILE-MENU flex lg:hidden">
<div
className="HAMBURGER-ICON space-y-2"
onClick={() => setIsNavOpen((prev) => !prev)} // toggle isNavOpen state on click
>
<span className="block h-0.5 w-8 animate-pulse bg-gray-600"></span>
<span className="block h-0.5 w-8 animate-pulse bg-gray-600"></span>
<span className="block h-0.5 w-8 animate-pulse bg-gray-600"></span>
</div>
<div className={isNavOpen ? "showMenuNav" : "hideMenuNav"}> // toggle class based on isNavOpen state
<div
className="CROSS-ICON absolute top-0 right-0 px-8 py-8"
onClick={() => setIsNavOpen(false)} // change isNavOpen state to false to close the menu
>
<svg
className="h-8 w-8 text-gray-600"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />
</svg>
</div>
<ul className="MENU-LINK-MOBILE-OPEN flex flex-col items-center justify-between min-h-[250px]">
<li className="border-b border-gray-400 my-8 uppercase">
<a href="/about">About</a>
</li>
<li className="border-b border-gray-400 my-8 uppercase">
<a href="/portfolio">Portfolio</a>
</li>
<li className="border-b border-gray-400 my-8 uppercase">
<a href="/contact">Contact</a>
</li>
</ul>
</div>
</section>
<ul className="DESKTOP-MENU hidden space-x-8 lg:flex">
<li>
<a href="/about">About</a>
</li>
<li>
<a href="/portfolio">Portfolio</a>
</li>
<li>
<a href="/contact">Contact</a>
</li>
</ul>
</nav>
<style>{`
.hideMenuNav {
display: none;
}
.showMenuNav {
display: block;
position: absolute;
width: 100%;
height: 100vh;
top: 0;
left: 0;
background: white;
z-index: 10;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
}
`}</style>
</div>
);
}
And here it is: A simple, clean design, responsive and functional hamburger menu with React and Tailwind Css framework!
Plaza Singapura is a popular shopping mall in Singapore that also has a wide variety of food options. Here are a few of the most popular restaurants in Plaza Singapura:
Seorae Korean Charcoal BBQ: This restaurant serves up delicious Korean barbecue, cooked over charcoal for a smoky flavor.
Haidilao Hot Pot: This popular hot pot chain is known for its flavorful broths and fresh ingredients. https://plaza-singapura.com/
Hello.
thanks!