點燈坊

失くすものさえない今が強くなるチャンスよ

Creating Responsive Fixed Navbar

Sam Xiao's Avatar 2022-01-08

Responsive Navbar is the essential component in every modern Web design. This can be done by only Alpine and TailwindCSS without any package.

Version

Tailwind CSS 3.0
Alpine 3.9

Desktop

navbar000

  • We can see Archive, Series, Tags and RSS in the Navbar on desktop

  • The Navbar is fixed when scrolling down

Mobile

navbar001

  • We can see hamburger in the Navbar on mobile device.

  • The Navbar is fixed when scrolling down.

  • When clicking the hamburger, the mobile dropdown menu is shown.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://unpkg.com/alpinejs" defer></script>
    <script src="https://cdn.tailwindcss.com"></script>
    <title>Navbar</title>
  </head>
  <body>
    <nav
      x-data="{ isShowMobileMenu: false }"
      class="fixed left-0 top-0 w-full bg-gray-800"
    >
      <!-- Desktop Navbar -->
      <div class="mx-auto max-w-7xl px-2 sm:px-4">
        <div class="flex h-16 items-center justify-between">
          <!-- Logo & menu -->
          <div class="flex items-center px-2 md:px-0">
            <!-- Logo -->
            <div class="shrink-0">
              <img
                class="block h-8 md:hidden"
                src="https://tailwindui.com/img/logos/workflow-mark-indigo-500.svg"
                alt="Workflow"
              />
              <img
                class="hidden h-8 md:block"
                src="https://tailwindui.com/img/logos/workflow-logo-indigo-500-mark-white-text.svg"
                alt="Workflow"
              />
            </div>
            <!-- Menu -->
            <div class="hidden md:ml-6 md:block">
              <div x-data="{ selected: 'archive' }" class="flex space-x-4">
                <a
                  href="#"
                  @click="selected = 'archive'"
                  class="rounded-md px-3 py-2 text-sm font-medium"
                  :class="selected === 'archive' ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white'"
                  >Archive</a
                >
                <a
                  href="#"
                  @click="selected = 'series'"
                  class="rounded-md px-3 py-2 text-sm font-medium"
                  :class="selected === 'series' ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white'"
                  >Series</a
                >
                <a
                  href="#"
                  @click="selected = 'tags'"
                  class="rounded-md px-3 py-2 text-sm font-medium"
                  :class="selected === 'tags' ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white'"
                  >Tags</a
                >
                <a
                  href="#"
                  @click="selected = 'rss'"
                  class="rounded-md px-3 py-2 text-sm font-medium"
                  :class="selected === 'rss' ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white'"
                  >RSS</a
                >
              </div>
            </div>
          </div>
          <!-- Search -->
          <div class="flex flex-1 justify-center px-2 md:ml-6 md:justify-end">
            <div class="w-full max-w-lg md:max-w-xs">
              <label for="search" class="sr-only">Search</label>
              <div class="relative">
                <!-- Search icon -->
                <div
                  class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3"
                >
                  <svg
                    class="h-5 w-5 text-gray-400"
                    xmlns="http://www.w3.org/2000/svg"
                    viewBox="0 0 20 20"
                    fill="currentColor"
                    aria-hidden="true"
                  >
                    <path
                      fill-rule="evenodd"
                      d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
                      clip-rule="evenodd"
                    />
                  </svg>
                </div>
                <!-- Search input -->
                <input
                  class="block w-full rounded-md border border-transparent bg-gray-700 py-2 pl-10 pr-3 leading-5 text-gray-300 placeholder-gray-400 focus:border-white focus:bg-white focus:text-gray-900 focus:outline-none focus:ring-white"
                  placeholder="Search"
                  type="search"
                  name="search"
                  id="search"
                />
              </div>
            </div>
          </div>
          <!-- Hamburger -->
          <div class="flex md:hidden">
            <!-- Hamburger button -->
            <button
              @click="isShowMobileMenu = !isShowMobileMenu"
              class="inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white"
              aria-controls="mobile-menu"
              aria-expanded="false"
            >
              <span class="sr-only">Hamburger</span>
              <!-- Hamburger icon-->
              <svg
                class="block h-6 w-6"
                xmlns="http://www.w3.org/2000/svg"
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
                aria-hidden="true"
              >
                <path
                  stroke-linecap="round"
                  stroke-linejoin="round"
                  stroke-width="2"
                  d="M4 6h16M4 12h16M4 18h16"
                />
              </svg>
            </button>
          </div>
        </div>
      </div>
      <!-- Mobile menu, show/hide based on isShowMobileMenu state. -->
      <div x-show="isShowMobileMenu" class="md:hidden">
        <div x-data="{ selected: 'archive' } " class="space-y-1 px-2 pt-2 pb-3">
          <a
            href="#"
            @click="selected = 'archive'"
            class="block rounded-md px-3 py-2 text-base font-medium"
            :class="selected === 'archive' ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white'"
            >Archive</a
          >
          <a
            href="#"
            @click="selected = 'series'"
            class="block rounded-md px-3 py-2 text-base font-medium"
            :class="selected === 'series' ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white'"
            >Series</a
          >
          <a
            href="#"
            @click="selected = 'tags'"
            class="block rounded-md px-3 py-2 text-base font-medium"
            :class="selected === 'tags' ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white'"
            >Tags</a
          >
          <a
            href="#"
            @click="selected = 'rss'"
            class="block rounded-md px-3 py-2 text-base font-medium"
            :class="selected === 'rss' ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white'"
            >RSS</a
          >
        </div>
      </div>
    </nav>
    <main class="mt-16">
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores
        facilis fuga iure officiis suscipit? Adipisci dolorum explicabo iste
        praesentium quas sequi, sint. Dolor esse ex itaque laboriosam saepe
        suscipit tenetur.
      </p>
    </main>
  </body>
</html>

Architecture

navbar002

All Navbar is in <nav> :

  • Desktop Navbar : the main part of Navbar
  • Mobile menu : the dropdown menu only for mobile device

Desktop Navbar

navbar003

  • Logo & menu : Logo and desktop menu
  • Search : global search
  • Hamburger : only available for mobile device

Logo & Menu

navbar004

  • Logo : available for all devices
  • Menu : only available for desktop

navbar005

  • Search icon : use SVG from Hero icon
  • Search input : global search for all device

Hamburger

navbar006

  • Hamburger button : only available for mobile device
  • Hamburger icon : use SVG from Hero icon
  • isShowMobileMenu : toggle isShowMobileMenu state to display mobile menu

Mobile Menu

navbar007

  • x-show : display mobile menu according to isShowMobileMenu state

Conclusion

  • With TailwindCSS and Alpine, we can implement almost all kinds of layouts on Responsive Web