3 Tailwind3 with JSPublished 2026-10-04Free · no sign-up
Six hamburger icons and mobile menus in Tailwind: an icon that morphs into a cross, a button with a visible Menu label, a slide-out panel, a full-screen overlay with staggered links, kebab and meatball icons and a small dropdown menu.
A three-line menu icon that turns into a cross, styled entirely with Tailwind's aria-expanded: variants via group-aria-expanded:. The script only flips aria-expanded, so the animation always matches the announced state.
A pill button that shows both the icon and the word Menu, switching to Close when open. Visible text helps people who do not recognise the three-line icon and also serves as the accessible name, so no aria-label is needed.
A phone-sized header with a hamburger that slides a panel in from the left. The panel uses translate utilities toggled by a data-open attribute and the data-[open]: variant, and Escape closes it and returns focus to the button.
const sb = document.querySelector('#twso button'), sp = document.getElementById('twso-p');
function set(o) { sb.setAttribute('aria-expanded', String(o)); sp.toggleAttribute('data-open', o); if (o) sp.querySelector('a').focus(); }
sb.addEventListener('click', () => set(!sp.hasAttribute('data-open')));
document.addEventListener('keydown', e => { if (e.key === 'Escape' && sp.hasAttribute('data-open')) { set(false); sb.focus(); } });
04. Tailwind Full-Screen Menu
TailwindOverlay
A full-screen overlay menu with very large links that fade and rise in one after another. The stagger uses Tailwind's delay utilities on each link, and the overlay is invisible to keyboard and screen readers until it opens.
const ob = document.querySelector('#twfs button'), om = document.getElementById('twfs-m');
ob.addEventListener('click', () => { const o = !om.hasAttribute('data-open'); om.toggleAttribute('data-open', o); ob.setAttribute('aria-expanded', String(o)); ob.textContent = o ? 'Close' : 'Menu'; });
05. Tailwind Kebab and Meatball Icons
TailwindIcon
Vertical and horizontal three-dot overflow icons drawn with a single dot and an arbitrary box-shadow value that copies it twice. Each is a button with an accessible name, so they work as triggers for any menu.
A small-site menu where the hamburger drops a list of links below the button instead of opening a full panel. It closes on outside click and Escape, and the links keep visible focus styles on the dark background.
const hb = document.querySelector('#twhd button'), hl = document.getElementById('twhd-l');
function set(o) { hl.hidden = !o; hb.setAttribute('aria-expanded', String(o)); }
hb.addEventListener('click', () => set(hl.hidden));
document.addEventListener('click', e => { if (!e.target.closest('#twhd')) set(false); });
document.addEventListener('keydown', e => { if (e.key === 'Escape' && !hl.hidden) { set(false); hb.focus(); } });
About these Tailwind Hamburger Menus
Animate from aria-expanded
group-aria-expanded:rotate-45 and similar variants animate the bars from the button's own aria-expanded attribute, so the script only flips that attribute and the visual state always matches.
Panels with data attributes
The slide-out and overlay menus toggle a data-open attribute and use data-[open]: variants to show the panel, keeping all styling in the markup.
Staggered links
Each overlay link has its own delay utility such as delay-75 or delay-150, which creates the cascading entrance without custom keyframes.
Focus and Escape
When a menu opens, move focus to its first link; when Escape is pressed, close it and return focus to the button.
Frequently asked questions
Which Tailwind features are needed?
aria-* and data-* variants, available in v3.2 and later.
Do these need JavaScript?
A few lines to toggle state; the kebab icons need none.