DEV Community

Kumar Deepanshu
Kumar Deepanshu

Posted on

Responsive NavBar using Tailwind-css and React

Let's see what we are going to build .

Final UI

So let's start with , some basic ui

const navData = [
  {
    name: "Home",
    href: "/home",
  },
  {
    name: "About",
    href: "/about",
  },
  {
    name: "Projects",
    href: "/projects",
  },
  {
    name: "Contact",
    href: "/contact",
  },
];

export default function NavBar() {
  return (
    <div className="flex container w-full mx-auto justify-between items-center font-bold text-2xl px-5  py-6">
      <Link href="/">
        <h1 className="h-[3.5rem] flex items-center text-center">Logo</h1>
      </Link>
      <nav className="hidden md:flex space-x-10 items-center">
        {navData.map((n) => {
          return (
            <Link key={n.name} href={n.href}>
              {n.name}
            </Link>
          );
        })}
      </nav>
      <div className="md:hidden">
          <button >
            <svg
              xmlns="http://www.w3.org/2000/svg"
              className="h-6 w-6"
              fill="white"
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M4 6h16M4 12h16m-7 6h7"
              />
            </svg>
          </button>
      </div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

so this is the basic ui to start
so this is the basic ui to start

Now Let's add Some Functionality for mobile view.

so first we will add some toggle function in it by create a state

const [isModalOpen, setModalOpen] = useState(false);

Enter fullscreen mode Exit fullscreen mode

and connect it to the buttton which is only visible on mobile view ,

<button onClick={() => setModalOpen(!isModalOpen)}>
          <svg
              xmlns="http://www.w3.org/2000/svg"
              className="h-6 w-6"
              fill="white"
              viewBox="0 0 24 24"
              stroke="currentColor"
               >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M4 6h16M4 12h16m-7 6h7"
              />
            </svg>
 </button>
Enter fullscreen mode Exit fullscreen mode

And i have also updated the ui code, for mobile view.
for mobile view.

Updated code

const [isModalOpen, setModalOpen] = useState(false);

  return (
    <div className="flex container w-full mx-auto justify-between items-center font-bold text-2xl px-5  py-6">
      <Link href="/">
        <h1 className="h-[3.5rem] flex items-center text-center">Logo</h1>
      </Link>
      <nav className="hidden md:flex space-x-10 items-center">
        {navData.map((n) => {
          return (
            <Link key={n.name} href={n.href}>
              {n.name}
            </Link>
          );
        })}
      </nav>
      <div className="md:hidden">
        {isModalOpen ? (
          <div
            className="bg-[#161B21] border-[1px] border-red-100/20  fixed w-[24rem] right-0 top-0 h-[100vh] transition translate-x-[-1px] rounded-lg  text-white"
          >
            <div className="pt-5 pb-6 px-5">
              <button
                onClick={() => setModalOpen(!isModalOpen)}
                className="-mr-2 float-right mb-3"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  fill="none"
                  stroke="currentColor"
                  aria-hidden="true"
                  className="h-6 w-6"
                  viewBox="0 0 24 24"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth="2"
                    d="M6 18L18 6M6 6l12 12"
                  ></path>
                </svg>
              </button>

              <div className="mt-[5rem] z-10 relative">
                <nav className="grid gap-y-8">
                  {navData.map((item) => (
                    <a
                      key={item.name}
                      href={item.href}
                      className="-m-3 p-3 flex items-center rounded-md hover:bg-black/20  border-[1px] border-gray-500/60"
                    >
                      <h1 className="my-3 ml-3 text-3xl font-bold ">
                        {item.name}
                      </h1>
                    </a>
                  ))}
                </nav>
              </div>
            </div>
          </div>
        ) : (
          <button onClick={() => setModalOpen(!isModalOpen)}>
            <svg
              xmlns="http://www.w3.org/2000/svg"
              className="h-6 w-6"
              fill="white"
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M4 6h16M4 12h16m-7 6h7"
              />
            </svg>
          </button>
        )}
      </div>
    </div>
  );

Enter fullscreen mode Exit fullscreen mode

And till now you can say we have completed a basic Responsive NavBar. And you can use it in your next big project , but there is one more addition feature for better UX, which is closing the navbar when someone click outside the navbar . Let's add that functionality also.

I am using a custom hook called useOnClickOutside , and my final code look like this


export default function NavBar() {
  const [isModalOpen, setModalOpen] = useState(false);


  const ref = useRef<HTMLDivElement>(null);
  useOnClickOutside(ref, () => setModalOpen(false));
  return (
    <div className="flex container w-full mx-auto justify-between items-center font-bold text-2xl px-5  py-6">
      <Link href="/">
        <h1 className="h-[3.5rem] flex items-center text-center">Logo</h1>
      </Link>
      <nav className="hidden md:flex space-x-10 items-center">
        {navData.map((n) => {
          return (
            <Link key={n.name} href={n.href}>
              {n.name}
            </Link>
          );
        })}
      </nav>
      <div className="md:hidden">
        {isModalOpen ? (
          <div
          ref={ref}
            className="bg-[#161B21] border-[1px] border-red-100/20  fixed w-[24rem] right-0 top-0 h-[100vh] transition translate-x-[-1px] rounded-lg  text-white"
          >
            <div className="pt-5 pb-6 px-5">
              <button
                onClick={() => setModalOpen(!isModalOpen)}
                className="-mr-2 float-right mb-3"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  fill="none"
                  stroke="currentColor"
                  aria-hidden="true"
                  className="h-6 w-6"
                  viewBox="0 0 24 24"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth="2"
                    d="M6 18L18 6M6 6l12 12"
                  ></path>
                </svg>
              </button>

              <div className="mt-[5rem] z-10 relative">
                <nav className="grid gap-y-8">
                  {navData.map((item) => (
                    <a
                      key={item.name}
                      href={item.href}
                      className="-m-3 p-3 flex items-center rounded-md hover:bg-black/20 border-[1px] border-gray-500/60"
                    >
                      <h1 className="my-3 ml-3 text-3xl font-bold ">
                        {item.name}
                      </h1>
                    </a>
                  ))}
                </nav>
              </div>
            </div>
          </div>
        ) : (
          <button onClick={() => setModalOpen(!isModalOpen)}>
            <svg
              xmlns="http://www.w3.org/2000/svg"
              className="h-6 w-6"
              fill="white"
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M4 6h16M4 12h16m-7 6h7"
              />
            </svg>
          </button>
        )}
      </div>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

Final ui

final ui

Source Code : Github

Top comments (0)