From Zero to Header: Build a Stunning Responsive Navigation Bar with React and Tailwind CSS

Chintanonweb
8 min readSep 27, 2024

--

Creating a Responsive Header Using React and Tailwind CSS

When building a modern web application, a responsive and user-friendly header (or navigation bar) is a must. In this article, we’ll walk through creating a responsive header component using React and Tailwind CSS. This tutorial will break down the code step by step, making it easy for beginners to follow along and implement it in their projects. By the end of this tutorial, you’ll have a fully functional and responsive navigation bar that works seamlessly across all devices.

Introduction

Headers are crucial elements of any website or web app. They house navigation links and often include branding elements, such as logos, as well as action buttons like “Sign In” or “Sign Up.” This tutorial will show you how to build a responsive header that automatically adjusts its layout based on the screen size, using React and Tailwind CSS for styling. We’ll also implement a hamburger menu for mobile users to toggle navigation links.

Let’s dive into the step-by-step process of creating this header.

Prerequisites

To follow along, you need:

  • Basic knowledge of React.
  • Familiarity with Tailwind CSS for styling.
  • A React environment set up (create-react-app or any preferred method).
  • Tailwind CSS installed in your React project. If you haven’t set up Tailwind, follow their installation guide.

Step-by-Step Breakdown

Step 1: Setting Up the Component

We’ll start by creating a simple header component. In your src folder, create a new file named Header.js. Import React, and use the useState hook to manage the navigation state for toggling the menu on mobile devices.

import React, { useState } from "react";

function Header() {
const [nav, setNav] = useState(false); // State to toggle mobile menu
return (
<header>
<nav className="bg-white border-gray-200 px-4 lg:px-6 py-2.5 dark:bg-gray-800 shadow">
{/* Rest of the code will go here */}
</nav>
</header>
);
}
export default Header;

Here, we’ve initialized a React component called Header and added a piece of state nav that we’ll use later to control whether the mobile navigation menu is visible or not.

Step 2: Creating the Main Layout

Next, let’s create the basic structure of the header. We need a container for the logo and another container for the navigation links and buttons. Tailwind’s utility classes like flex, justify-between, and items-center will help us lay these elements out properly.

<div className="flex flex-wrap justify-between items-center mx-auto max-w-screen-lg">
<a href="#" className="flex items-center">
<span className="self-center text-xl font-semibold whitespace-nowrap dark:text-white">
Logo
</span>
</a>
</div>

In this block, we created the logo section. We used Tailwind’s utility classes to align the logo (flex items-center), and self-center ensures the logo is vertically aligned. You can replace the Logo text with an image or an actual logo.

Step 3: Adding the Navigation Links

The navigation links are essential to the header. We’ll add some example links like Home, Pricing, Contact Us, and Sign In. These links should adapt to different screen sizes, so we’ll use responsive Tailwind classes.

<div className={`flex-col md:flex md:flex-row items-center w-full md:w-auto md:order-2 transition-all duration-300 ${nav ? "absolute top-14 left-0 w-full bg-white shadow-md p-4 md:relative md:top-0 md:w-auto md:bg-transparent md:shadow-none" : "hidden md:flex gap-6"}`}>
<ul className="flex flex-col md:flex-row md:gap-8 gap-0">
<li><a href="#" className="block py-2 pr-4 pl-3 text-gray-700 rounded md:bg-transparent md:text-primary-700 md:p-0 dark:text-white">Home</a></li>
<li><a href="#" className="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-primary-700 md:p-0 dark:text-gray-400 md:dark:hover:text-white dark:border-gray-700">Pricing</a></li>
<li><a href="#" className="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-primary-700 md:p-0 dark:text-gray-400 md:dark:hover:text-white dark:border-gray-700">Contact Us</a></li>
<li><a href="#" className="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-primary-700 md:p-0 dark:text-gray-400 md:dark:hover:text-white dark:border-gray-700">Sign In</a></li>
</ul>
<button className="mt-4 md:mt-0 rounded-full bg-slate-800 py-2 px-4 border border-transparent text-center text-sm text-white transition-all shadow-md hover:shadow-lg">Sign Up Now</button>
</div>

In this part of the code:

  • We create a <ul> for the links and apply different classes based on the screen size (flex-col for mobile, md:flex-row for larger screens).
  • We use Tailwind’s hover and dark mode utilities for different background and text colors.
  • A button for Sign Up is added after the navigation links.

Step 4: Handling the Mobile Hamburger Menu

On mobile devices, we want to collapse the links into a hamburger menu. We’ll add a button to toggle the visibility of the navigation links when clicked. The useState hook we introduced earlier helps manage this toggle.

