Welcome to this blog post, where I'll walk you through building a mobile menu using only Tailwind CSS and HTML, without JavaScript. This approach is excellent for enhancing website performance, as minimizing the use of JavaScript can help your site load faster. You can check out a live example of this technique on my website. Let's get started!
Using peer-*
from Tailwind CSS for animations and state
To create the animations for our mobile menu, we'll utilize the peer-*
utility from Tailwind CSS. This allows us to control the state of a sibling element, like an <input>
element of the type checkbox
. By placing all HTML elements within the <label>
element, we can make them dependent on the state of the <input>
element. We will then hide the <input>
element and make the <label>
element respond to touch or cursor.
<label class="relative z-40 cursor-pointer px-3 py-6" for="mobile-menu">
<input class="peer hidden" type="checkbox" id="mobile-menu" />
</label>
Creating the hamburger icon with before:
and after:
pseudo-elements
To craft the hamburger icon, we'll use the before:
and after:
pseudo-elements. We'll start with a <div>
element with a height of 1px
and a width equal to the w-7
value. In this example, the middle line is set to transparent
, so we only see the lines from before:
and after:
<label class="relative z-40 cursor-pointer px-3 py-6" for="mobile-menu">
<input class="peer hidden" type="checkbox" id="mobile-menu" />
<div
class="relative z-50 block h-[1px] w-7 bg-black bg-transparent content-[''] before:absolute before:top-[-0.35rem] before:z-50 before:block before:h-full before:w-full before:bg-black before:transition-all before:duration-200 before:ease-out before:content-[''] after:absolute after:right-0 after:bottom-[-0.35rem] after:block after:h-full after:w-full after:bg-black after:transition-all after:duration-200 after:ease-out after:content-[''] peer-checked:bg-transparent before:peer-checked:top-0 before:peer-checked:w-full before:peer-checked:rotate-45 before:peer-checked:transform after:peer-checked:bottom-0 after:peer-checked:w-full after:peer-checked:-rotate-45 after:peer-checked:transform"
>
</div>
</label>
Completing the mobile menu with additional elements
Now, let's add more elements to complete the mobile menu:
- A full-screen background with a backdrop blur filter
- A
<div>
element for the menu items with an animation, which scrolls the menu from right to left - The menu itself, using a
<menu>
element (which functions like a<ul>
element, but is better for semantics in HTML)
<label class="relative z-40 cursor-pointer px-3 py-6" for="mobile-menu">
<input class="peer hidden" type="checkbox" id="mobile-menu" />
<div
class="relative z-50 block h-[1px] w-7 bg-black bg-transparent content-[''] before:absolute before:top-[-0.35rem] before:z-50 before:block before:h-full before:w-full before:bg-black before:transition-all before:duration-200 before:ease-out before:content-[''] after:absolute after:right-0 after:bottom-[-0.35rem] after:block after:h-full after:w-full after:bg-black after:transition-all after:duration-200 after:ease-out after:content-[''] peer-checked:bg-transparent before:peer-checked:top-0 before:peer-checked:w-full before:peer-checked:rotate-45 before:peer-checked:transform after:peer-checked:bottom-0 after:peer-checked:w-full after:peer-checked:-rotate-45 after:peer-checked:transform"
>
</div>
<div
class="fixed inset-0 z-40 hidden h-full w-full bg-black/50 backdrop-blur-sm peer-checked:block"
>
</div>
<div
class="fixed top-0 right-0 z-40 h-full w-full translate-x-full overflow-y-auto overscroll-y-none transition duration-500 peer-checked:translate-x-0"
>
<div class="float-right min-h-full w-[85%] bg-white px-6 pt-12 shadow-2xl">
<menu>
<li><a href="/">Home</a></li>
<li><a href="/contact">Contact</a></li>
</menu>
</div>
</div>
</label>
Conclusion
In this blog post, we've successfully built a lightweight mobile menu using Tailwind CSS and HTML without JavaScript. This approach is crucial for optimizing your website's load speed and ranking higher in search engines. So try and experience the benefits of a more performant, JavaScript-free mobile menu.
Top comments (12)
@seppegadeyne great tutorial. I was looking for a non-js solution in Tailwind. Is it possible to modify the menu the way it will act the same as here: web3templates.com/preview/astroshi...?
Hi @stankukucka, thank you for your feedback. It is also possible. I will make an example and add it to the tutorial later.
Hi @stankukucka, Thanks for working together to create a vertical dropdown menu like on web3templates.com. You can view the demo and source on Github.
Thanks @seppegadeyne it was a great experience to work together on such a "small project".
if i want to change the background color from black to white . I want it to be white before and black after click.
Hi @godfreymutebi, If you have three lines, you can do so by adjusting the background color of the before and after content + background color. So before the click, white =
before:bg-white bg-white after:bg-white
and then black after click =before:peer-checked:bg-black peer-checked:bg-black after:peer-checked:bg-black
. I hope this can help you.thanks, its what i deed
Thank you so much for sharing this, great post!
Very nice solution. I'm thinking of use similar not only for menu but to separate screens of content in mobile devices.
Great! thanks for sharing.
hi
its amazing
but i want when i click on any links in menu, menu be closed
ty