Skip to main content
TailwindCSS Basics
CHAPTER 14 Beginner

Tailwind CSS Navigation Bars and Menus

Updated: May 12, 2026
30 min read

# Chapter 14: Tailwind CSS Navigation Bars and Menus

A Navigation Bar (Navbar) is arguably the most important component of any website. It anchors the user, tells them where they are, and provides the map to where they can go.

Building a responsive navbar—one that lays out horizontally on a desktop but collapses into a "hamburger" menu on mobile—used to require significant CSS and JavaScript. Tailwind's Flexbox and responsive utilities make this structure simple and maintainable.

---

1. Introduction

Navbars heavily rely on Flexbox (flex justify-between items-center) to separate the Logo on the left from the Links/Buttons on the right.

In this chapter, we will build a desktop navigation bar, understand how to hide it on mobile, and design the dropdown menus that modern SaaS applications use for user profiles and settings.

2. Learning Objectives

By the end of this chapter, you will be able to:

  • Construct a horizontal navbar using Flexbox.
  • Fix a navbar to the top of the screen using sticky or fixed.
  • Show and hide menu links based on screen size using breakpoints.
  • Design a dropdown menu using absolute positioning.

3. Beginner-Friendly Explanations

Sticky vs Fixed

  • fixed top-0: The navbar is permanently glued to the screen. Scrolling the page doesn't move it. *Warning: It takes the navbar out of the normal document flow, so content underneath might slide up behind it.*
  • sticky top-0: The navbar scrolls naturally with the page until it hits the top of the browser window, then it "sticks" there. It stays in the document flow, preventing content from hiding behind it. This is usually preferred.
To make a dropdown menu appear directly below a specific button, the parent wrapper of the button and menu must be relative. The dropdown menu itself must be absolute. This traps the absolute dropdown relative to the button, rather than the whole page.

4. Syntax Explanation

Key utilities for Navbars:

  • sticky top-0 z-50: Keeps the navbar at the top and ensures it stays above other content (z-index: 50).
  • justify-between: Pushes the Logo to the left and Links to the right.
  • hidden md:flex: Hides the navigation links on mobile phones, displays them on tablets/desktops.
  • absolute right-0 mt-2: Positions a dropdown menu below its parent and aligns it to the right edge.

5. Real-World Examples

If you look at the header of GitHub or Vercel, you see:

  1. 1. Logo (Left)
  1. 2. Links (Middle/Left)
  1. 3. Search Bar (Middle/Right)
  1. 4. Profile Avatar / Notifications (Right)
All of this is achieved by nesting flex containers inside a primary flex justify-between container.

6. Multiple Code Examples

Let's build the pieces of a navigation system.

Example 1: Basic Horizontal Navbar

html
123456789
<!-- TailwindCSS Example -->
<nav class="bg-slate-900 text-white p-4 flex justify-between items-center">
  <div class="font-bold text-xl tracking-wider">BRAND</div>
  <div class="space-x-6">
    <a href="#" class="hover:text-blue-400 transition">Home</a>
    <a href="#" class="hover:text-blue-400 transition">About</a>
    <a href="#" class="hover:text-blue-400 transition">Contact</a>
  </div>
</nav>

Resize your browser to see the links disappear and the "Menu" button appear!

html
12345678910111213141516
<!-- TailwindCSS Example -->
<nav class="bg-white border-b p-4 flex justify-between items-center">
  <div class="font-bold text-xl text-indigo-600">AppLogo</div>
  
  <!-- Desktop Links (Hidden on mobile) -->
  <div class="hidden md:flex items-center space-x-8">
    <a href="#" class="text-gray-600 hover:text-indigo-600 font-medium">Dashboard</a>
    <a href="#" class="text-gray-600 hover:text-indigo-600 font-medium">Projects</a>
    <a href="#" class="text-gray-600 hover:text-indigo-600 font-medium">Team</a>
  </div>

  <!-- Mobile Hamburger Button (Hidden on desktop) -->
  <button class="md:hidden p-2 text-gray-600 bg-gray-100 rounded">
    <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path></svg>
  </button>
</nav>

Example 3: The Dropdown Menu Structure

