Navbar
The biggest issue with Tailwind CSS is that it does not offer ready-to-use components, such as a navigation bar.
However, this is not a problem if a component library such as TW Elements comes to the rescue. Thanks to it, we can not only fully use the potential of Tailwind CSS itself, but also have dozens of ready-to-use elements at our disposal.
In this lesson, we will focus on a rather complex component, which is Navbar.
Let's jump into the code 🚀
Step 1 - add a basic example of the navbar to the project
Go to the
navbar documentation page
and copy the code of the basic example. Then paste it into the
index.html
file, inside of the
<header>
section.
<!--Main Navigation-->
<header>
<!-- Main navigation container -->
<nav
class="flex-no-wrap relative flex w-full items-center justify-between bg-neutral-100 py-2 shadow-md shadow-black/5 dark:bg-neutral-600 dark:shadow-black/10 lg:flex-wrap lg:justify-start lg:py-4"
data-twe-navbar-ref>
<div class="flex w-full flex-wrap items-center justify-between px-3">
<!-- Hamburger button for mobile view -->
<button
class="block border-0 bg-transparent px-2 text-neutral-500 hover:no-underline hover:shadow-none focus:no-underline focus:shadow-none focus:outline-none focus:ring-0 dark:text-neutral-200 lg:hidden"
type="button"
data-twe-collapse-init
data-twe-target="#navbarSupportedContent1"
aria-controls="navbarSupportedContent1"
aria-expanded="false"
aria-label="Toggle navigation">
<!-- Hamburger icon -->
<span class="[&>svg]:w-7">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="h-7 w-7">
<path
fill-rule="evenodd"
d="M3 6.75A.75.75 0 013.75 6h16.5a.75.75 0 010 1.5H3.75A.75.75 0 013 6.75zM3 12a.75.75 0 01.75-.75h16.5a.75.75 0 010 1.5H3.75A.75.75 0 013 12zm0 5.25a.75.75 0 01.75-.75h16.5a.75.75 0 010 1.5H3.75a.75.75 0 01-.75-.75z"
clip-rule="evenodd" />
</svg>
</span>
</button>
<!-- Collapsible navigation container -->
<div
class="!visible hidden flex-grow basis-[100%] items-center lg:!flex lg:basis-auto"
id="navbarSupportedContent1"
data-twe-collapse-item>
<!-- Logo -->
<a
class="mb-4 me-2 mt-3 flex items-center text-neutral-900 hover:text-neutral-900 focus:text-neutral-900 dark:text-neutral-200 dark:hover:text-neutral-400 dark:focus:text-neutral-400 lg:mb-0 lg:mt-0"
href="#">
<img
src="https://tecdn.b-cdn.net/img/logo/te-transparent-noshadows.webp"
style="height: 15px"
alt=""
loading="lazy" />
</a>
<!-- Left navigation links -->
<ul
class="list-style-none me-auto flex flex-col ps-0 lg:flex-row"
data-twe-navbar-nav-ref>
<li class="mb-4 lg:mb-0 lg:pe-2" data-twe-nav-item-ref>
<!-- Dashboard link -->
<a
class="text-neutral-500 hover:text-neutral-700 focus:text-neutral-700 disabled:text-black/30 dark:text-neutral-200 dark:hover:text-neutral-300 dark:focus:text-neutral-300 lg:px-2 [&.active]:text-black/90 dark:[&.active]:text-zinc-400"
href="#"
data-twe-nav-link-ref
>Dashboard</a
>
</li>
<!-- Team link -->
<li class="mb-4 lg:mb-0 lg:pe-2" data-twe-nav-item-ref>
<a
class="text-neutral-500 hover:text-neutral-700 focus:text-neutral-700 disabled:text-black/30 dark:text-neutral-200 dark:hover:text-neutral-300 dark:focus:text-neutral-300 lg:px-2 [&.active]:text-black/90 dark:[&.active]:text-neutral-400"
href="#"
data-twe-nav-link-ref
>Team</a
>
</li>
<!-- Projects link -->
<li class="mb-4 lg:mb-0 lg:pe-2" data-twe-nav-item-ref>
<a
class="text-neutral-500 hover:text-neutral-700 focus:text-neutral-700 disabled:text-black/30 dark:text-neutral-200 dark:hover:text-neutral-300 dark:focus:text-neutral-300 lg:px-2 [&.active]:text-black/90 dark:[&.active]:text-neutral-400"
href="#"
data-twe-nav-link-ref
>Projects</a
>
</li>
</ul>
</div>
<!-- Right elements -->
<div class="relative flex items-center">
<!-- Cart Icon -->
<a
class="me-4 text-neutral-500 hover:text-neutral-700 focus:text-neutral-700 disabled:text-black/30 dark:text-neutral-200 dark:hover:text-neutral-300 dark:focus:text-neutral-300 [&.active]:text-black/90 dark:[&.active]:text-neutral-400"
href="#">
<span class="[&>svg]:w-5">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="h-5 w-5">
<path
d="M2.25 2.25a.75.75 0 000 1.5h1.386c.17 0 .318.114.362.278l2.558 9.592a3.752 3.752 0 00-2.806 3.63c0 .414.336.75.75.75h15.75a.75.75 0 000-1.5H5.378A2.25 2.25 0 017.5 15h11.218a.75.75 0 00.674-.421 60.358 60.358 0 002.96-7.228.75.75 0 00-.525-.965A60.864 60.864 0 005.68 4.509l-.232-.867A1.875 1.875 0 003.636 2.25H2.25zM3.75 20.25a1.5 1.5 0 113 0 1.5 1.5 0 01-3 0zM16.5 20.25a1.5 1.5 0 113 0 1.5 1.5 0 01-3 0z" />
</svg>
</span>
</a>
<!-- Container with two dropdown menus -->
<div class="relative" data-twe-dropdown-ref>
<!-- First dropdown trigger -->
<a
class="hidden-arrow me-4 flex items-center text-neutral-500 hover:text-neutral-700 focus:text-neutral-700 disabled:text-black/30 dark:text-neutral-200 dark:hover:text-neutral-300 dark:focus:text-neutral-300 [&.active]:text-black/90 dark:[&.active]:text-neutral-400"
href="#"
id="dropdownMenuButton1"
role="button"
data-twe-dropdown-toggle-ref
aria-expanded="false">
<!-- Dropdown trigger icon -->
<span class="[&>svg]:w-5">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="h-5 w-5">
<path
fill-rule="evenodd"
d="M5.25 9a6.75 6.75 0 0113.5 0v.75c0 2.123.8 4.057 2.118 5.52a.75.75 0 01-.297 1.206c-1.544.57-3.16.99-4.831 1.243a3.75 3.75 0 11-7.48 0 24.585 24.585 0 01-4.831-1.244.75.75 0 01-.298-1.205A8.217 8.217 0 005.25 9.75V9zm4.502 8.9a2.25 2.25 0 104.496 0 25.057 25.057 0 01-4.496 0z"
clip-rule="evenodd" />
</svg>
</span>
<!-- Notification counter -->
<span
class="absolute -mt-2.5 ms-2 rounded-[0.37rem] bg-danger px-[0.45em] py-[0.2em] text-[0.6rem] leading-none text-white"
>1</span
>
</a>
<!-- First dropdown menu -->
<ul
class="absolute left-auto right-0 z-[1000] float-left m-0 mt-1 hidden min-w-max list-none overflow-hidden rounded-lg border-none bg-white bg-clip-padding text-left text-base shadow-lg data-[twe-dropdown-show]:block dark:bg-neutral-700"
aria-labelledby="dropdownMenuButton1"
data-twe-dropdown-menu-ref>
<!-- First dropdown menu items -->
<li>
<a
class="block w-full whitespace-nowrap bg-transparent px-4 py-2 text-sm font-normal text-neutral-700 hover:bg-neutral-100 active:text-neutral-800 active:no-underline disabled:pointer-events-none disabled:bg-transparent disabled:text-neutral-400 dark:text-neutral-200 dark:hover:bg-white/30"
href="#"
data-twe-dropdown-item-ref
>Action</a
>
</li>
<li>
<a
class="block w-full whitespace-nowrap bg-transparent px-4 py-2 text-sm font-normal text-neutral-700 hover:bg-neutral-100 active:text-neutral-800 active:no-underline disabled:pointer-events-none disabled:bg-transparent disabled:text-neutral-400 dark:text-neutral-200 dark:hover:bg-white/30"
href="#"
data-twe-dropdown-item-ref
>Another action</a
>
</li>
<li>
<a
class="block w-full whitespace-nowrap bg-transparent px-4 py-2 text-sm font-normal text-neutral-700 hover:bg-neutral-100 active:text-neutral-800 active:no-underline disabled:pointer-events-none disabled:bg-transparent disabled:text-neutral-400 dark:text-neutral-200 dark:hover:bg-white/30"
href="#"
data-twe-dropdown-item-ref
>Something else here</a
>
</li>
</ul>
</div>
<!-- Second dropdown container -->
<div class="relative" data-twe-dropdown-ref>
<!-- Second dropdown trigger -->
<a
class="hidden-arrow flex items-center whitespace-nowrap transition duration-150 ease-in-out motion-reduce:transition-none"
href="#"
id="dropdownMenuButton2"
role="button"
data-twe-dropdown-toggle-ref
aria-expanded="false">
<!-- User avatar -->
<img
src="https://tecdn.b-cdn.net/img/new/avatars/2.jpg"
class="rounded-full"
style="height: 25px; width: 25px"
alt=""
loading="lazy" />
</a>
<!-- Second dropdown menu -->
<ul
class="absolute left-auto right-0 z-[1000] float-left m-0 mt-1 hidden min-w-max list-none overflow-hidden rounded-lg border-none bg-white bg-clip-padding text-left text-base shadow-lg data-[twe-dropdown-show]:block dark:bg-neutral-700"
aria-labelledby="dropdownMenuButton2"
data-twe-dropdown-menu-ref>
<!-- Second dropdown menu items -->
<li>
<a
class="block w-full whitespace-nowrap bg-transparent px-4 py-2 text-sm font-normal text-neutral-700 hover:bg-neutral-100 active:text-neutral-800 active:no-underline disabled:pointer-events-none disabled:bg-transparent disabled:text-neutral-400 dark:text-neutral-200 dark:hover:bg-white/30"
href="#"
data-twe-dropdown-item-ref
>Action</a
>
</li>
<li>
<a
class="block w-full whitespace-nowrap bg-transparent px-4 py-2 text-sm font-normal text-neutral-700 hover:bg-neutral-100 active:text-neutral-800 active:no-underline disabled:pointer-events-none disabled:bg-transparent disabled:text-neutral-400 dark:text-neutral-200 dark:hover:bg-white/30"
href="#"
data-twe-dropdown-item-ref
>Another action</a
>
</li>
<li>
<a
class="block w-full whitespace-nowrap bg-transparent px-4 py-2 text-sm font-normal text-neutral-700 hover:bg-neutral-100 active:text-neutral-800 active:no-underline disabled:pointer-events-none disabled:bg-transparent disabled:text-neutral-400 dark:text-neutral-200 dark:hover:bg-white/30"
href="#"
data-twe-dropdown-item-ref
>Something else here</a
>
</li>
</ul>
</div>
</div>
</div>
</nav>
</header>
<!--Main Navigation-->
I know, I know, that's really a lot of code and a terrifying number of classes. However, this is perfectly normal in Tailwind, and you'll soon understand why.
Anyway, after saving the file you should see a navigation bar in your project.
By the way, for now you can remove the grid from the
<main>
section. It was there just as an example to learn
from and we don't need it anymore. Clear the
<main>
section so it's empty again:
<!--Main layout-->
<main></main>
<!--Main layout-->
Step 2 - initialize the navbar
We mentioned this in the previous lesson - our navbar looks good, but unfortunately it doesn't work properly yet. If you reduce the size of the browser window to the mobile size and click on the hamburger icon, you will see that the menu does not expand.
This is because we still need to initialize the component.
Initializing simply means calling the component/adding it to our project.
Initialization is extremely important in optimization. TW Elements is a huge library with many components, but it is very rare that you need all of these components in every project.
Through initialization, you indicate which components are to be included in your project and thanks to this, our library can then do the so-called tree shaking.
Tree shaking is a method of optimizing code for production by eliminating dead or unused code.
The term itself comes from the mental image of shaking a tree to remove dead leaves. When building an application for production, it's crucial to ensure that the size of the final bundle is as small as possible to reduce load times and improve performance.
This process significantly trims the final bundle size, leading to faster load times and a more efficient application.
So again, go to the navbar documentation page and from the basic example click the "JavaScript" tab and copy the initialization code.
Then go to src/js/index.js
and replace the code you will find
there with the one you just copied.
// Initialization for ES Users
import {
Collapse,
Dropdown,
initTWE,
} from "tw-elements";
initTWE({ Collapse, Dropdown });
After saving the file you should see all the interactive elements (like hamburger or dropdown) work properly.
Alright, we have a working navbar!
However, this is only the beginning of our adventure with him. Since it's a complex component, we'll spend some time with it and use it to explain some important concepts.
About author
Michal Szymanski
Co Founder at TW Elements and MDBootstrap / Listed in Forbes „30 under 30" / Open-source enthusiast / Dancer, nerd & book lover.
Author of hundreds of articles on programming, business, marketing and productivity. In the past, an educator working with troubled youth in orphanages and correctional facilities.