19 / 47
All 47 in 47 Tailwind CSS Toggles & Switches
- 01Tailwind iOS-Style Toggle Switch with appearance-none
- 02Tailwind Dark Mode Sun / Moon Theme Switcher
- 03Tailwind Neumorphic Soft-UI Pill Toggle
- 04Tailwind Gooey Liquid Morphing Switch with SVG Filter
- 05Tailwind Bouncy Elastic Physics Toggle (Overshoot Cubic-Bezier)
- 06Tailwind ON / OFF Text Switch with Labels Inside the Track
- 07Tailwind SaaS Pricing Toggle — Monthly / Annually Segmented Pill
- 08Tailwind Mechanical Keycap Toggles with Haptic Feedback
- 09Tailwind Waveform Mute Toggle with Animated EQ Bars
- 10Tailwind Timed Auto-Off Toggle with Conic Countdown Ring
- 11Tailwind Press-and-Hold to Confirm Toggle (Fingerprint Scan)
- 12Tailwind Split-Flap Departure Board Toggle (3D Flip)
- 13Tailwind Permission Toggle Group with :has() Live Status Badge
- 14Tailwind Material Design 3 Switch with State Layer
- 15Tailwind Skeuomorphic Wall Light Switch with Room Relight
- 16Tailwind Neon Cyberpunk Toggle with Clipped Corners
- 17Tailwind Brutalist Snap Toggle with Hard Offset Shadow
- 18Tailwind Day / Night Landscape Scene Switch
- 19Tailwind 3D Flip Card Toggle (rotateY Switch)
- 20Tailwind Sliding Pill Toggle with Label Inside the Thumb
- 21Tailwind Glassmorphism Frosted Toggle with backdrop-blur
- 22Tailwind Rotary Knob Toggle with Brushed-Metal Conic Gradient
- 23Tailwind iOS Settings List with Grouped Toggle Rows
- 24Tailwind Minimal Outline Toggle Drawn in currentColor
- 25Tailwind Squash-and-Stretch Pebble Toggle
- 26Tailwind Industrial Rocker I/O Power Switch
- 27Tailwind Accessible role=switch Toggle with forced-colors Support
- 28Tailwind Macro-Pad Toggle Grid with RGB Underglow
- 29Tailwind Radial VU Meter Mute Toggle
- 30Tailwind Segmented Pip Countdown Auto-Off Toggle
- 31Tailwind Slide-to-Confirm Toggle Rail (Drag or Arrow Keys)
- 32Tailwind Odometer Roll ON / OFF Toggle
- 33Tailwind Master Toggle with Indeterminate Tri-State
- 34Tailwind iOS Control Centre Tile Toggles
- 35Tailwind Material 3 Connected Icon Toggle Buttons
- 36Tailwind Two-Gang Wall Plate with Cumulative Room Light
- 37Tailwind Neon Toggle with Animated Conic Border Light
- 38Tailwind Brutalist Rubber-Stamp Toggle
- 39Tailwind Aurora Night Sky Toggle Switch
- 40Tailwind 3D Rotating Cube Toggle
- 41Tailwind Three-Position Off / Auto / On Selector
- 42Tailwind Liquid Glass Toggle with Specular Highlight
- 43Tailwind Three-Detent Rotary Selector Knob
- 44Tailwind Hardware Slide Switch with Knurled Grip
- 45Tailwind Battery Saver Toggle with Live Fill Meter
- 46Tailwind Morphing Sun-to-Moon Icon Toggle (SVG Stroke)
- 47Tailwind Guarded Kill Switch Under a Flip-Up Safety Cover
Tailwind 3D Flip Card Toggle (rotateY Switch)
A boolean as a physical object: the whole control rotates 180° to reveal its other face — muted "Paused" on the front, vivid "Active" with a live figure on the back. v4's first-class 3D utilities mean the entire flip is five classes.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="ttg-19 w-full min-h-svh flex flex-col items-center justify-center gap-7 px-5 py-14 bg-ttg19-bg font-ttg19-sans" aria-label="3D flip card toggle">
<input type="checkbox" id="ttg-19-sw" role="switch" aria-label="Campaign active" class="peer sr-only">
<label for="ttg-19-sw" aria-hidden="true" class="block cursor-pointer perspective-[900px] peer-checked:[&_.ttg19-card]:rotate-y-180 peer-focus-visible:outline-3 peer-focus-visible:outline-ttg19-focus peer-focus-visible:outline-offset-[5px] peer-focus-visible:rounded-[18px]">
<span class="ttg19-card relative block w-[230px] h-[130px] transform-3d transition-transform duration-[650ms] ease-[cubic-bezier(0.4,0.2,0.2,1.15)] motion-reduce:duration-150">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-1.5 rounded-2xl backface-hidden bg-linear-150 from-ttg19-frontthi to-ttg19-frontlo text-ttg19-frontink shadow-[0_18px_36px_-20px_oklch(0.3_0.03_265/0.55)]">
<b class="text-2xl font-extrabold tracking-[0.12em]">PAUSED</b>
<small class="text-[12.5px] opacity-80">Campaign is not spending</small>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-1.5 rounded-2xl backface-hidden rotate-y-180 bg-linear-150 from-ttg19-backhi to-ttg19-backlo text-white shadow-[0_18px_36px_-20px_oklch(0.3_0.08_160/0.55)]">
<b class="text-2xl font-extrabold tracking-[0.12em]">ACTIVE</b>
<small class="text-[12.5px] opacity-90">Ads are live · $184/day</small>
</span>
</span>
</label>
<p class="text-[12px] tracking-[0.12em] uppercase text-ttg19-mute">Click the card to flip state</p>
</section><section class="ttg-19 w-full min-h-svh flex flex-col items-center justify-center gap-7 px-5 py-14 bg-ttg19-bg font-ttg19-sans" aria-label="3D flip card toggle">
<input type="checkbox" id="ttg-19-sw" role="switch" aria-label="Campaign active" class="peer sr-only">
<label for="ttg-19-sw" aria-hidden="true" class="block cursor-pointer perspective-[900px] peer-checked:[&_.ttg19-card]:rotate-y-180 peer-focus-visible:outline-3 peer-focus-visible:outline-ttg19-focus peer-focus-visible:outline-offset-[5px] peer-focus-visible:rounded-[18px]">
<span class="ttg19-card relative block w-[230px] h-[130px] transform-3d transition-transform duration-[650ms] ease-[cubic-bezier(0.4,0.2,0.2,1.15)] motion-reduce:duration-150">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-1.5 rounded-2xl backface-hidden bg-linear-150 from-ttg19-frontthi to-ttg19-frontlo text-ttg19-frontink shadow-[0_18px_36px_-20px_oklch(0.3_0.03_265/0.55)]">
<b class="text-2xl font-extrabold tracking-[0.12em]">PAUSED</b>
<small class="text-[12.5px] opacity-80">Campaign is not spending</small>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-1.5 rounded-2xl backface-hidden rotate-y-180 bg-linear-150 from-ttg19-backhi to-ttg19-backlo text-white shadow-[0_18px_36px_-20px_oklch(0.3_0.08_160/0.55)]">
<b class="text-2xl font-extrabold tracking-[0.12em]">ACTIVE</b>
<small class="text-[12.5px] opacity-90">Ads are live · $184/day</small>
</span>
</span>
</label>
<p class="text-[12px] tracking-[0.12em] uppercase text-ttg19-mute">Click the card to flip state</p>
</section>@import "tailwindcss";
@theme {
--color-ttg19-bg: #eff0f5;
--color-ttg19-bg: oklch(0.95 0.006 265);
--color-ttg19-frontthi: #fdfdfe;
--color-ttg19-frontthi: oklch(0.99 0.002 265);
--color-ttg19-frontlo: #e4e7ee;
--color-ttg19-frontlo: oklch(0.92 0.008 265);
--color-ttg19-frontink: #4d5566;
--color-ttg19-frontink: oklch(0.44 0.02 265);
--color-ttg19-backhi: #2fa368;
--color-ttg19-backhi: oklch(0.64 0.16 155);
--color-ttg19-backlo: #1d7a5f;
--color-ttg19-backlo: oklch(0.51 0.12 170);
--color-ttg19-mute: #8a91a1;
--color-ttg19-mute: oklch(0.64 0.015 265);
--color-ttg19-focus: #3f63e0;
--color-ttg19-focus: oklch(0.55 0.19 265);
--font-ttg19-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.ttg-19 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-ttg19-bg: #eff0f5;
--color-ttg19-bg: oklch(0.95 0.006 265);
--color-ttg19-frontthi: #fdfdfe;
--color-ttg19-frontthi: oklch(0.99 0.002 265);
--color-ttg19-frontlo: #e4e7ee;
--color-ttg19-frontlo: oklch(0.92 0.008 265);
--color-ttg19-frontink: #4d5566;
--color-ttg19-frontink: oklch(0.44 0.02 265);
--color-ttg19-backhi: #2fa368;
--color-ttg19-backhi: oklch(0.64 0.16 155);
--color-ttg19-backlo: #1d7a5f;
--color-ttg19-backlo: oklch(0.51 0.12 170);
--color-ttg19-mute: #8a91a1;
--color-ttg19-mute: oklch(0.64 0.015 265);
--color-ttg19-focus: #3f63e0;
--color-ttg19-focus: oklch(0.55 0.19 265);
--font-ttg19-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.ttg-19 {
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-ttg19-bg: #eff0f5;
--color-ttg19-bg: oklch(0.95 0.006 265);
--color-ttg19-frontthi: #fdfdfe;
--color-ttg19-frontthi: oklch(0.99 0.002 265);
--color-ttg19-frontlo: #e4e7ee;
--color-ttg19-frontlo: oklch(0.92 0.008 265);
--color-ttg19-frontink: #4d5566;
--color-ttg19-frontink: oklch(0.44 0.02 265);
--color-ttg19-backhi: #2fa368;
--color-ttg19-backhi: oklch(0.64 0.16 155);
--color-ttg19-backlo: #1d7a5f;
--color-ttg19-backlo: oklch(0.51 0.12 170);
--color-ttg19-mute: #8a91a1;
--color-ttg19-mute: oklch(0.64 0.015 265);
--color-ttg19-focus: #3f63e0;
--color-ttg19-focus: oklch(0.55 0.19 265);
--font-ttg19-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.ttg-19 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-ttg19-bg: #eff0f5;
--color-ttg19-bg: oklch(0.95 0.006 265);
--color-ttg19-frontthi: #fdfdfe;
--color-ttg19-frontthi: oklch(0.99 0.002 265);
--color-ttg19-frontlo: #e4e7ee;
--color-ttg19-frontlo: oklch(0.92 0.008 265);
--color-ttg19-frontink: #4d5566;
--color-ttg19-frontink: oklch(0.44 0.02 265);
--color-ttg19-backhi: #2fa368;
--color-ttg19-backhi: oklch(0.64 0.16 155);
--color-ttg19-backlo: #1d7a5f;
--color-ttg19-backlo: oklch(0.51 0.12 170);
--color-ttg19-mute: #8a91a1;
--color-ttg19-mute: oklch(0.64 0.015 265);
--color-ttg19-focus: #3f63e0;
--color-ttg19-focus: oklch(0.55 0.19 265);
--font-ttg19-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.ttg-19 {
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=Plus+Jakarta+Sans: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=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- This demo is the clearest evidence that v4 changed what belongs in CSS:
transform-3d,backface-hidden,perspective-[900px]androtate-y-180are all core utilities now, so a flip card that used to need a hand-written block needs none. - The
sr-onlyinput sits OUTSIDE the label rather than inside it, bound byfor. Both work, but keeping the peer as a preceding sibling of the label is what letspeer-checked:andpeer-focus-visible:reach the card at all. motion-reduce:duration-150instead oftransition-none: the card must still finish on the correct face, and a 150ms rotation is short enough to read as a swap.- UI change from the CSS original: the back face's green pair was darkened to
oklch(0.64/0.51)so white text clears 4.6:1 across the whole gradient (the original's light end sat at 2.8:1), the front ink went tooklch(0.44), and the supporting line's opacity rose from 0.75 to 0.8/0.9 — the detail line is the part that makes the state unambiguous, so it should not be the faintest thing on the card.
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 3D Flip Card Toggle (rotateY Switch)
Source: https://codefronts.com/components/tailwind-css-toggles-switches/tailwind-3d-flip-card-toggle-rotatey-switch/
A boolean as a physical object: the whole control rotates 180° to reveal its other face — muted "Paused" on the front, vivid "Active" with a live figure on the back. v4's first-class 3D utilities mean the entire flip is five classes.
## HTML
```html
<section class="ttg-19 w-full min-h-svh flex flex-col items-center justify-center gap-7 px-5 py-14 bg-ttg19-bg font-ttg19-sans" aria-label="3D flip card toggle">
<input type="checkbox" id="ttg-19-sw" role="switch" aria-label="Campaign active" class="peer sr-only">
<label for="ttg-19-sw" aria-hidden="true" class="block cursor-pointer perspective-[900px] peer-checked:[&_.ttg19-card]:rotate-y-180 peer-focus-visible:outline-3 peer-focus-visible:outline-ttg19-focus peer-focus-visible:outline-offset-[5px] peer-focus-visible:rounded-[18px]">
<span class="ttg19-card relative block w-[230px] h-[130px] transform-3d transition-transform duration-[650ms] ease-[cubic-bezier(0.4,0.2,0.2,1.15)] motion-reduce:duration-150">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-1.5 rounded-2xl backface-hidden bg-linear-150 from-ttg19-frontthi to-ttg19-frontlo text-ttg19-frontink shadow-[0_18px_36px_-20px_oklch(0.3_0.03_265/0.55)]">
<b class="text-2xl font-extrabold tracking-[0.12em]">PAUSED</b>
<small class="text-[12.5px] opacity-80">Campaign is not spending</small>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-1.5 rounded-2xl backface-hidden rotate-y-180 bg-linear-150 from-ttg19-backhi to-ttg19-backlo text-white shadow-[0_18px_36px_-20px_oklch(0.3_0.08_160/0.55)]">
<b class="text-2xl font-extrabold tracking-[0.12em]">ACTIVE</b>
<small class="text-[12.5px] opacity-90">Ads are live · $184/day</small>
</span>
</span>
</label>
<p class="text-[12px] tracking-[0.12em] uppercase text-ttg19-mute">Click the card to flip state</p>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-ttg19-bg: #eff0f5;
--color-ttg19-bg: oklch(0.95 0.006 265);
--color-ttg19-frontthi: #fdfdfe;
--color-ttg19-frontthi: oklch(0.99 0.002 265);
--color-ttg19-frontlo: #e4e7ee;
--color-ttg19-frontlo: oklch(0.92 0.008 265);
--color-ttg19-frontink: #4d5566;
--color-ttg19-frontink: oklch(0.44 0.02 265);
--color-ttg19-backhi: #2fa368;
--color-ttg19-backhi: oklch(0.64 0.16 155);
--color-ttg19-backlo: #1d7a5f;
--color-ttg19-backlo: oklch(0.51 0.12 170);
--color-ttg19-mute: #8a91a1;
--color-ttg19-mute: oklch(0.64 0.015 265);
--color-ttg19-focus: #3f63e0;
--color-ttg19-focus: oklch(0.55 0.19 265);
--font-ttg19-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.ttg-19 {
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 3D Flip Card Toggle (rotateY Switch)
Source: https://codefronts.com/components/tailwind-css-toggles-switches/tailwind-3d-flip-card-toggle-rotatey-switch/
A boolean as a physical object: the whole control rotates 180° to reveal its other face — muted "Paused" on the front, vivid "Active" with a live figure on the back. v4's first-class 3D utilities mean the entire flip is five classes.
## HTML
```html
<section class="ttg-19 w-full min-h-svh flex flex-col items-center justify-center gap-7 px-5 py-14 bg-ttg19-bg font-ttg19-sans" aria-label="3D flip card toggle">
<input type="checkbox" id="ttg-19-sw" role="switch" aria-label="Campaign active" class="peer sr-only">
<label for="ttg-19-sw" aria-hidden="true" class="block cursor-pointer perspective-[900px] peer-checked:[&_.ttg19-card]:rotate-y-180 peer-focus-visible:outline-3 peer-focus-visible:outline-ttg19-focus peer-focus-visible:outline-offset-[5px] peer-focus-visible:rounded-[18px]">
<span class="ttg19-card relative block w-[230px] h-[130px] transform-3d transition-transform duration-[650ms] ease-[cubic-bezier(0.4,0.2,0.2,1.15)] motion-reduce:duration-150">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-1.5 rounded-2xl backface-hidden bg-linear-150 from-ttg19-frontthi to-ttg19-frontlo text-ttg19-frontink shadow-[0_18px_36px_-20px_oklch(0.3_0.03_265/0.55)]">
<b class="text-2xl font-extrabold tracking-[0.12em]">PAUSED</b>
<small class="text-[12.5px] opacity-80">Campaign is not spending</small>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-1.5 rounded-2xl backface-hidden rotate-y-180 bg-linear-150 from-ttg19-backhi to-ttg19-backlo text-white shadow-[0_18px_36px_-20px_oklch(0.3_0.08_160/0.55)]">
<b class="text-2xl font-extrabold tracking-[0.12em]">ACTIVE</b>
<small class="text-[12.5px] opacity-90">Ads are live · $184/day</small>
</span>
</span>
</label>
<p class="text-[12px] tracking-[0.12em] uppercase text-ttg19-mute">Click the card to flip state</p>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-ttg19-bg: #eff0f5;
--color-ttg19-bg: oklch(0.95 0.006 265);
--color-ttg19-frontthi: #fdfdfe;
--color-ttg19-frontthi: oklch(0.99 0.002 265);
--color-ttg19-frontlo: #e4e7ee;
--color-ttg19-frontlo: oklch(0.92 0.008 265);
--color-ttg19-frontink: #4d5566;
--color-ttg19-frontink: oklch(0.44 0.02 265);
--color-ttg19-backhi: #2fa368;
--color-ttg19-backhi: oklch(0.64 0.16 155);
--color-ttg19-backlo: #1d7a5f;
--color-ttg19-backlo: oklch(0.51 0.12 170);
--color-ttg19-mute: #8a91a1;
--color-ttg19-mute: oklch(0.64 0.015 265);
--color-ttg19-focus: #3f63e0;
--color-ttg19-focus: oklch(0.55 0.19 265);
--font-ttg19-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.ttg-19 {
width: 100%;
min-height: 100svh;
}
```How this works
Four rules make a flip card, and v4 has a utility for each. Perspective on the parent, transform-3d on the rotating inner, backface-hidden on the faces, and a pre-rotation on the back. Miss any one and the faces ghost through each other — which is the single most common flip-card bug.
Both faces state their meaning in words. Mid-flip, colour is unreadable and the card is edge-on; "PAUSED" and "ACTIVE" with supporting lines mean the state survives the animation, greyscale, and a screenshot.
The checkbox is sr-only and the card is its label, so clicking anywhere on 230×130px toggles — far past any touch-target floor, and the focus ring draws on the card the user can see via peer-focus-visible:.
Make it yours
- Flip vertically with
rotate-x-180for a flashcard feel. - Put real content on the back — a live spend figure sells the metaphor better than a word.
- Heavier card:
duration-[800ms]andperspective-[1200px]. - Add a corner fold with a clip-path triangle on each face.
Gotchas — read before shipping
backface-hiddenmust be on BOTH faces andtransform-3don their parent. Three of the four are easy to remember; the fourth is why flip cards ghost.perspective-*belongs on the wrapper. On the rotating element itself the flip flattens into a horizontal squash.- Under
motion-reduce:this must become a near-instant swap — a 650ms 3D rotation of a 230px card is a strong vestibular trigger.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
The 3D transform stack is universal in modern browsers; v4 ships transform-3d and backface-hidden as core utilities (in v3 both needed a plugin).