05 / 16
All 16 in 16 Tailwind CSS Mobile Navbars & Menus
- 01Tailwind CSS Hamburger Menu with Slide-Out Drawer (No JavaScript)
- 02Tailwind Full-Screen Overlay Menu with Circle Reveal Animation
- 03Tailwind CSS iOS Bottom Tab Bar Navigation
- 04Tailwind Animated Hamburger to X Icon with Dropdown Menu
- 05Tailwind Radial Menu — Circular FAB Fan-Out Navigation
- 06Tailwind Swipeable Sidebar Menu with Touch Gestures
- 07Tailwind Floating Action Button (FAB) Speed Dial Menu
- 08Tailwind Tabs with Animated Sliding Pill Indicator
- 09Tailwind Mobile Mega Menu with Accordion Dropdowns
- 10Tailwind Glassmorphism Sidebar Navigation Drawer
- 11Tailwind Cyberpunk Neon Full-Screen Menu
- 12Tailwind Carousel with Dot Navigation, Swipe & Autoplay Progress
- 13Tailwind Collapsible Breadcrumb with Ellipsis Dropdown
- 14Tailwind Split-Screen Sidebar Category Navigation
- 15Tailwind Command Palette — Cmd+K Search Menu
- 16Tailwind Neumorphic Bottom Navigation Bar
Tailwind Radial Menu — Circular FAB Fan-Out Navigation
A floating action button whose plus spins into an X while five labelled actions spring out along a 140px arc, each 50ms behind the last. The port fixes the original's dead overlay — it was a plain <div>, so tapping outside never closed the menu — by making it a <label>. Zero JavaScript.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tmn-05 w-full min-h-svh grid place-items-center bg-tmn05-stage bg-[radial-gradient(70%_50%_at_50%_100%,var(--color-tmn05-glow),transparent)] px-4 py-6 font-tmn05-sans antialiased" aria-label="Tailwind radial FAB menu demo">
<div class="group relative h-[min(667px,calc(100svh-3rem))] w-full max-w-[375px] overflow-hidden rounded-[2.25rem] bg-tmn05-bg text-tmn05-ink shadow-[0_40px_100px_-30px_oklch(0_0_0/0.85)] ring-1 ring-white/8">
<input type="checkbox" id="tmn-05-toggle" class="peer sr-only" aria-label="Toggle quick actions">
<main class="absolute inset-0 overflow-y-auto px-5 pt-6 pb-28">
<p class="mb-8 text-[22px] font-extrabold tracking-[-0.03em]">Spark<span class="text-tmn05-acc">AI</span></p>
<h1 class="mb-2 text-[28px] leading-[1.15] font-bold tracking-[-0.03em] text-balance">Your creative workspace</h1>
<p class="mb-6 text-sm leading-relaxed text-tmn05-mut">Generate, edit and share visuals with AI-powered tools.</p>
<dl class="mb-6 grid grid-cols-3 gap-2.5">
<div class="rounded-2xl border border-white/6 bg-tmn05-surface p-3.5"><dt class="text-[11px] text-tmn05-mut">Creations</dt><dd class="text-xl font-bold">248</dd></div>
<div class="rounded-2xl border border-white/6 bg-tmn05-surface p-3.5"><dt class="text-[11px] text-tmn05-mut">Views</dt><dd class="text-xl font-bold">12k</dd></div>
<div class="rounded-2xl border border-white/6 bg-tmn05-surface p-3.5"><dt class="text-[11px] text-tmn05-mut">Likes</dt><dd class="text-xl font-bold">94</dd></div>
</dl>
<p class="mb-3 text-[13px] font-semibold text-tmn05-mut">Recent</p>
<div class="grid grid-cols-2 gap-2.5">
<div class="aspect-square rounded-2xl bg-[conic-gradient(from_200deg_at_30%_70%,#6366f1,#ec4899,#f59e0b,#6366f1)]"></div>
<div class="aspect-square rounded-2xl bg-[radial-gradient(circle_at_70%_30%,#14b8a6,#0f172a_70%)]"></div>
</div>
</main>
<label for="tmn-05-toggle" aria-hidden="true" class="pointer-events-none absolute inset-0 z-10 bg-tmn05-bg/70 opacity-0 backdrop-blur-[2px] transition-opacity duration-300 group-has-checked:pointer-events-auto group-has-checked:opacity-100"></label>
<nav aria-label="Quick actions">
<a href="#" class="invisible absolute right-[53px] bottom-[171px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[30ms] focus-visible:outline-none"><span class="grid size-12 place-items-center rounded-full bg-teal-500 text-white shadow-lg shadow-black/40 ring-tmn05-ink focus-visible:ring-2"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-5-5L5 21"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Gallery</span></a>
<a href="#" class="invisible absolute right-[103px] bottom-[152px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[80ms]"><span class="grid size-12 place-items-center rounded-full bg-amber-500 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 1 1 3 3L7 19l-4 1 1-4z"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Edit</span></a>
<a href="#" class="invisible absolute right-[136px] bottom-[123px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[130ms]"><span class="grid size-12 place-items-center rounded-full bg-green-500 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8M16 6l-4-4-4 4M12 2v13"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Share</span></a>
<a href="#" class="invisible absolute right-[159px] bottom-[86px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[180ms]"><span class="grid size-12 place-items-center rounded-full bg-tmn05-acc2 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="m12 3 2.8 5.7 6.2.9-4.5 4.4 1 6.2L12 17.3 6.5 20.2l1-6.2L3 9.6l6.2-.9z"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Favorites</span></a>
<a href="#" class="invisible absolute right-[168px] bottom-[45px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[230ms]"><span class="grid size-12 place-items-center rounded-full bg-sky-500 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="M4 6h10M18 6h2M4 12h4M12 12h8M4 18h12"/><circle cx="16" cy="6" r="2"/><circle cx="10" cy="12" r="2"/><circle cx="18" cy="18" r="2"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Settings</span></a>
</nav>
<label for="tmn-05-toggle" class="absolute right-6 bottom-7 z-30 grid size-[58px] cursor-pointer place-items-center rounded-full bg-tmn05-acc text-white shadow-[0_10px_30px_-6px_var(--color-tmn05-acc)] transition duration-300 hover:scale-105 active:scale-95 group-has-checked:bg-tmn05-acc2 group-has-checked:shadow-[0_10px_30px_-6px_var(--color-tmn05-acc2)] peer-focus-visible:ring-2 peer-focus-visible:ring-white peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-tmn05-bg">
<svg viewBox="0 0 24 24" class="size-6 stroke-[2.2] transition-transform duration-300 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:rotate-45" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
</label>
</div>
</section><section class="tmn-05 w-full min-h-svh grid place-items-center bg-tmn05-stage bg-[radial-gradient(70%_50%_at_50%_100%,var(--color-tmn05-glow),transparent)] px-4 py-6 font-tmn05-sans antialiased" aria-label="Tailwind radial FAB menu demo">
<div class="group relative h-[min(667px,calc(100svh-3rem))] w-full max-w-[375px] overflow-hidden rounded-[2.25rem] bg-tmn05-bg text-tmn05-ink shadow-[0_40px_100px_-30px_oklch(0_0_0/0.85)] ring-1 ring-white/8">
<input type="checkbox" id="tmn-05-toggle" class="peer sr-only" aria-label="Toggle quick actions">
<main class="absolute inset-0 overflow-y-auto px-5 pt-6 pb-28">
<p class="mb-8 text-[22px] font-extrabold tracking-[-0.03em]">Spark<span class="text-tmn05-acc">AI</span></p>
<h1 class="mb-2 text-[28px] leading-[1.15] font-bold tracking-[-0.03em] text-balance">Your creative workspace</h1>
<p class="mb-6 text-sm leading-relaxed text-tmn05-mut">Generate, edit and share visuals with AI-powered tools.</p>
<dl class="mb-6 grid grid-cols-3 gap-2.5">
<div class="rounded-2xl border border-white/6 bg-tmn05-surface p-3.5"><dt class="text-[11px] text-tmn05-mut">Creations</dt><dd class="text-xl font-bold">248</dd></div>
<div class="rounded-2xl border border-white/6 bg-tmn05-surface p-3.5"><dt class="text-[11px] text-tmn05-mut">Views</dt><dd class="text-xl font-bold">12k</dd></div>
<div class="rounded-2xl border border-white/6 bg-tmn05-surface p-3.5"><dt class="text-[11px] text-tmn05-mut">Likes</dt><dd class="text-xl font-bold">94</dd></div>
</dl>
<p class="mb-3 text-[13px] font-semibold text-tmn05-mut">Recent</p>
<div class="grid grid-cols-2 gap-2.5">
<div class="aspect-square rounded-2xl bg-[conic-gradient(from_200deg_at_30%_70%,#6366f1,#ec4899,#f59e0b,#6366f1)]"></div>
<div class="aspect-square rounded-2xl bg-[radial-gradient(circle_at_70%_30%,#14b8a6,#0f172a_70%)]"></div>
</div>
</main>
<label for="tmn-05-toggle" aria-hidden="true" class="pointer-events-none absolute inset-0 z-10 bg-tmn05-bg/70 opacity-0 backdrop-blur-[2px] transition-opacity duration-300 group-has-checked:pointer-events-auto group-has-checked:opacity-100"></label>
<nav aria-label="Quick actions">
<a href="#" class="invisible absolute right-[53px] bottom-[171px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[30ms] focus-visible:outline-none"><span class="grid size-12 place-items-center rounded-full bg-teal-500 text-white shadow-lg shadow-black/40 ring-tmn05-ink focus-visible:ring-2"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-5-5L5 21"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Gallery</span></a>
<a href="#" class="invisible absolute right-[103px] bottom-[152px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[80ms]"><span class="grid size-12 place-items-center rounded-full bg-amber-500 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 1 1 3 3L7 19l-4 1 1-4z"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Edit</span></a>
<a href="#" class="invisible absolute right-[136px] bottom-[123px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[130ms]"><span class="grid size-12 place-items-center rounded-full bg-green-500 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8M16 6l-4-4-4 4M12 2v13"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Share</span></a>
<a href="#" class="invisible absolute right-[159px] bottom-[86px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[180ms]"><span class="grid size-12 place-items-center rounded-full bg-tmn05-acc2 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="m12 3 2.8 5.7 6.2.9-4.5 4.4 1 6.2L12 17.3 6.5 20.2l1-6.2L3 9.6l6.2-.9z"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Favorites</span></a>
<a href="#" class="invisible absolute right-[168px] bottom-[45px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[230ms]"><span class="grid size-12 place-items-center rounded-full bg-sky-500 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="M4 6h10M18 6h2M4 12h4M12 12h8M4 18h12"/><circle cx="16" cy="6" r="2"/><circle cx="10" cy="12" r="2"/><circle cx="18" cy="18" r="2"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Settings</span></a>
</nav>
<label for="tmn-05-toggle" class="absolute right-6 bottom-7 z-30 grid size-[58px] cursor-pointer place-items-center rounded-full bg-tmn05-acc text-white shadow-[0_10px_30px_-6px_var(--color-tmn05-acc)] transition duration-300 hover:scale-105 active:scale-95 group-has-checked:bg-tmn05-acc2 group-has-checked:shadow-[0_10px_30px_-6px_var(--color-tmn05-acc2)] peer-focus-visible:ring-2 peer-focus-visible:ring-white peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-tmn05-bg">
<svg viewBox="0 0 24 24" class="size-6 stroke-[2.2] transition-transform duration-300 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:rotate-45" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
</label>
</div>
</section>@import "tailwindcss";
@theme {
--color-tmn05-stage: #060a16;
--color-tmn05-stage: oklch(0.15 0.025 265);
--color-tmn05-glow: #2b2a6b80;
--color-tmn05-glow: oklch(0.32 0.11 278 / 0.5);
--color-tmn05-bg: #0f172a;
--color-tmn05-bg: oklch(0.21 0.04 265);
--color-tmn05-surface: #1e293b;
--color-tmn05-surface: oklch(0.28 0.04 260);
--color-tmn05-ink: #f1f5f9;
--color-tmn05-ink: oklch(0.97 0.007 248);
--color-tmn05-mut: #94a3b8;
--color-tmn05-mut: oklch(0.71 0.035 257);
--color-tmn05-acc: #6366f1;
--color-tmn05-acc: oklch(0.59 0.2 277);
--color-tmn05-acc2: #ec4899;
--color-tmn05-acc2: oklch(0.66 0.21 354);
--font-tmn05-sans: 'Sora', system-ui, sans-serif;
}
/* Icon base: utilities still win because this sits in the base layer. */
@layer base {
.tmn-05 svg {
fill: none;
stroke: currentColor;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
flex: none;
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in utilities, so the stage is
sized before the browser build compiles. */
.tmn-05 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tmn05-stage: #060a16;
--color-tmn05-stage: oklch(0.15 0.025 265);
--color-tmn05-glow: #2b2a6b80;
--color-tmn05-glow: oklch(0.32 0.11 278 / 0.5);
--color-tmn05-bg: #0f172a;
--color-tmn05-bg: oklch(0.21 0.04 265);
--color-tmn05-surface: #1e293b;
--color-tmn05-surface: oklch(0.28 0.04 260);
--color-tmn05-ink: #f1f5f9;
--color-tmn05-ink: oklch(0.97 0.007 248);
--color-tmn05-mut: #94a3b8;
--color-tmn05-mut: oklch(0.71 0.035 257);
--color-tmn05-acc: #6366f1;
--color-tmn05-acc: oklch(0.59 0.2 277);
--color-tmn05-acc2: #ec4899;
--color-tmn05-acc2: oklch(0.66 0.21 354);
--font-tmn05-sans: 'Sora', system-ui, sans-serif;
}
/* Icon base: utilities still win because this sits in the base layer. */
@layer base {
.tmn-05 svg {
fill: none;
stroke: currentColor;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
flex: none;
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in utilities, so the stage is
sized before the browser build compiles. */
.tmn-05 {
width: 100%;
min-height: 100svh;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tmn05-stage: #060a16;
--color-tmn05-stage: oklch(0.15 0.025 265);
--color-tmn05-glow: #2b2a6b80;
--color-tmn05-glow: oklch(0.32 0.11 278 / 0.5);
--color-tmn05-bg: #0f172a;
--color-tmn05-bg: oklch(0.21 0.04 265);
--color-tmn05-surface: #1e293b;
--color-tmn05-surface: oklch(0.28 0.04 260);
--color-tmn05-ink: #f1f5f9;
--color-tmn05-ink: oklch(0.97 0.007 248);
--color-tmn05-mut: #94a3b8;
--color-tmn05-mut: oklch(0.71 0.035 257);
--color-tmn05-acc: #6366f1;
--color-tmn05-acc: oklch(0.59 0.2 277);
--color-tmn05-acc2: #ec4899;
--color-tmn05-acc2: oklch(0.66 0.21 354);
--font-tmn05-sans: 'Sora', system-ui, sans-serif;
}
/* Icon base: utilities still win because this sits in the base layer. */
@layer base {
.tmn-05 svg {
fill: none;
stroke: currentColor;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
flex: none;
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in utilities, so the stage is
sized before the browser build compiles. */
.tmn-05 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tmn05-stage: #060a16;
--color-tmn05-stage: oklch(0.15 0.025 265);
--color-tmn05-glow: #2b2a6b80;
--color-tmn05-glow: oklch(0.32 0.11 278 / 0.5);
--color-tmn05-bg: #0f172a;
--color-tmn05-bg: oklch(0.21 0.04 265);
--color-tmn05-surface: #1e293b;
--color-tmn05-surface: oklch(0.28 0.04 260);
--color-tmn05-ink: #f1f5f9;
--color-tmn05-ink: oklch(0.97 0.007 248);
--color-tmn05-mut: #94a3b8;
--color-tmn05-mut: oklch(0.71 0.035 257);
--color-tmn05-acc: #6366f1;
--color-tmn05-acc: oklch(0.59 0.2 277);
--color-tmn05-acc2: #ec4899;
--color-tmn05-acc2: oklch(0.66 0.21 354);
--font-tmn05-sans: 'Sora', system-ui, sans-serif;
}
/* Icon base: utilities still win because this sits in the base layer. */
@layer base {
.tmn-05 svg {
fill: none;
stroke: currentColor;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
flex: none;
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in utilities, so the stage is
sized before the browser build compiles. */
.tmn-05 {
width: 100%;
min-height: 100svh;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Sora:wght@400;500;600;700;800&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Sora:wght@400;500;600;700;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Ten
:nth-childposition and delay rules became inline arbitrary insets plusgroup-has-checked:delay-[…]on each item — the arc maths is documented inhowItWorks, not hidden in a stylesheet. transform: rotate(45deg)moved from the button to the icon, so the button's focus ring and shadow stay upright.- Bug fix from the CSS original: the overlay was a
<div>, so tapping outside never closed the fan; it is now a<label for>scrim with a soft blur. - UI upgrade: emoji became stroke icons on solid colour discs, items are real links (focusable, invisible when closed), stats became a semantic
<dl>, and muted copy rose from slate-500 (3.7:1) to slate-400 (6.9:1).
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Radial Menu — Circular FAB Fan-Out Navigation
Source: https://codefronts.com/navigation/tailwind-css-mobile-navbar/tailwind-radial-fab-menu-circular-navigation/
A floating action button whose plus spins into an X while five labelled actions spring out along a 140px arc, each 50ms behind the last. The port fixes the original's dead overlay — it was a plain <div>, so tapping outside never closed the menu — by making it a <label>. Zero JavaScript.
## HTML
```html
<section class="tmn-05 w-full min-h-svh grid place-items-center bg-tmn05-stage bg-[radial-gradient(70%_50%_at_50%_100%,var(--color-tmn05-glow),transparent)] px-4 py-6 font-tmn05-sans antialiased" aria-label="Tailwind radial FAB menu demo">
<div class="group relative h-[min(667px,calc(100svh-3rem))] w-full max-w-[375px] overflow-hidden rounded-[2.25rem] bg-tmn05-bg text-tmn05-ink shadow-[0_40px_100px_-30px_oklch(0_0_0/0.85)] ring-1 ring-white/8">
<input type="checkbox" id="tmn-05-toggle" class="peer sr-only" aria-label="Toggle quick actions">
<main class="absolute inset-0 overflow-y-auto px-5 pt-6 pb-28">
<p class="mb-8 text-[22px] font-extrabold tracking-[-0.03em]">Spark<span class="text-tmn05-acc">AI</span></p>
<h1 class="mb-2 text-[28px] leading-[1.15] font-bold tracking-[-0.03em] text-balance">Your creative workspace</h1>
<p class="mb-6 text-sm leading-relaxed text-tmn05-mut">Generate, edit and share visuals with AI-powered tools.</p>
<dl class="mb-6 grid grid-cols-3 gap-2.5">
<div class="rounded-2xl border border-white/6 bg-tmn05-surface p-3.5"><dt class="text-[11px] text-tmn05-mut">Creations</dt><dd class="text-xl font-bold">248</dd></div>
<div class="rounded-2xl border border-white/6 bg-tmn05-surface p-3.5"><dt class="text-[11px] text-tmn05-mut">Views</dt><dd class="text-xl font-bold">12k</dd></div>
<div class="rounded-2xl border border-white/6 bg-tmn05-surface p-3.5"><dt class="text-[11px] text-tmn05-mut">Likes</dt><dd class="text-xl font-bold">94</dd></div>
</dl>
<p class="mb-3 text-[13px] font-semibold text-tmn05-mut">Recent</p>
<div class="grid grid-cols-2 gap-2.5">
<div class="aspect-square rounded-2xl bg-[conic-gradient(from_200deg_at_30%_70%,#6366f1,#ec4899,#f59e0b,#6366f1)]"></div>
<div class="aspect-square rounded-2xl bg-[radial-gradient(circle_at_70%_30%,#14b8a6,#0f172a_70%)]"></div>
</div>
</main>
<label for="tmn-05-toggle" aria-hidden="true" class="pointer-events-none absolute inset-0 z-10 bg-tmn05-bg/70 opacity-0 backdrop-blur-[2px] transition-opacity duration-300 group-has-checked:pointer-events-auto group-has-checked:opacity-100"></label>
<nav aria-label="Quick actions">
<a href="#" class="invisible absolute right-[53px] bottom-[171px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[30ms] focus-visible:outline-none"><span class="grid size-12 place-items-center rounded-full bg-teal-500 text-white shadow-lg shadow-black/40 ring-tmn05-ink focus-visible:ring-2"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-5-5L5 21"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Gallery</span></a>
<a href="#" class="invisible absolute right-[103px] bottom-[152px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[80ms]"><span class="grid size-12 place-items-center rounded-full bg-amber-500 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 1 1 3 3L7 19l-4 1 1-4z"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Edit</span></a>
<a href="#" class="invisible absolute right-[136px] bottom-[123px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[130ms]"><span class="grid size-12 place-items-center rounded-full bg-green-500 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8M16 6l-4-4-4 4M12 2v13"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Share</span></a>
<a href="#" class="invisible absolute right-[159px] bottom-[86px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[180ms]"><span class="grid size-12 place-items-center rounded-full bg-tmn05-acc2 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="m12 3 2.8 5.7 6.2.9-4.5 4.4 1 6.2L12 17.3 6.5 20.2l1-6.2L3 9.6l6.2-.9z"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Favorites</span></a>
<a href="#" class="invisible absolute right-[168px] bottom-[45px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[230ms]"><span class="grid size-12 place-items-center rounded-full bg-sky-500 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="M4 6h10M18 6h2M4 12h4M12 12h8M4 18h12"/><circle cx="16" cy="6" r="2"/><circle cx="10" cy="12" r="2"/><circle cx="18" cy="18" r="2"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Settings</span></a>
</nav>
<label for="tmn-05-toggle" class="absolute right-6 bottom-7 z-30 grid size-[58px] cursor-pointer place-items-center rounded-full bg-tmn05-acc text-white shadow-[0_10px_30px_-6px_var(--color-tmn05-acc)] transition duration-300 hover:scale-105 active:scale-95 group-has-checked:bg-tmn05-acc2 group-has-checked:shadow-[0_10px_30px_-6px_var(--color-tmn05-acc2)] peer-focus-visible:ring-2 peer-focus-visible:ring-white peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-tmn05-bg">
<svg viewBox="0 0 24 24" class="size-6 stroke-[2.2] transition-transform duration-300 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:rotate-45" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
</label>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tmn05-stage: #060a16;
--color-tmn05-stage: oklch(0.15 0.025 265);
--color-tmn05-glow: #2b2a6b80;
--color-tmn05-glow: oklch(0.32 0.11 278 / 0.5);
--color-tmn05-bg: #0f172a;
--color-tmn05-bg: oklch(0.21 0.04 265);
--color-tmn05-surface: #1e293b;
--color-tmn05-surface: oklch(0.28 0.04 260);
--color-tmn05-ink: #f1f5f9;
--color-tmn05-ink: oklch(0.97 0.007 248);
--color-tmn05-mut: #94a3b8;
--color-tmn05-mut: oklch(0.71 0.035 257);
--color-tmn05-acc: #6366f1;
--color-tmn05-acc: oklch(0.59 0.2 277);
--color-tmn05-acc2: #ec4899;
--color-tmn05-acc2: oklch(0.66 0.21 354);
--font-tmn05-sans: 'Sora', system-ui, sans-serif;
}
/* Icon base: utilities still win because this sits in the base layer. */
@layer base {
.tmn-05 svg {
fill: none;
stroke: currentColor;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
flex: none;
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in utilities, so the stage is
sized before the browser build compiles. */
.tmn-05 {
width: 100%;
min-height: 100svh;
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Radial Menu — Circular FAB Fan-Out Navigation
Source: https://codefronts.com/navigation/tailwind-css-mobile-navbar/tailwind-radial-fab-menu-circular-navigation/
A floating action button whose plus spins into an X while five labelled actions spring out along a 140px arc, each 50ms behind the last. The port fixes the original's dead overlay — it was a plain <div>, so tapping outside never closed the menu — by making it a <label>. Zero JavaScript.
## HTML
```html
<section class="tmn-05 w-full min-h-svh grid place-items-center bg-tmn05-stage bg-[radial-gradient(70%_50%_at_50%_100%,var(--color-tmn05-glow),transparent)] px-4 py-6 font-tmn05-sans antialiased" aria-label="Tailwind radial FAB menu demo">
<div class="group relative h-[min(667px,calc(100svh-3rem))] w-full max-w-[375px] overflow-hidden rounded-[2.25rem] bg-tmn05-bg text-tmn05-ink shadow-[0_40px_100px_-30px_oklch(0_0_0/0.85)] ring-1 ring-white/8">
<input type="checkbox" id="tmn-05-toggle" class="peer sr-only" aria-label="Toggle quick actions">
<main class="absolute inset-0 overflow-y-auto px-5 pt-6 pb-28">
<p class="mb-8 text-[22px] font-extrabold tracking-[-0.03em]">Spark<span class="text-tmn05-acc">AI</span></p>
<h1 class="mb-2 text-[28px] leading-[1.15] font-bold tracking-[-0.03em] text-balance">Your creative workspace</h1>
<p class="mb-6 text-sm leading-relaxed text-tmn05-mut">Generate, edit and share visuals with AI-powered tools.</p>
<dl class="mb-6 grid grid-cols-3 gap-2.5">
<div class="rounded-2xl border border-white/6 bg-tmn05-surface p-3.5"><dt class="text-[11px] text-tmn05-mut">Creations</dt><dd class="text-xl font-bold">248</dd></div>
<div class="rounded-2xl border border-white/6 bg-tmn05-surface p-3.5"><dt class="text-[11px] text-tmn05-mut">Views</dt><dd class="text-xl font-bold">12k</dd></div>
<div class="rounded-2xl border border-white/6 bg-tmn05-surface p-3.5"><dt class="text-[11px] text-tmn05-mut">Likes</dt><dd class="text-xl font-bold">94</dd></div>
</dl>
<p class="mb-3 text-[13px] font-semibold text-tmn05-mut">Recent</p>
<div class="grid grid-cols-2 gap-2.5">
<div class="aspect-square rounded-2xl bg-[conic-gradient(from_200deg_at_30%_70%,#6366f1,#ec4899,#f59e0b,#6366f1)]"></div>
<div class="aspect-square rounded-2xl bg-[radial-gradient(circle_at_70%_30%,#14b8a6,#0f172a_70%)]"></div>
</div>
</main>
<label for="tmn-05-toggle" aria-hidden="true" class="pointer-events-none absolute inset-0 z-10 bg-tmn05-bg/70 opacity-0 backdrop-blur-[2px] transition-opacity duration-300 group-has-checked:pointer-events-auto group-has-checked:opacity-100"></label>
<nav aria-label="Quick actions">
<a href="#" class="invisible absolute right-[53px] bottom-[171px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[30ms] focus-visible:outline-none"><span class="grid size-12 place-items-center rounded-full bg-teal-500 text-white shadow-lg shadow-black/40 ring-tmn05-ink focus-visible:ring-2"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-5-5L5 21"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Gallery</span></a>
<a href="#" class="invisible absolute right-[103px] bottom-[152px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[80ms]"><span class="grid size-12 place-items-center rounded-full bg-amber-500 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 1 1 3 3L7 19l-4 1 1-4z"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Edit</span></a>
<a href="#" class="invisible absolute right-[136px] bottom-[123px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[130ms]"><span class="grid size-12 place-items-center rounded-full bg-green-500 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8M16 6l-4-4-4 4M12 2v13"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Share</span></a>
<a href="#" class="invisible absolute right-[159px] bottom-[86px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[180ms]"><span class="grid size-12 place-items-center rounded-full bg-tmn05-acc2 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="m12 3 2.8 5.7 6.2.9-4.5 4.4 1 6.2L12 17.3 6.5 20.2l1-6.2L3 9.6l6.2-.9z"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Favorites</span></a>
<a href="#" class="invisible absolute right-[168px] bottom-[45px] z-20 flex translate-y-5 scale-70 flex-row-reverse items-center gap-2 opacity-0 transition duration-400 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:visible group-has-checked:translate-y-0 group-has-checked:scale-100 group-has-checked:opacity-100 group-has-checked:delay-[230ms]"><span class="grid size-12 place-items-center rounded-full bg-sky-500 text-white shadow-lg shadow-black/40"><svg viewBox="0 0 24 24" class="size-5" aria-hidden="true"><path d="M4 6h10M18 6h2M4 12h4M12 12h8M4 18h12"/><circle cx="16" cy="6" r="2"/><circle cx="10" cy="12" r="2"/><circle cx="18" cy="18" r="2"/></svg></span><span class="rounded-full bg-black/70 px-2.5 py-1 text-[11px] font-semibold whitespace-nowrap">Settings</span></a>
</nav>
<label for="tmn-05-toggle" class="absolute right-6 bottom-7 z-30 grid size-[58px] cursor-pointer place-items-center rounded-full bg-tmn05-acc text-white shadow-[0_10px_30px_-6px_var(--color-tmn05-acc)] transition duration-300 hover:scale-105 active:scale-95 group-has-checked:bg-tmn05-acc2 group-has-checked:shadow-[0_10px_30px_-6px_var(--color-tmn05-acc2)] peer-focus-visible:ring-2 peer-focus-visible:ring-white peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-tmn05-bg">
<svg viewBox="0 0 24 24" class="size-6 stroke-[2.2] transition-transform duration-300 ease-[cubic-bezier(.34,1.56,.64,1)] group-has-checked:rotate-45" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
</label>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tmn05-stage: #060a16;
--color-tmn05-stage: oklch(0.15 0.025 265);
--color-tmn05-glow: #2b2a6b80;
--color-tmn05-glow: oklch(0.32 0.11 278 / 0.5);
--color-tmn05-bg: #0f172a;
--color-tmn05-bg: oklch(0.21 0.04 265);
--color-tmn05-surface: #1e293b;
--color-tmn05-surface: oklch(0.28 0.04 260);
--color-tmn05-ink: #f1f5f9;
--color-tmn05-ink: oklch(0.97 0.007 248);
--color-tmn05-mut: #94a3b8;
--color-tmn05-mut: oklch(0.71 0.035 257);
--color-tmn05-acc: #6366f1;
--color-tmn05-acc: oklch(0.59 0.2 277);
--color-tmn05-acc2: #ec4899;
--color-tmn05-acc2: oklch(0.66 0.21 354);
--font-tmn05-sans: 'Sora', system-ui, sans-serif;
}
/* Icon base: utilities still win because this sits in the base layer. */
@layer base {
.tmn-05 svg {
fill: none;
stroke: currentColor;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
flex: none;
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in utilities, so the stage is
sized before the browser build compiles. */
.tmn-05 {
width: 100%;
min-height: 100svh;
}
```How this works
The arc. With the FAB centre at bottom:57px right:53px and 48px buttons, each item sits at right = 29 + 140·sin θ, bottom = 33 + 140·cos θ for θ = 10°, 32°, 50°, 68°, 85° — a non-linear spread so labels near the top never collide.
<a class="absolute bottom-[152px] right-[103px] scale-70 opacity-0 invisible
group-has-checked:visible group-has-checked:scale-100 group-has-checked:opacity-100
group-has-checked:delay-[80ms]">Closing. The scrim is a <label for>, so any tap outside unchecks the toggle. The plus icon (not the button) rotates 45°, keeping the focus ring square to the screen.
Make it yours
- Wider arc: increase the radius (140) in the formula and recompute each
bottom-[…] right-[…]pair. - Sixth item: add an anchor at θ ≈ 95° with
group-has-checked:delay-[280ms]. - Square FAB: replace
rounded-fullwithrounded-2xl. - Keep the page interactive: delete the scrim label; close via the FAB only.
Gotchas — read before shipping
- Positions are absolute to the phone shell, not the FAB — move the FAB and every item must move with it.
invisibleon closed items is what stops them intercepting taps on the page underneath.- Spring easing overshoots scale past 1 — give items breathing room from the screen edge, or they clip under
overflow-hidden.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Spring cubic-bezier() values above 1 are universally supported; the floor is Tailwind v4.