*Note: In a real app, Javascript toggles the hidden class on the dropdown menu when the button is clicked. Here we show it statically.*

html
12345678910111213141516171819
<!-- TailwindCSS Example -->
<!-- Parent MUST be relative -->
<div class="relative inline-block mt-8 ml-8">
  
  <!-- Trigger Button -->
  <button class="flex items-center gap-2 bg-white border px-4 py-2 rounded shadow-sm hover:bg-gray-50">
    <img src="https://i.pravatar.cc/100" class="w-6 h-6 rounded-full" alt="Avatar">
    <span>John Doe</span>
  </button>

  <!-- The Dropdown Menu (Absolute) -->
  <div class="absolute right-0 mt-2 w-48 bg-white border rounded-lg shadow-xl overflow-hidden z-10">
    <a href="#" class="block px-4 py-2 text-gray-700 hover:bg-indigo-50 hover:text-indigo-600">Profile</a>
    <a href="#" class="block px-4 py-2 text-gray-700 hover:bg-indigo-50 hover:text-indigo-600">Settings</a>
    <div class="border-t"></div>
    <a href="#" class="block px-4 py-2 text-red-600 hover:bg-red-50">Sign out</a>
  </div>
  
</div>

Example 4: Mobile Menu Overlay

When the user clicks the hamburger menu, a full-screen or sliding menu appears.

html
12345678910111213
<!-- TailwindCSS Example -->
<!-- This would normally be toggled via JS -->
<div class="bg-gray-900 w-64 min-h-[300px] text-white p-6">
  <div class="flex justify-between items-center mb-8">
    <span class="font-bold text-xl">Menu</span>
    <button class="text-gray-400 hover:text-white">× Close</button>
  </div>
  <div class="flex flex-col space-y-4">
    <a href="#" class="text-lg text-gray-300 hover:text-white hover:pl-2 transition-all">Home</a>
    <a href="#" class="text-lg text-gray-300 hover:text-white hover:pl-2 transition-all">Features</a>
    <a href="#" class="text-lg text-gray-300 hover:text-white hover:pl-2 transition-all">Pricing</a>
  </div>
</div>

7. Output Explanations

In Example 3 (Dropdown), the absolute right-0 mt-2 is the magic formula. absolute pulls the menu out of the page flow so it overlaps other content. right-0 aligns the right edge of the dropdown perfectly with the right edge of the button above it. mt-2 adds a small gap between the button and the menu. The z-10 ensures it renders *on top* of whatever page content is below it.

8. Common Mistakes

  1. 1. Forgetting z-index: If your sticky navbar or dropdown menu slides *underneath* an image or card on the page, it's because you forgot to add a high z-index (e.g., z-50) to the navbar/dropdown.
  1. 2. Forgetting relative on dropdown parent: If you make a dropdown menu absolute, but forget to make its container relative, the dropdown will position itself relative to the *entire page* instead of the button! It will fly off to the corner of the screen.

9. Best Practices

  • Use <nav>: Always use the semantic <nav> HTML tag for your main navigation, not a <div>.
  • Max-width containers: A navbar background should span the full width of the screen (w-full), but the content *inside* the navbar should be constrained by a max-w-7xl mx-auto container so links don't get pushed to the extreme edges of an ultra-wide monitor.

10. Exercises

  1. 1. Create a sticky navbar with a dark background. It should have a logo on the left and a "Login" button on the right.
  1. 2. Create a "Notification" icon button. When hovered, use the group class to show a small absolute positioned red dot (unread indicator) on the top right corner of the icon.

11. Mini Project: SaaS Navbar UI

Let's build a complete, production-ready SaaS navbar with a constrained layout, hover states, and a profile dropdown skeleton.

