Let's build the above navigation sidebar with TailwindCSS & Nuxt.js. It's not necessarily a nuxt specific project I will be hardly using any vue/nuxt feature so tailwindcss can be used with any framework.
I will not be explaining the markup and the elements, this will just be a blueprint for making a navigation drawer with tailwind, without writing any custom css.
TL;DR
Live Demo - https://tailwind-components-pink.vercel.app/
Source code - https://github.com/fayazara/tailwind-components
1. Make a Nuxt project & add Tailwindcss
Run command npx create-nuxt-app tailwind-sidebar
& enter some project information, choose tailwind as your UI framework, Nuxt js provides tailwind setup out of the box, you dont have to do it manually. If you are using React or Vanilla JS, please follow tailwind docs.
Once project is created remove the starter code, the classes and the <logo />
component from index.vue
, also remove the styles from default.vue
2. Making the Navbar.
Here is the approach I will be taking.
Make a component called navbar.vue
and add a nav
element with flex
to it along with some padding and margin
<nav
class="flex fixed w-full items-center justify-between px-6 h-16 bg-white text-gray-700 border-b border-gray-200 z-10"
>
...
</nav>
Now add two sections, one with the button + logo and one for the desktop buttons, we have justify-between
class added to the nav element, making the navbar elements places on either ends of the screen.
We will hide the right most div, the desktop buttons on phones and smaller screens, so add the display modifier classes to the second div hidden md:block md:flex md:justify-between md:bg-transparent
3. Navigation Drawer
So technically, we will be keeping the sidebar div outside the viewport and translate it to the screen when it is toggled.
Now add a Sidebar with aside
tag with position fixed and another div which will act as an overlay with absolute positioning and center it.
Layer them with z-index n
for the overlay and z-index n+1
for the sidebar, below is a visual representation on it.
Adding the interaction
When the button is clicked, toggle translate x to full
classes on the aside tag, which will move the sidebat in and out of the screen horizontally (the x axis) and display/hide the overlay when the button is toggled.
Since I am using vue, here is how you can conditionally bind classes to any element.
<aside
class="transform top-0 left-0 w-64 bg-white fixed h-full overflow-auto ease-in-out transition-all duration-300 z-30"
:class="isOpen ? 'translate-x-0' : '-translate-x-full'">
...
</aside>
Add transition classes to these to animate then while moving.
A small caveat, the window will still be scrolling even after the sidebar is opened, I have added overflow hidden property to the body tag whenver the sidebar opens and remove it when closed, with vue's watch property.
watch: {
isOpen: {
immediate: true,
handler(isOpen) {
if (process.client) {
if (isOpen) document.body.style.setProperty("overflow", "hidden");
else document.body.style.removeProperty("overflow");
}
}
}
}
You can find the entire code here and the live demo here.
The icons are used from Vijay Verma's uilogos & illustrations from Pablo Stanley's Open Peeps
Top comments (12)
Thanks for the article.
Just checked it, works in a similar way I have explained here.
When I click on Nuxt-link the sidebar still open.. how close it when a link is clicked ? Awesome work btw! 🔥
You can add a close logic when link is clicked with @click.native="isOpen = false"
The .native ensure click happens as well page ia navigated.
The background is very cut.
Cut?
thanks!
Hi Ahmed
thank you for this great example.
how could I have the main content to shrink when the sidebar is displayed, instead of the sidebar to overlap the main content?
Wonderful... one question:
How to open menu from the right?
Replace
left-0
withright-0
to have the menu position to the right, then replace-translate-x-full
withtranslate-x-full
to have the transition change direction toward the right instead of the left.Nice
Thank you Ahmed