02 / 22
All 22 in 22 Tailwind Dropdown Menus
- 01Tailwind Slide-Down Fade Dropdown Menu
- 02Tailwind Clip-Path Curtain Reveal Dropdown
- 03Tailwind 3D Perspective Flip Dropdown
- 04Tailwind Elastic Bounce Dropdown Menu
- 05Tailwind Glassmorphism Float Panel Dropdown
- 06Tailwind Stagger Children Reveal Dropdown
- 07Tailwind Mega Menu Grid Dropdown
- 08Tailwind Underline Nav Fade Panel Dropdown
- 09Tailwind Details Summary Native Dropdown
- 10Tailwind Checkbox Hack Mobile Nav Dropdown
- 11Tailwind Nested Multi-Level Dropdown
- 12Tailwind Icon Sidebar Flyout Dropdown
- 13Tailwind Split-Screen Mega Menu Dropdown
- 14Tailwind Segmented Pill Nav Dropdown
- 15Tailwind Color Swatch Picker Dropdown
- 16Tailwind Right-Click Context Menu Dropdown
- 17Tailwind Keyboard Accessible ARIA Dropdown
- 18Tailwind Stagger Blur Entrance Dropdown
- 19Tailwind Command Palette Search Dropdown
- 20Tailwind Autocomplete Suggestion Dropdown
- 21Tailwind Tab Panel Dropdown
- 22Tailwind Custom Animated Select Dropdown
Tailwind Clip-Path Curtain Reveal Dropdown
A curtain that falls open: the panel is always full height, and a clip-path polygon animates from a zero-height strip at its top edge to the full rectangle. Both polygons live on the panel as arbitrary utilities, which is the whole argument for the port — a mismatched pair of point counts is the classic bug in this pattern, and here the pair is one line apart.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tdd-02 w-full min-h-svh grid justify-center content-start bg-linear-[160deg,var(--color-tdd02-bg1),var(--color-tdd02-bg2)] font-tdd02-sans text-tdd02-ink px-5 py-8" aria-label="Clip-path curtain reveal dropdown demo">
<nav class="relative z-10 flex w-[min(720px,92vw)] items-center gap-8 rounded-xl border-b-2 border-tdd02-edge bg-white px-7 py-3.5 shadow-[0_2px_16px_oklch(0_0_0/0.06)]" aria-label="Primary">
<a href="#home" class="mr-auto text-lg font-bold tracking-[-0.5px] text-tdd02-acc no-underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Vertex</a>
<div class="flex gap-1">
<div class="group relative after:absolute after:inset-x-0 after:top-full after:h-2.5 after:content-['']">
<button type="button" class="cursor-pointer rounded-lg border-0 bg-transparent px-3.5 py-2 font-tdd02-sans text-sm font-medium text-tdd02-ink transition-colors duration-150 group-hover:bg-tdd02-tint group-hover:text-tdd02-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Company ▾</button>
<div class="pointer-events-none absolute top-[calc(100%+10px)] left-1/2 min-w-55 -translate-x-1/2 overflow-hidden rounded-xl border border-tdd02-edge bg-white opacity-0 shadow-[0_16px_48px_oklch(0_0_0/0.12)] [clip-path:polygon(0_0,100%_0,100%_0,0_0)] transition-[clip-path,opacity] duration-400 ease-tdd02 group-hover:pointer-events-auto group-hover:opacity-100 group-hover:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-focus-within:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] motion-reduce:[clip-path:none] motion-reduce:duration-150">
<div class="grid grid-cols-2 gap-1 p-2">
<a href="#about" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🏗</span>About Us</a>
<a href="#careers" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">👥</span>Careers</a>
<a href="#press" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📰</span>Press</a>
<a href="#locations" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📍</span>Locations</a>
</div>
</div>
</div>
<div class="group relative after:absolute after:inset-x-0 after:top-full after:h-2.5 after:content-['']">
<button type="button" class="cursor-pointer rounded-lg border-0 bg-transparent px-3.5 py-2 font-tdd02-sans text-sm font-medium text-tdd02-ink transition-colors duration-150 group-hover:bg-tdd02-tint group-hover:text-tdd02-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Platform ▾</button>
<div class="pointer-events-none absolute top-[calc(100%+10px)] left-1/2 min-w-55 -translate-x-1/2 overflow-hidden rounded-xl border border-tdd02-edge bg-white opacity-0 shadow-[0_16px_48px_oklch(0_0_0/0.12)] [clip-path:polygon(0_0,100%_0,100%_0,0_0)] transition-[clip-path,opacity] duration-400 ease-tdd02 group-hover:pointer-events-auto group-hover:opacity-100 group-hover:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-focus-within:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] motion-reduce:[clip-path:none] motion-reduce:duration-150">
<div class="grid grid-cols-2 gap-1 p-2">
<a href="#analytics" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">⚡</span>Analytics</a>
<a href="#reporting" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📊</span>Reporting</a>
<a href="#integrations" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🛠</span>Integrations</a>
<a href="#security" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🔒</span>Security</a>
</div>
</div>
</div>
<div class="group relative after:absolute after:inset-x-0 after:top-full after:h-2.5 after:content-['']">
<button type="button" class="cursor-pointer rounded-lg border-0 bg-transparent px-3.5 py-2 font-tdd02-sans text-sm font-medium text-tdd02-ink transition-colors duration-150 group-hover:bg-tdd02-tint group-hover:text-tdd02-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Developers ▾</button>
<div class="pointer-events-none absolute top-[calc(100%+10px)] left-1/2 min-w-55 -translate-x-1/2 overflow-hidden rounded-xl border border-tdd02-edge bg-white opacity-0 shadow-[0_16px_48px_oklch(0_0_0/0.12)] [clip-path:polygon(0_0,100%_0,100%_0,0_0)] transition-[clip-path,opacity] duration-400 ease-tdd02 group-hover:pointer-events-auto group-hover:opacity-100 group-hover:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-focus-within:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] motion-reduce:[clip-path:none] motion-reduce:duration-150">
<div class="grid grid-cols-2 gap-1 p-2">
<a href="#api" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📄</span>API Docs</a>
<a href="#sdks" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🧰</span>SDKs</a>
<a href="#status" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🆕</span>Status</a>
</div>
</div>
</div>
</div>
</nav>
</section><section class="tdd-02 w-full min-h-svh grid justify-center content-start bg-linear-[160deg,var(--color-tdd02-bg1),var(--color-tdd02-bg2)] font-tdd02-sans text-tdd02-ink px-5 py-8" aria-label="Clip-path curtain reveal dropdown demo">
<nav class="relative z-10 flex w-[min(720px,92vw)] items-center gap-8 rounded-xl border-b-2 border-tdd02-edge bg-white px-7 py-3.5 shadow-[0_2px_16px_oklch(0_0_0/0.06)]" aria-label="Primary">
<a href="#home" class="mr-auto text-lg font-bold tracking-[-0.5px] text-tdd02-acc no-underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Vertex</a>
<div class="flex gap-1">
<div class="group relative after:absolute after:inset-x-0 after:top-full after:h-2.5 after:content-['']">
<button type="button" class="cursor-pointer rounded-lg border-0 bg-transparent px-3.5 py-2 font-tdd02-sans text-sm font-medium text-tdd02-ink transition-colors duration-150 group-hover:bg-tdd02-tint group-hover:text-tdd02-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Company ▾</button>
<div class="pointer-events-none absolute top-[calc(100%+10px)] left-1/2 min-w-55 -translate-x-1/2 overflow-hidden rounded-xl border border-tdd02-edge bg-white opacity-0 shadow-[0_16px_48px_oklch(0_0_0/0.12)] [clip-path:polygon(0_0,100%_0,100%_0,0_0)] transition-[clip-path,opacity] duration-400 ease-tdd02 group-hover:pointer-events-auto group-hover:opacity-100 group-hover:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-focus-within:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] motion-reduce:[clip-path:none] motion-reduce:duration-150">
<div class="grid grid-cols-2 gap-1 p-2">
<a href="#about" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🏗</span>About Us</a>
<a href="#careers" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">👥</span>Careers</a>
<a href="#press" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📰</span>Press</a>
<a href="#locations" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📍</span>Locations</a>
</div>
</div>
</div>
<div class="group relative after:absolute after:inset-x-0 after:top-full after:h-2.5 after:content-['']">
<button type="button" class="cursor-pointer rounded-lg border-0 bg-transparent px-3.5 py-2 font-tdd02-sans text-sm font-medium text-tdd02-ink transition-colors duration-150 group-hover:bg-tdd02-tint group-hover:text-tdd02-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Platform ▾</button>
<div class="pointer-events-none absolute top-[calc(100%+10px)] left-1/2 min-w-55 -translate-x-1/2 overflow-hidden rounded-xl border border-tdd02-edge bg-white opacity-0 shadow-[0_16px_48px_oklch(0_0_0/0.12)] [clip-path:polygon(0_0,100%_0,100%_0,0_0)] transition-[clip-path,opacity] duration-400 ease-tdd02 group-hover:pointer-events-auto group-hover:opacity-100 group-hover:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-focus-within:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] motion-reduce:[clip-path:none] motion-reduce:duration-150">
<div class="grid grid-cols-2 gap-1 p-2">
<a href="#analytics" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">⚡</span>Analytics</a>
<a href="#reporting" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📊</span>Reporting</a>
<a href="#integrations" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🛠</span>Integrations</a>
<a href="#security" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🔒</span>Security</a>
</div>
</div>
</div>
<div class="group relative after:absolute after:inset-x-0 after:top-full after:h-2.5 after:content-['']">
<button type="button" class="cursor-pointer rounded-lg border-0 bg-transparent px-3.5 py-2 font-tdd02-sans text-sm font-medium text-tdd02-ink transition-colors duration-150 group-hover:bg-tdd02-tint group-hover:text-tdd02-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Developers ▾</button>
<div class="pointer-events-none absolute top-[calc(100%+10px)] left-1/2 min-w-55 -translate-x-1/2 overflow-hidden rounded-xl border border-tdd02-edge bg-white opacity-0 shadow-[0_16px_48px_oklch(0_0_0/0.12)] [clip-path:polygon(0_0,100%_0,100%_0,0_0)] transition-[clip-path,opacity] duration-400 ease-tdd02 group-hover:pointer-events-auto group-hover:opacity-100 group-hover:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-focus-within:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] motion-reduce:[clip-path:none] motion-reduce:duration-150">
<div class="grid grid-cols-2 gap-1 p-2">
<a href="#api" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📄</span>API Docs</a>
<a href="#sdks" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🧰</span>SDKs</a>
<a href="#status" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🆕</span>Status</a>
</div>
</div>
</div>
</div>
</nav>
</section>@import "tailwindcss";
@theme {
--color-tdd02-bg1: #fff7ed;
--color-tdd02-bg1: oklch(0.97 0.02 70);
--color-tdd02-bg2: #fef3c7;
--color-tdd02-bg2: oklch(0.95 0.06 92);
--color-tdd02-ink: #1c1917;
--color-tdd02-ink: oklch(0.22 0.01 60);
--color-tdd02-edge: #e7e5e4;
--color-tdd02-edge: oklch(0.91 0.005 60);
--color-tdd02-tint: #fff7ed;
--color-tdd02-tint: oklch(0.97 0.02 70);
--color-tdd02-acc: #f97316;
--color-tdd02-acc: oklch(0.7 0.19 45);
--font-tdd02-sans: 'DM Sans', system-ui, sans-serif;
--ease-tdd02: cubic-bezier(0.16, 1, 0.3, 1);
}
.tdd-02 {
width: 100%;
min-height: 100svh;
}
.tdd-02 ::selection {
background: var(--color-tdd02-acc);
color: #fff;
}@import "tailwindcss";
@theme {
--color-tdd02-bg1: #fff7ed;
--color-tdd02-bg1: oklch(0.97 0.02 70);
--color-tdd02-bg2: #fef3c7;
--color-tdd02-bg2: oklch(0.95 0.06 92);
--color-tdd02-ink: #1c1917;
--color-tdd02-ink: oklch(0.22 0.01 60);
--color-tdd02-edge: #e7e5e4;
--color-tdd02-edge: oklch(0.91 0.005 60);
--color-tdd02-tint: #fff7ed;
--color-tdd02-tint: oklch(0.97 0.02 70);
--color-tdd02-acc: #f97316;
--color-tdd02-acc: oklch(0.7 0.19 45);
--font-tdd02-sans: 'DM Sans', system-ui, sans-serif;
--ease-tdd02: cubic-bezier(0.16, 1, 0.3, 1);
}
.tdd-02 {
width: 100%;
min-height: 100svh;
}
.tdd-02 ::selection {
background: var(--color-tdd02-acc);
color: #fff;
}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-tdd02-bg1: #fff7ed;
--color-tdd02-bg1: oklch(0.97 0.02 70);
--color-tdd02-bg2: #fef3c7;
--color-tdd02-bg2: oklch(0.95 0.06 92);
--color-tdd02-ink: #1c1917;
--color-tdd02-ink: oklch(0.22 0.01 60);
--color-tdd02-edge: #e7e5e4;
--color-tdd02-edge: oklch(0.91 0.005 60);
--color-tdd02-tint: #fff7ed;
--color-tdd02-tint: oklch(0.97 0.02 70);
--color-tdd02-acc: #f97316;
--color-tdd02-acc: oklch(0.7 0.19 45);
--font-tdd02-sans: 'DM Sans', system-ui, sans-serif;
--ease-tdd02: cubic-bezier(0.16, 1, 0.3, 1);
}
.tdd-02 {
width: 100%;
min-height: 100svh;
}
.tdd-02 ::selection {
background: var(--color-tdd02-acc);
color: #fff;
}@import "tailwindcss";
@theme {
--color-tdd02-bg1: #fff7ed;
--color-tdd02-bg1: oklch(0.97 0.02 70);
--color-tdd02-bg2: #fef3c7;
--color-tdd02-bg2: oklch(0.95 0.06 92);
--color-tdd02-ink: #1c1917;
--color-tdd02-ink: oklch(0.22 0.01 60);
--color-tdd02-edge: #e7e5e4;
--color-tdd02-edge: oklch(0.91 0.005 60);
--color-tdd02-tint: #fff7ed;
--color-tdd02-tint: oklch(0.97 0.02 70);
--color-tdd02-acc: #f97316;
--color-tdd02-acc: oklch(0.7 0.19 45);
--font-tdd02-sans: 'DM Sans', system-ui, sans-serif;
--ease-tdd02: cubic-bezier(0.16, 1, 0.3, 1);
}
.tdd-02 {
width: 100%;
min-height: 100svh;
}
.tdd-02 ::selection {
background: var(--color-tdd02-acc);
color: #fff;
}<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=DM+Sans:wght@400;500;600&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=DM+Sans:wght@400;500;600&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The two clip-paths are the entire port: one rule pair in CSS becomes one class list, and the point-count contract between them is enforceable by reading.
--ease-tdd02is a token, not an arbitrary value, precisely because a curve IS a design-scale value — it earns a utility.grid-cols-2plusgap-1deletes the demo's.gridrule outright.motion-reduce:[clip-path:none]is a better fallback than disabling the transition: with no clip at all the panel simply appears.
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 Clip-Path Curtain Reveal Dropdown
Source: https://codefronts.com/navigation/tailwind-dropdown-menus/tailwind-clip-path-curtain-reveal-dropdown/
A curtain that falls open: the panel is always full height, and a clip-path polygon animates from a zero-height strip at its top edge to the full rectangle. Both polygons live on the panel as arbitrary utilities, which is the whole argument for the port — a mismatched pair of point counts is the classic bug in this pattern, and here the pair is one line apart.
## HTML
```html
<section class="tdd-02 w-full min-h-svh grid justify-center content-start bg-linear-[160deg,var(--color-tdd02-bg1),var(--color-tdd02-bg2)] font-tdd02-sans text-tdd02-ink px-5 py-8" aria-label="Clip-path curtain reveal dropdown demo">
<nav class="relative z-10 flex w-[min(720px,92vw)] items-center gap-8 rounded-xl border-b-2 border-tdd02-edge bg-white px-7 py-3.5 shadow-[0_2px_16px_oklch(0_0_0/0.06)]" aria-label="Primary">
<a href="#home" class="mr-auto text-lg font-bold tracking-[-0.5px] text-tdd02-acc no-underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Vertex</a>
<div class="flex gap-1">
<div class="group relative after:absolute after:inset-x-0 after:top-full after:h-2.5 after:content-['']">
<button type="button" class="cursor-pointer rounded-lg border-0 bg-transparent px-3.5 py-2 font-tdd02-sans text-sm font-medium text-tdd02-ink transition-colors duration-150 group-hover:bg-tdd02-tint group-hover:text-tdd02-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Company ▾</button>
<div class="pointer-events-none absolute top-[calc(100%+10px)] left-1/2 min-w-55 -translate-x-1/2 overflow-hidden rounded-xl border border-tdd02-edge bg-white opacity-0 shadow-[0_16px_48px_oklch(0_0_0/0.12)] [clip-path:polygon(0_0,100%_0,100%_0,0_0)] transition-[clip-path,opacity] duration-400 ease-tdd02 group-hover:pointer-events-auto group-hover:opacity-100 group-hover:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-focus-within:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] motion-reduce:[clip-path:none] motion-reduce:duration-150">
<div class="grid grid-cols-2 gap-1 p-2">
<a href="#about" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🏗</span>About Us</a>
<a href="#careers" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">👥</span>Careers</a>
<a href="#press" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📰</span>Press</a>
<a href="#locations" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📍</span>Locations</a>
</div>
</div>
</div>
<div class="group relative after:absolute after:inset-x-0 after:top-full after:h-2.5 after:content-['']">
<button type="button" class="cursor-pointer rounded-lg border-0 bg-transparent px-3.5 py-2 font-tdd02-sans text-sm font-medium text-tdd02-ink transition-colors duration-150 group-hover:bg-tdd02-tint group-hover:text-tdd02-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Platform ▾</button>
<div class="pointer-events-none absolute top-[calc(100%+10px)] left-1/2 min-w-55 -translate-x-1/2 overflow-hidden rounded-xl border border-tdd02-edge bg-white opacity-0 shadow-[0_16px_48px_oklch(0_0_0/0.12)] [clip-path:polygon(0_0,100%_0,100%_0,0_0)] transition-[clip-path,opacity] duration-400 ease-tdd02 group-hover:pointer-events-auto group-hover:opacity-100 group-hover:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-focus-within:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] motion-reduce:[clip-path:none] motion-reduce:duration-150">
<div class="grid grid-cols-2 gap-1 p-2">
<a href="#analytics" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">⚡</span>Analytics</a>
<a href="#reporting" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📊</span>Reporting</a>
<a href="#integrations" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🛠</span>Integrations</a>
<a href="#security" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🔒</span>Security</a>
</div>
</div>
</div>
<div class="group relative after:absolute after:inset-x-0 after:top-full after:h-2.5 after:content-['']">
<button type="button" class="cursor-pointer rounded-lg border-0 bg-transparent px-3.5 py-2 font-tdd02-sans text-sm font-medium text-tdd02-ink transition-colors duration-150 group-hover:bg-tdd02-tint group-hover:text-tdd02-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Developers ▾</button>
<div class="pointer-events-none absolute top-[calc(100%+10px)] left-1/2 min-w-55 -translate-x-1/2 overflow-hidden rounded-xl border border-tdd02-edge bg-white opacity-0 shadow-[0_16px_48px_oklch(0_0_0/0.12)] [clip-path:polygon(0_0,100%_0,100%_0,0_0)] transition-[clip-path,opacity] duration-400 ease-tdd02 group-hover:pointer-events-auto group-hover:opacity-100 group-hover:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-focus-within:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] motion-reduce:[clip-path:none] motion-reduce:duration-150">
<div class="grid grid-cols-2 gap-1 p-2">
<a href="#api" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📄</span>API Docs</a>
<a href="#sdks" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🧰</span>SDKs</a>
<a href="#status" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🆕</span>Status</a>
</div>
</div>
</div>
</div>
</nav>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tdd02-bg1: #fff7ed;
--color-tdd02-bg1: oklch(0.97 0.02 70);
--color-tdd02-bg2: #fef3c7;
--color-tdd02-bg2: oklch(0.95 0.06 92);
--color-tdd02-ink: #1c1917;
--color-tdd02-ink: oklch(0.22 0.01 60);
--color-tdd02-edge: #e7e5e4;
--color-tdd02-edge: oklch(0.91 0.005 60);
--color-tdd02-tint: #fff7ed;
--color-tdd02-tint: oklch(0.97 0.02 70);
--color-tdd02-acc: #f97316;
--color-tdd02-acc: oklch(0.7 0.19 45);
--font-tdd02-sans: 'DM Sans', system-ui, sans-serif;
--ease-tdd02: cubic-bezier(0.16, 1, 0.3, 1);
}
.tdd-02 {
width: 100%;
min-height: 100svh;
}
.tdd-02 ::selection {
background: var(--color-tdd02-acc);
color: #fff;
}
```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 Clip-Path Curtain Reveal Dropdown
Source: https://codefronts.com/navigation/tailwind-dropdown-menus/tailwind-clip-path-curtain-reveal-dropdown/
A curtain that falls open: the panel is always full height, and a clip-path polygon animates from a zero-height strip at its top edge to the full rectangle. Both polygons live on the panel as arbitrary utilities, which is the whole argument for the port — a mismatched pair of point counts is the classic bug in this pattern, and here the pair is one line apart.
## HTML
```html
<section class="tdd-02 w-full min-h-svh grid justify-center content-start bg-linear-[160deg,var(--color-tdd02-bg1),var(--color-tdd02-bg2)] font-tdd02-sans text-tdd02-ink px-5 py-8" aria-label="Clip-path curtain reveal dropdown demo">
<nav class="relative z-10 flex w-[min(720px,92vw)] items-center gap-8 rounded-xl border-b-2 border-tdd02-edge bg-white px-7 py-3.5 shadow-[0_2px_16px_oklch(0_0_0/0.06)]" aria-label="Primary">
<a href="#home" class="mr-auto text-lg font-bold tracking-[-0.5px] text-tdd02-acc no-underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Vertex</a>
<div class="flex gap-1">
<div class="group relative after:absolute after:inset-x-0 after:top-full after:h-2.5 after:content-['']">
<button type="button" class="cursor-pointer rounded-lg border-0 bg-transparent px-3.5 py-2 font-tdd02-sans text-sm font-medium text-tdd02-ink transition-colors duration-150 group-hover:bg-tdd02-tint group-hover:text-tdd02-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Company ▾</button>
<div class="pointer-events-none absolute top-[calc(100%+10px)] left-1/2 min-w-55 -translate-x-1/2 overflow-hidden rounded-xl border border-tdd02-edge bg-white opacity-0 shadow-[0_16px_48px_oklch(0_0_0/0.12)] [clip-path:polygon(0_0,100%_0,100%_0,0_0)] transition-[clip-path,opacity] duration-400 ease-tdd02 group-hover:pointer-events-auto group-hover:opacity-100 group-hover:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-focus-within:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] motion-reduce:[clip-path:none] motion-reduce:duration-150">
<div class="grid grid-cols-2 gap-1 p-2">
<a href="#about" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🏗</span>About Us</a>
<a href="#careers" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">👥</span>Careers</a>
<a href="#press" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📰</span>Press</a>
<a href="#locations" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📍</span>Locations</a>
</div>
</div>
</div>
<div class="group relative after:absolute after:inset-x-0 after:top-full after:h-2.5 after:content-['']">
<button type="button" class="cursor-pointer rounded-lg border-0 bg-transparent px-3.5 py-2 font-tdd02-sans text-sm font-medium text-tdd02-ink transition-colors duration-150 group-hover:bg-tdd02-tint group-hover:text-tdd02-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Platform ▾</button>
<div class="pointer-events-none absolute top-[calc(100%+10px)] left-1/2 min-w-55 -translate-x-1/2 overflow-hidden rounded-xl border border-tdd02-edge bg-white opacity-0 shadow-[0_16px_48px_oklch(0_0_0/0.12)] [clip-path:polygon(0_0,100%_0,100%_0,0_0)] transition-[clip-path,opacity] duration-400 ease-tdd02 group-hover:pointer-events-auto group-hover:opacity-100 group-hover:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-focus-within:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] motion-reduce:[clip-path:none] motion-reduce:duration-150">
<div class="grid grid-cols-2 gap-1 p-2">
<a href="#analytics" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">⚡</span>Analytics</a>
<a href="#reporting" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📊</span>Reporting</a>
<a href="#integrations" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🛠</span>Integrations</a>
<a href="#security" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🔒</span>Security</a>
</div>
</div>
</div>
<div class="group relative after:absolute after:inset-x-0 after:top-full after:h-2.5 after:content-['']">
<button type="button" class="cursor-pointer rounded-lg border-0 bg-transparent px-3.5 py-2 font-tdd02-sans text-sm font-medium text-tdd02-ink transition-colors duration-150 group-hover:bg-tdd02-tint group-hover:text-tdd02-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tdd02-acc">Developers ▾</button>
<div class="pointer-events-none absolute top-[calc(100%+10px)] left-1/2 min-w-55 -translate-x-1/2 overflow-hidden rounded-xl border border-tdd02-edge bg-white opacity-0 shadow-[0_16px_48px_oklch(0_0_0/0.12)] [clip-path:polygon(0_0,100%_0,100%_0,0_0)] transition-[clip-path,opacity] duration-400 ease-tdd02 group-hover:pointer-events-auto group-hover:opacity-100 group-hover:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-focus-within:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)] motion-reduce:[clip-path:none] motion-reduce:duration-150">
<div class="grid grid-cols-2 gap-1 p-2">
<a href="#api" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">📄</span>API Docs</a>
<a href="#sdks" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🧰</span>SDKs</a>
<a href="#status" class="flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-[13.5px] font-medium text-tdd02-ink no-underline transition-colors duration-150 hover:bg-tdd02-tint hover:text-tdd02-acc focus-visible:bg-tdd02-tint focus-visible:outline-none"><span class="text-base leading-none" aria-hidden="true">🆕</span>Status</a>
</div>
</div>
</div>
</div>
</nav>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tdd02-bg1: #fff7ed;
--color-tdd02-bg1: oklch(0.97 0.02 70);
--color-tdd02-bg2: #fef3c7;
--color-tdd02-bg2: oklch(0.95 0.06 92);
--color-tdd02-ink: #1c1917;
--color-tdd02-ink: oklch(0.22 0.01 60);
--color-tdd02-edge: #e7e5e4;
--color-tdd02-edge: oklch(0.91 0.005 60);
--color-tdd02-tint: #fff7ed;
--color-tdd02-tint: oklch(0.97 0.02 70);
--color-tdd02-acc: #f97316;
--color-tdd02-acc: oklch(0.7 0.19 45);
--font-tdd02-sans: 'DM Sans', system-ui, sans-serif;
--ease-tdd02: cubic-bezier(0.16, 1, 0.3, 1);
}
.tdd-02 {
width: 100%;
min-height: 100svh;
}
.tdd-02 ::selection {
background: var(--color-tdd02-acc);
color: #fff;
}
```How this works
Two polygons, same element. The closed shape is a degenerate rectangle at the top edge; the open shape is the full box. Because clip-path morphs point-for-point, both must declare four points — and in utilities you can see at a glance that they do.
class="[clip-path:polygon(0_0,100%_0,100%_0,0_0)]
group-hover:[clip-path:polygon(0_0,100%_0,100%_100%,0_100%)]"Composited, not laid out. clip-path runs on the compositor like transform, so the wipe holds 60fps and never reflows the nav.
Spaces are the enemy. An arbitrary value cannot contain a literal space, so every gap inside the polygon is an underscore. Tailwind converts them back when it emits the declaration.
Hover and focus both drive it, and the closed panel keeps pointer-events-none so the clipped-away area cannot intercept the cursor.
Make it yours
- Angled wipe: make the open shape
polygon(0_0,100%_0,100%_100%,0_80%)for a diagonal curtain. - Curve:
--ease-tdd02in@theme; a springycubic-bezier(.3,1.3,.4,1)reads well because a clip simply grows past its box. - Simpler shape:
[clip-path:inset(0_0_100%_0_round_12px)]keeps the rounded corners honest in Safari. - Duration: the
duration-400on the panel; under 250ms the curtain metaphor stops reading.
Gotchas — read before shipping
- Both polygons must declare the same number of points, or the browser hard-snaps instead of morphing.
- A clipped panel clips its children's overflow too — keep the drop shadow on the panel, never on something inside it.
- Safari combines
border-radiusand polygon clips badly; preferinset(... round 12px)if you need both. - Arbitrary values are matched statically. A clip-path assembled at runtime from a variable emits no CSS at all.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Animatable basic-shape clip-path has been Baseline since 2021; the floor quoted is Tailwind v4's generated sheet.