html
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
<!-- TailwindCSS Example: Complete SaaS Navbar -->
<!-- Sticky wrapper -->
<nav class="sticky top-0 z-50 w-full bg-white/80 backdrop-blur-md border-b border-slate-200 shadow-sm transition-all">
  
  <!-- Constrained inner container -->
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    
    <!-- Main Flex Row -->
    <div class="flex justify-between items-center h-16">
      
      <!-- Left: Logo & Links -->
      <div class="flex items-center gap-8">
        <!-- Brand -->
        <a href="#" class="flex items-center gap-2">
          <div class="bg-indigo-600 text-white w-8 h-8 rounded-lg flex items-center justify-center font-bold text-xl">S</div>
          <span class="font-bold text-xl text-slate-900">SaaSify</span>
        </a>
        
        <!-- Desktop Navigation -->
        <div class="hidden md:flex items-center gap-1">
          <a href="#" class="px-3 py-2 text-sm font-medium text-slate-900 bg-slate-100 rounded-md">Dashboard</a>
          <a href="#" class="px-3 py-2 text-sm font-medium text-slate-500 hover:text-slate-900 hover:bg-slate-50 rounded-md transition">Team</a>
          <a href="#" class="px-3 py-2 text-sm font-medium text-slate-500 hover:text-slate-900 hover:bg-slate-50 rounded-md transition">Projects</a>
        </div>
      </div>

      <!-- Right: Search & Profile -->
      <div class="flex items-center gap-4">
        
        <!-- Search Bar (Hidden on small mobile) -->
        <div class="hidden sm:block relative">
          <svg class="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
          <input type="text" placeholder="Search..." class="w-64 pl-9 pr-4 py-1.5 bg-slate-100 border-transparent focus:bg-white focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 rounded-full text-sm outline-none transition-all">
        </div>

        <!-- Notification Bell -->
        <button class="relative p-2 text-slate-400 hover:text-slate-600 transition">
          <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"></path></svg>
          <!-- Unread Dot -->
          <span class="absolute top-1.5 right-1.5 w-2.5 h-2.5 bg-rose-500 border-2 border-white rounded-full"></span>
        </button>

        <!-- Profile Avatar -->
        <button class="w-8 h-8 rounded-full border border-slate-200 overflow-hidden hover:ring-2 hover:ring-indigo-500 hover:ring-offset-2 transition-all focus:outline-none">
          <img src="https://i.pravatar.cc/150" alt="Profile" class="w-full h-full object-cover">
        </button>
        
      </div>
      
    </div>
  </div>
</nav>

Output Explanation: This navbar uses bg-white/80 and backdrop-blur-md to create an Apple-style frosted glass effect as the user scrolls down the page. The search bar is hidden on very small phones (hidden sm:block) to save space. The links use padding (px-3 py-2) and hover backgrounds (hover:bg-slate-50) to create distinct, clickable "target areas" rather than just changing text color.

12. Coding Challenges

Challenge: Add a mobile hamburger menu to the Mini Project above. Hide the Profile and Notification icons on mobile, and replace them with the hamburger icon.

13. MCQs with Answers

Question 1

What happens if you position a dropdown menu absolute but forget to make its parent container relative?

Question 2

Which utility combination creates a frosted glass effect on a navbar?

14. Interview Questions

Q: Explain the difference between fixed and sticky positioning for a navigation bar. *Answer:* A fixed navbar is removed from the normal document flow and stays at the defined position (e.g., top-0) relative to the viewport. Because it's removed from the flow, the content below it shifts up, requiring you to add top padding to the body. A sticky navbar remains in the normal document flow until the user scrolls past its designated position (top-0), at which point it "sticks" to the top. This prevents content from jumping up behind the navbar.

15. FAQs

Q: Does Tailwind handle the click event to open the mobile menu? A: No. Tailwind is strictly a CSS framework. To make the hamburger menu actually open a drawer, you need to use JavaScript (e.g., React state, Alpine.js, or vanilla JS) to toggle a hidden class on the menu container.

16. Summary

By mastering Flexbox alignments (justify-between), responsive prefixes (hidden md:flex), and positioning (relative/absolute), building complex navigation bars becomes a straightforward layout exercise. These tools ensure your navigation adapts gracefully from massive desktop monitors down to the smallest mobile screens.

17. Next Chapter Recommendation

Navigation takes the user to a page, but what displays the content on that page? In Chapter 15: Tailwind CSS Cards and Dashboard UI, we will combine everything we've learned so far—Grid, Flexbox, Typography, and Shadows—to build complex dashboard widgets and content cards.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·