<div className="md:hidden flex items-center lg:order-1">
<button
type="button"
className="inline-flex items-center p-2 ml-1 text-sm text-gray-500 rounded-lg hover:bg-gray-100 focus:outline-none"
aria-controls="mobile-menu"
aria-expanded={nav}
onClick={() => setNav(!nav)} // Toggle the nav state on click
>
{nav ? (
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
) : (
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
clipRule="evenodd"
/>
</svg>
)}
</button>
</div>

This button displays either a hamburger icon or a close icon based on the state of nav. The onClick event handler toggles the state, and the visibility of the links is controlled by the state.

Step 5: Making It Responsive

We use Tailwind CSS’s responsive design features to ensure the navigation behaves well across devices. Tailwind’s md: prefix allows us to specify different styles for medium-sized screens and up. By default, the navigation links are hidden on smaller screens, and the hamburger menu is shown. On medium-sized screens and larger, the navigation links appear inline, and the hamburger menu disappears.

Complete Component Code

Now that we’ve gone through each part, here’s the complete code for the Header component:

import React, { useState } from "react";
function Header() {
const [nav, setNav] = useState(false);
return (
<header>
<nav className="bg-white border-gray-200 px-4 lg:px-6 py-2.5 dark:bg-gray-800 shadow">
<div className="flex flex-wrap justify-between items-center mx-auto max-w-screen-lg">
<a href="#" className="flex items-center">
<span className="self-center text-xl font-semibold whitespace-nowrap dark:text-white">
Logo
</span>
</a>
<div
className={`flex-col md:flex md:flex-row items-center w-full md:w-auto md:order-2 transition-all duration-300 ${
nav
? "absolute top-14 left-0 w-full bg-white shadow-md p-4 md:relative md:top-0 md:w-auto md:bg-transparent md:shadow-none"
: "hidden md:flex gap-6"
}`}
>
<ul className="flex flex-col md:flex-row md:gap-8 gap-0">
<li>
<a
href="#"
className="block py-2 pr-4 pl-3 text-gray-700 rounded md:bg-transparent md:text-primary-700 md:p-0 dark:text-white"
aria-current="page"
>
Home
</a>
</li>
<li>
<a
href="#"
className="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-primary-700 md:p-0 dark:text-gray-400 md:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700"
>
Pricing
</a>
</li>
<li>
<a
href="#"
className="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-primary-700 md:p-0 dark:text-gray-400 md:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700"
>
Contact Us
</a>
</li>
<li>
<a
href="#"
className="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-primary-700 md:p-0 dark:text-gray-400 md:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700"
>
Sign In
</a>
</li>
</ul>
<button
className="mt-4 md:mt-0 rounded-full bg-slate-800 py-2 px-4 border border-transparent text-center text-sm text-white transition-all shadow-md hover:shadow-lg focus:bg-slate-700 focus:shadow-none active:bg-slate-700 hover:bg-slate-700 active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
type="button"
>
Sign Up Now
</button>
</div>
<div className="md:hidden flex items-center lg:order-1">
<button
type="button"
className="inline-flex items-center p-2 ml-1 text-sm text-gray-500 rounded-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600"
aria-controls="mobile-menu"
aria-expanded={nav}
onClick={() => setNav(!nav)}
>
<span className="sr-only">Open main menu</span>
{nav ? (
<svg
className="w-6 h-6"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
clipRule="evenodd"
></path>
</svg>
) : (
<svg
className="w-6 h-6"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
clipRule="evenodd"
></path>
</svg>
)}
</button>
</div>
</div>
</nav>
</header>
);
}
export default Header;

Conclusion

Conclusion

By following the steps outlined above, you now have a fully functional responsive header using React and Tailwind CSS. This header includes:

  • A logo section.
  • A responsive navigation bar that adapts to different screen sizes.
  • A mobile hamburger menu to toggle navigation links.
  • Styling for light and dark modes using Tailwind’s dark: utilities.

This solution is easy to customize and extend based on your project needs. Feel free to adjust the links, add more features, or replace the text with your own branding and content.

FAQs

How do I add more links to the navigation?

Simply add more <li> elements inside the <ul> block with your desired links.

How can I replace the logo text with an image?

Instead of using the <span> element for the logo, replace it with an <img> tag:

<a href="#" className="flex items-center">
<img src="/path/to/logo.png" alt="Logo" className="h-8" />
</a>

How do I add more buttons or CTA (Call-to-Action) elements?

You can add more buttons after the navigation links or replace the Sign Up Now button with any other CTA. Tailwind’s utility classes make it easy to style these buttons.

--

--

Chintanonweb

As a software engineer, bringing my ideas to life through code and inspiring others with the possibilities. Managed By : chintandhokai97@gmail.com