Pure TailwindMIT licensed

Tailwind CSS Full-Screen Overlay Menu

A cinematic, portfolio-grade overlay: the menu wipes down with a clip-path reveal, giant links rise out of masks one after another, and hovering one link dims the rest. A side column carries contact details and socials. Everything replays on every open because it is built from transitions. Zero JavaScript.

Live Demo
Plain CSSTailwind v4
Try it

Nucleo: 44,000+ SVG icons in five families · All Icons Bundle $149

Nucleo · Affiliate link

Get the Nucleo bundle

The code

<div class="tnv-05 group/root min-h-svh w-full bg-tnv05-bg font-tnv05-sans text-tnv05-ink antialiased selection:bg-tnv05-acc selection:text-white">
  <input type="checkbox" id="tnv05-toggle" class="sr-only" aria-controls="tnv05-overlay">
  <header class="fixed inset-x-0 top-0 z-50 flex items-center justify-between px-6 py-6 sm:px-10">
    <a href="#" class="text-2xl font-extrabold tracking-[-0.04em]">Vol<span class="text-tnv05-acc">ta</span></a>
    <label for="tnv05-toggle" class="group/btn flex h-11 cursor-pointer items-center gap-3 rounded-full border border-white/10 bg-white/[0.06] pr-2 pl-4 text-xs font-bold tracking-[0.14em] uppercase backdrop-blur-md transition-colors select-none hover:bg-white/10 group-has-[#tnv05-toggle:focus-visible]/root:ring-2 group-has-[#tnv05-toggle:focus-visible]/root:ring-tnv05-acc">
      <span class="grid"><span class="col-start-1 row-start-1 transition-opacity group-has-checked/root:opacity-0">Menu</span><span class="col-start-1 row-start-1 opacity-0 transition-opacity group-has-checked/root:opacity-100">Close</span></span>
      <span class="grid size-8 place-items-center rounded-full bg-tnv05-ink text-tnv05-bg"><span class="grid gap-1"><span class="block h-0.5 w-3.5 rounded-full bg-current transition-[translate,rotate] duration-300 group-has-checked/root:translate-y-[3px] group-has-checked/root:rotate-45"></span><span class="block h-0.5 w-3.5 rounded-full bg-current transition-[translate,rotate] duration-300 group-has-checked/root:-translate-y-[3px] group-has-checked/root:-rotate-45"></span></span></span>
    </label>
  </header>
  <div id="tnv05-overlay" role="dialog" aria-label="Site menu" class="invisible fixed inset-0 z-40 grid overflow-y-auto bg-tnv05-bg bg-[radial-gradient(50%_50%_at_90%_100%,var(--color-tnv05-glow),transparent)] [clip-path:inset(0_0_100%_0)] transition-[clip-path,visibility] duration-[650ms] ease-[cubic-bezier(.77,0,.175,1)] group-has-checked/root:visible group-has-checked/root:[clip-path:inset(0)] motion-reduce:transition-none">
    <div class="mx-auto grid w-full max-w-6xl content-center gap-12 px-6 pt-28 pb-12 sm:px-10 lg:grid-cols-[1fr_16rem] lg:items-end">
      <nav aria-label="Primary">
        <ul class="group/list">
          <li class="overflow-hidden"><a href="#" style="--i:1" class="group/l inline-flex translate-y-full items-start gap-4 py-1 text-[clamp(2.75rem,8vw,5.75rem)] leading-[1.02] font-extrabold tracking-[-0.045em] text-white outline-none transition-[translate,color] delay-[calc(var(--i)*70ms_+_220ms)] duration-700 ease-[cubic-bezier(.23,1,.32,1)] group-hover/list:text-white/25 group-has-checked/root:translate-y-0 hover:text-white! focus-visible:text-tnv05-acc! motion-reduce:transition-none"><span class="mt-[0.6em] font-tnv05-mono text-xs font-medium tracking-wider text-tnv05-acc opacity-0 transition-opacity group-hover/l:opacity-100">01</span>Work</a></li>
          <li class="overflow-hidden"><a href="#" style="--i:2" class="group/l inline-flex translate-y-full items-start gap-4 py-1 text-[clamp(2.75rem,8vw,5.75rem)] leading-[1.02] font-extrabold tracking-[-0.045em] text-white outline-none transition-[translate,color] delay-[calc(var(--i)*70ms_+_220ms)] duration-700 ease-[cubic-bezier(.23,1,.32,1)] group-hover/list:text-white/25 group-has-checked/root:translate-y-0 hover:text-white! focus-visible:text-tnv05-acc! motion-reduce:transition-none"><span class="mt-[0.6em] font-tnv05-mono text-xs font-medium tracking-wider text-tnv05-acc opacity-0 transition-opacity group-hover/l:opacity-100">02</span>Studio</a></li>
          <li class="overflow-hidden"><a href="#" style="--i:3" class="group/l inline-flex translate-y-full items-start gap-4 py-1 text-[clamp(2.75rem,8vw,5.75rem)] leading-[1.02] font-extrabold tracking-[-0.045em] text-white outline-none transition-[translate,color] delay-[calc(var(--i)*70ms_+_220ms)] duration-700 ease-[cubic-bezier(.23,1,.32,1)] group-hover/list:text-white/25 group-has-checked/root:translate-y-0 hover:text-white! focus-visible:text-tnv05-acc! motion-reduce:transition-none"><span class="mt-[0.6em] font-tnv05-mono text-xs font-medium tracking-wider text-tnv05-acc opacity-0 transition-opacity group-hover/l:opacity-100">03</span>Services</a></li>
          <li class="overflow-hidden"><a href="#" style="--i:4" class="group/l inline-flex translate-y-full items-start gap-4 py-1 text-[clamp(2.75rem,8vw,5.75rem)] leading-[1.02] font-extrabold tracking-[-0.045em] text-white outline-none transition-[translate,color] delay-[calc(var(--i)*70ms_+_220ms)] duration-700 ease-[cubic-bezier(.23,1,.32,1)] group-hover/list:text-white/25 group-has-checked/root:translate-y-0 hover:text-white! focus-visible:text-tnv05-acc! motion-reduce:transition-none"><span class="mt-[0.6em] font-tnv05-mono text-xs font-medium tracking-wider text-tnv05-acc opacity-0 transition-opacity group-hover/l:opacity-100">04</span>Journal</a></li>
          <li class="overflow-hidden"><a href="#" style="--i:5" class="group/l inline-flex translate-y-full items-start gap-4 py-1 text-[clamp(2.75rem,8vw,5.75rem)] leading-[1.02] font-extrabold tracking-[-0.045em] text-white outline-none transition-[translate,color] delay-[calc(var(--i)*70ms_+_220ms)] duration-700 ease-[cubic-bezier(.23,1,.32,1)] group-hover/list:text-white/25 group-has-checked/root:translate-y-0 hover:text-white! focus-visible:text-tnv05-acc! motion-reduce:transition-none"><span class="mt-[0.6em] font-tnv05-mono text-xs font-medium tracking-wider text-tnv05-acc opacity-0 transition-opacity group-hover/l:opacity-100">05</span>Contact</a></li>
        </ul>
      </nav>
      <div class="grid translate-y-4 gap-6 border-t border-white/10 pt-6 text-sm opacity-0 transition-[translate,opacity] delay-[600ms] duration-700 group-has-checked/root:translate-y-0 group-has-checked/root:opacity-100 motion-reduce:transition-none lg:border-t-0 lg:border-l lg:pt-0 lg:pl-8">
        <div><p class="font-tnv05-mono text-[11px] tracking-wider text-tnv05-mut uppercase">New business</p><a href="#" class="mt-1 block font-semibold underline-offset-4 hover:underline">hello@volta.studio</a></div>
        <div class="flex flex-wrap gap-x-4 gap-y-2 font-semibold text-tnv05-mut [&_a]:transition-colors [&_a:hover]:text-white"><a href="#">Instagram</a><a href="#">Dribbble</a><a href="#">LinkedIn</a><a href="#">X</a></div>
        <a href="#" class="inline-flex min-h-12 w-fit items-center gap-2 rounded-full bg-tnv05-acc px-6 font-bold text-white shadow-[0_10px_40px_-10px_var(--color-tnv05-acc)] transition hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white">Start a project<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
      </div>
    </div>
  </div>
  <main class="grid min-h-svh place-items-center px-6 py-28 text-center [&_code]:rounded [&_code]:bg-white/[0.08] [&_code]:px-1.5 [&_code]:font-tnv05-mono [&_code]:text-[0.8em]">
    <div>
      <h1 class="text-[clamp(3rem,10vw,7rem)] leading-[0.95] font-extrabold tracking-[-0.055em]">Design <span class="bg-linear-135 from-tnv05-acc to-tnv05-acc2 bg-clip-text text-transparent">beyond</span><br>the ordinary</h1>
      <p class="mx-auto mt-6 max-w-md text-[17px]/[1.65] text-tnv05-mut text-pretty">Open the menu. It wipes in with <code>clip-path</code>, the links rise from masks on a stagger, and hovering one dims the rest. Close and reopen: it all replays.</p>
    </div>
  </main>
</div>
@import "tailwindcss";

@theme {
  --color-tnv05-bg: #09090b;
  --color-tnv05-bg: oklch(0.141 0.005 286);
  --color-tnv05-glow: #d946ef2e;
  --color-tnv05-glow: oklch(0.667 0.295 322 / 0.18);
  --color-tnv05-ink: #fafafa;
  --color-tnv05-ink: oklch(0.985 0 0);
  --color-tnv05-mut: #a1a1aa;
  --color-tnv05-mut: oklch(0.705 0.015 286);
  --color-tnv05-acc: #d946ef;
  --color-tnv05-acc: oklch(0.667 0.295 322);
  --color-tnv05-acc2: #e879f9;
  --color-tnv05-acc2: oklch(0.74 0.238 322);
  --font-tnv05-sans: 'Syne', system-ui, sans-serif;
  --font-tnv05-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tnv-05 {
  width: 100%;
  min-height: 100svh;
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<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.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tnv05-bg: #09090b;
  --color-tnv05-bg: oklch(0.141 0.005 286);
  --color-tnv05-glow: #d946ef2e;
  --color-tnv05-glow: oklch(0.667 0.295 322 / 0.18);
  --color-tnv05-ink: #fafafa;
  --color-tnv05-ink: oklch(0.985 0 0);
  --color-tnv05-mut: #a1a1aa;
  --color-tnv05-mut: oklch(0.705 0.015 286);
  --color-tnv05-acc: #d946ef;
  --color-tnv05-acc: oklch(0.667 0.295 322);
  --color-tnv05-acc2: #e879f9;
  --color-tnv05-acc2: oklch(0.74 0.238 322);
  --font-tnv05-sans: 'Syne', system-ui, sans-serif;
  --font-tnv05-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tnv-05 {
  width: 100%;
  min-height: 100svh;
}
3Fonts used by this demooptional — skip if you have your own type stack
<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=Syne:wght@500..800&family=JetBrains+Mono:wght@400;500&display=swap">

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • The overlay's translateY(-100%) slab became a clip-path wipe in an arbitrary property, toggled with group-has-checked/root:[clip-path:inset(0)].
  • The decorative ::before glow became a radial-gradient background utility reading a theme token.
  • Fix from the CSS original: its own gotcha noted the stagger played only once. Built from delayed transitions, it now replays on every open, and the side column enters last.
  • Accessibility upgrade: links were rgba(255,255,255,.15) at rest (1.4:1, effectively invisible); they now rest at full white and only dim while a sibling is hovered. The checkbox is keyboard-reachable and the button label switches Menu/Close.
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
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 CSS Full-Screen Overlay Menu
Source: https://codefronts.com/navigation/tailwind-css-navigation-menus/tailwind-css-full-screen-overlay-menu/

A cinematic, portfolio-grade overlay: the menu wipes down with a clip-path reveal, giant links rise out of masks one after another, and hovering one link dims the rest. A side column carries contact details and socials. Everything replays on every open because it is built from transitions. Zero JavaScript.
## HTML
```html
<div class="tnv-05 group/root min-h-svh w-full bg-tnv05-bg font-tnv05-sans text-tnv05-ink antialiased selection:bg-tnv05-acc selection:text-white">
  <input type="checkbox" id="tnv05-toggle" class="sr-only" aria-controls="tnv05-overlay">
  <header class="fixed inset-x-0 top-0 z-50 flex items-center justify-between px-6 py-6 sm:px-10">
    <a href="#" class="text-2xl font-extrabold tracking-[-0.04em]">Vol<span class="text-tnv05-acc">ta</span></a>
    <label for="tnv05-toggle" class="group/btn flex h-11 cursor-pointer items-center gap-3 rounded-full border border-white/10 bg-white/[0.06] pr-2 pl-4 text-xs font-bold tracking-[0.14em] uppercase backdrop-blur-md transition-colors select-none hover:bg-white/10 group-has-[#tnv05-toggle:focus-visible]/root:ring-2 group-has-[#tnv05-toggle:focus-visible]/root:ring-tnv05-acc">
      <span class="grid"><span class="col-start-1 row-start-1 transition-opacity group-has-checked/root:opacity-0">Menu</span><span class="col-start-1 row-start-1 opacity-0 transition-opacity group-has-checked/root:opacity-100">Close</span></span>
      <span class="grid size-8 place-items-center rounded-full bg-tnv05-ink text-tnv05-bg"><span class="grid gap-1"><span class="block h-0.5 w-3.5 rounded-full bg-current transition-[translate,rotate] duration-300 group-has-checked/root:translate-y-[3px] group-has-checked/root:rotate-45"></span><span class="block h-0.5 w-3.5 rounded-full bg-current transition-[translate,rotate] duration-300 group-has-checked/root:-translate-y-[3px] group-has-checked/root:-rotate-45"></span></span></span>
    </label>
  </header>
  <div id="tnv05-overlay" role="dialog" aria-label="Site menu" class="invisible fixed inset-0 z-40 grid overflow-y-auto bg-tnv05-bg bg-[radial-gradient(50%_50%_at_90%_100%,var(--color-tnv05-glow),transparent)] [clip-path:inset(0_0_100%_0)] transition-[clip-path,visibility] duration-[650ms] ease-[cubic-bezier(.77,0,.175,1)] group-has-checked/root:visible group-has-checked/root:[clip-path:inset(0)] motion-reduce:transition-none">
    <div class="mx-auto grid w-full max-w-6xl content-center gap-12 px-6 pt-28 pb-12 sm:px-10 lg:grid-cols-[1fr_16rem] lg:items-end">
      <nav aria-label="Primary">
        <ul class="group/list">
          <li class="overflow-hidden"><a href="#" style="--i:1" class="group/l inline-flex translate-y-full items-start gap-4 py-1 text-[clamp(2.75rem,8vw,5.75rem)] leading-[1.02] font-extrabold tracking-[-0.045em] text-white outline-none transition-[translate,color] delay-[calc(var(--i)*70ms_+_220ms)] duration-700 ease-[cubic-bezier(.23,1,.32,1)] group-hover/list:text-white/25 group-has-checked/root:translate-y-0 hover:text-white! focus-visible:text-tnv05-acc! motion-reduce:transition-none"><span class="mt-[0.6em] font-tnv05-mono text-xs font-medium tracking-wider text-tnv05-acc opacity-0 transition-opacity group-hover/l:opacity-100">01</span>Work</a></li>
          <li class="overflow-hidden"><a href="#" style="--i:2" class="group/l inline-flex translate-y-full items-start gap-4 py-1 text-[clamp(2.75rem,8vw,5.75rem)] leading-[1.02] font-extrabold tracking-[-0.045em] text-white outline-none transition-[translate,color] delay-[calc(var(--i)*70ms_+_220ms)] duration-700 ease-[cubic-bezier(.23,1,.32,1)] group-hover/list:text-white/25 group-has-checked/root:translate-y-0 hover:text-white! focus-visible:text-tnv05-acc! motion-reduce:transition-none"><span class="mt-[0.6em] font-tnv05-mono text-xs font-medium tracking-wider text-tnv05-acc opacity-0 transition-opacity group-hover/l:opacity-100">02</span>Studio</a></li>
          <li class="overflow-hidden"><a href="#" style="--i:3" class="group/l inline-flex translate-y-full items-start gap-4 py-1 text-[clamp(2.75rem,8vw,5.75rem)] leading-[1.02] font-extrabold tracking-[-0.045em] text-white outline-none transition-[translate,color] delay-[calc(var(--i)*70ms_+_220ms)] duration-700 ease-[cubic-bezier(.23,1,.32,1)] group-hover/list:text-white/25 group-has-checked/root:translate-y-0 hover:text-white! focus-visible:text-tnv05-acc! motion-reduce:transition-none"><span class="mt-[0.6em] font-tnv05-mono text-xs font-medium tracking-wider text-tnv05-acc opacity-0 transition-opacity group-hover/l:opacity-100">03</span>Services</a></li>
          <li class="overflow-hidden"><a href="#" style="--i:4" class="group/l inline-flex translate-y-full items-start gap-4 py-1 text-[clamp(2.75rem,8vw,5.75rem)] leading-[1.02] font-extrabold tracking-[-0.045em] text-white outline-none transition-[translate,color] delay-[calc(var(--i)*70ms_+_220ms)] duration-700 ease-[cubic-bezier(.23,1,.32,1)] group-hover/list:text-white/25 group-has-checked/root:translate-y-0 hover:text-white! focus-visible:text-tnv05-acc! motion-reduce:transition-none"><span class="mt-[0.6em] font-tnv05-mono text-xs font-medium tracking-wider text-tnv05-acc opacity-0 transition-opacity group-hover/l:opacity-100">04</span>Journal</a></li>
          <li class="overflow-hidden"><a href="#" style="--i:5" class="group/l inline-flex translate-y-full items-start gap-4 py-1 text-[clamp(2.75rem,8vw,5.75rem)] leading-[1.02] font-extrabold tracking-[-0.045em] text-white outline-none transition-[translate,color] delay-[calc(var(--i)*70ms_+_220ms)] duration-700 ease-[cubic-bezier(.23,1,.32,1)] group-hover/list:text-white/25 group-has-checked/root:translate-y-0 hover:text-white! focus-visible:text-tnv05-acc! motion-reduce:transition-none"><span class="mt-[0.6em] font-tnv05-mono text-xs font-medium tracking-wider text-tnv05-acc opacity-0 transition-opacity group-hover/l:opacity-100">05</span>Contact</a></li>
        </ul>
      </nav>
      <div class="grid translate-y-4 gap-6 border-t border-white/10 pt-6 text-sm opacity-0 transition-[translate,opacity] delay-[600ms] duration-700 group-has-checked/root:translate-y-0 group-has-checked/root:opacity-100 motion-reduce:transition-none lg:border-t-0 lg:border-l lg:pt-0 lg:pl-8">
        <div><p class="font-tnv05-mono text-[11px] tracking-wider text-tnv05-mut uppercase">New business</p><a href="#" class="mt-1 block font-semibold underline-offset-4 hover:underline">hello@volta.studio</a></div>
        <div class="flex flex-wrap gap-x-4 gap-y-2 font-semibold text-tnv05-mut [&_a]:transition-colors [&_a:hover]:text-white"><a href="#">Instagram</a><a href="#">Dribbble</a><a href="#">LinkedIn</a><a href="#">X</a></div>
        <a href="#" class="inline-flex min-h-12 w-fit items-center gap-2 rounded-full bg-tnv05-acc px-6 font-bold text-white shadow-[0_10px_40px_-10px_var(--color-tnv05-acc)] transition hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white">Start a project<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
      </div>
    </div>
  </div>
  <main class="grid min-h-svh place-items-center px-6 py-28 text-center [&_code]:rounded [&_code]:bg-white/[0.08] [&_code]:px-1.5 [&_code]:font-tnv05-mono [&_code]:text-[0.8em]">
    <div>
      <h1 class="text-[clamp(3rem,10vw,7rem)] leading-[0.95] font-extrabold tracking-[-0.055em]">Design <span class="bg-linear-135 from-tnv05-acc to-tnv05-acc2 bg-clip-text text-transparent">beyond</span><br>the ordinary</h1>
      <p class="mx-auto mt-6 max-w-md text-[17px]/[1.65] text-tnv05-mut text-pretty">Open the menu. It wipes in with <code>clip-path</code>, the links rise from masks on a stagger, and hovering one dims the rest. Close and reopen: it all replays.</p>
    </div>
  </main>
</div>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tnv05-bg: #09090b;
  --color-tnv05-bg: oklch(0.141 0.005 286);
  --color-tnv05-glow: #d946ef2e;
  --color-tnv05-glow: oklch(0.667 0.295 322 / 0.18);
  --color-tnv05-ink: #fafafa;
  --color-tnv05-ink: oklch(0.985 0 0);
  --color-tnv05-mut: #a1a1aa;
  --color-tnv05-mut: oklch(0.705 0.015 286);
  --color-tnv05-acc: #d946ef;
  --color-tnv05-acc: oklch(0.667 0.295 322);
  --color-tnv05-acc2: #e879f9;
  --color-tnv05-acc2: oklch(0.74 0.238 322);
  --font-tnv05-sans: 'Syne', system-ui, sans-serif;
  --font-tnv05-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tnv-05 {
  width: 100%;
  min-height: 100svh;
}
```

How this works

The stagger now replays. The CSS original's gotcha admitted its keyframe stagger played once and never again. Re-expressed as transitions keyed off group-has-checked/root:, every open re-runs it:

<li class="overflow-hidden">
  <a style="--i:2" class="translate-y-full
    delay-[calc(var(--i)*70ms_+_220ms)]
    group-has-checked/root:translate-y-0">Studio</a>

Spotlight hover uses two groups: the <ul> is group/list, so hovering anywhere in it fades all links to 25%, and the hovered link wins back full white with the important modifier.

Make it yours

  • Solid brand overlay: change bg-tnv05-bg to bg-tnv05-acc and the ink to black.
  • Wipe from the left: [clip-path:inset(0_100%_0_0)].
  • Smaller type: lower the clamp(2.75rem,8vw,5.75rem) range.

Gotchas — read before shipping

  • Fixed overlays lock nothing: add overflow-hidden to <body> with JS if the page behind should not scroll.
  • calc() inside an arbitrary value needs underscores around + to emit spaces.
  • Keep the hamburger above the overlay (z-50) or nobody can close it.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

clip-path: inset() transitions are universal in this range.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Arbitraryneeds bracket syntax

Search CodeFronts

Loading…