03 / 39
All 39 in 39 Tailwind CSS Breadcrumbs
- 01Tailwind Accessible Breadcrumb with Schema.org Microdata & ARIA
- 02Tailwind Responsive Collapsing Breadcrumb Bar with Container Queries
- 03Tailwind Adaptive Light & Dark Mode Breadcrumb Bar with Theme Tokens
- 04Tailwind E-Commerce Filter & Facet Breadcrumb with Removable Chips
- 05Tailwind Glassmorphism Floating Breadcrumb Pill with Shimmer Sweep
- 06Tailwind Neumorphic Soft UI Breadcrumb with Dual Box Shadows
- 07Tailwind Sticky Scroll-Shrink Breadcrumb Header with Scroll-Driven Animation
- 08Tailwind Material Design Flat Breadcrumb Bar with Ink Ripple
- 09Tailwind Isometric 3D Layered Breadcrumb with Extruded Tiles
- 10Tailwind Breadcrumb Bar with Built-In Dropdown Sibling Menus
- 11Tailwind Full-Width Block-Style Segmented Breadcrumb Bar
- 12Tailwind Accent-Colour Toggle Breadcrumb with Persisted Theme
- 13Tailwind Seamless Arrow-Cutout Breadcrumb Trail with clip-path
- 14Tailwind Compact Icon-Only Home Node Breadcrumb Bar
- 15Tailwind Segmented Rounded-Outline Pill Breadcrumb
- 16Tailwind Neumorphic Soft Inset-Shadow Breadcrumb Channel
- 17Tailwind CSS Grid Auto-Fitting Responsive Breadcrumb Trail
- 18Tailwind Holographic Shimmer Web3 Breadcrumb with Animated @property
- 19Tailwind SaaS Gradient-Text Breadcrumb Bar with Animated Clip
- 20Tailwind Marketplace Filter-Chip Breadcrumb with Icon Chips
- 21Tailwind Editorial Breadcrumb with Animated SVG Wave Underline
- 22Tailwind Developer Docs Breadcrumb with One-Click Path Copy
- 23Tailwind Modern Arrow Breadcrumb Bar using clip-path Polygons
- 24Tailwind Multi-Line Aligned Breadcrumb Layout with CSS Subgrid
- 25Tailwind Breadcrumb Links with Animated Underline Glow
- 26Tailwind Minimalist Breadcrumb with Swappable Masked SVG Separators
- 27Tailwind Multi-Step Checkout & Wizard Breadcrumb Indicator
- 28Tailwind Ribbon-Style Chevron Breadcrumb Trail
- 29Tailwind Pill-Shape Badge Breadcrumb Bar
- 30Tailwind Clean Line-Separator Minimalist Breadcrumbs
- 31Tailwind Gradient Background Glow Breadcrumb Bar
- 32Tailwind Floating Card Shadow Breadcrumb Navigation
- 33Tailwind Truncated Ellipsis Compact Mobile Breadcrumb
- 34Tailwind Inline Bullet-Dot Separator Breadcrumb
- 35Tailwind Skewed Parallelogram Breadcrumb Bar
- 36Tailwind Outline Border-Only Geometric Breadcrumbs
- 37Tailwind Circular Icon & Numbered Step Breadcrumbs
- 38Tailwind Frosted Glass Dark UI Breadcrumb Component
- 39Tailwind Micro-Interaction Animated Hover Breadcrumbs
Tailwind Adaptive Light & Dark Mode Breadcrumb Bar with Theme Tokens
A trail whose entire skin flips light to dark from one block of custom properties, with no JavaScript and no class-toggling framework: a hidden checkbox flips the tokens through has-checked:, so every crumb, separator and hover tint recolours from the same five variables. The SaaS-dashboard treatment, frosted glass included.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tbc-03 w-full min-h-svh grid place-items-center px-5 py-9 font-tbc03-sans [--tbc03-bg:oklch(1_0_0/.7)] [--tbc03-text:oklch(0.5_0.02_265)] [--tbc03-strong:oklch(0.25_0.02_265)] [--tbc03-sep:oklch(0.75_0.02_265)] [--tbc03-hover:oklch(0.95_0.01_265)] [--tbc03-line:oklch(0.85_0.01_265/.7)] [--tbc03-stage:oklch(0.97_0.005_265)] bg-[var(--tbc03-stage)] [color-scheme:light] transition-colors duration-300 has-checked:[--tbc03-bg:oklch(0.2_0.02_265/.7)] has-checked:[--tbc03-text:oklch(0.72_0.02_265)] has-checked:[--tbc03-strong:oklch(0.96_0.01_265)] has-checked:[--tbc03-sep:oklch(0.5_0.02_265)] has-checked:[--tbc03-hover:oklch(0.28_0.02_265)] has-checked:[--tbc03-line:oklch(0.4_0.02_265/.5)] has-checked:[--tbc03-stage:oklch(0.14_0.02_265)] has-checked:[color-scheme:dark] motion-reduce:transition-none">
<div class="flex flex-wrap items-center justify-center gap-4">
<nav aria-label="Breadcrumb">
<ol class="flex flex-wrap items-center list-none m-0 px-3.5 py-2 rounded-xl bg-[var(--tbc03-bg)] border border-[var(--tbc03-line)] backdrop-blur-md transition-colors duration-300 motion-reduce:transition-none">
<li class="flex items-center"><a href="#" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-medium text-[var(--tbc03-text)] no-underline transition-colors duration-200 hover:text-[var(--tbc03-strong)] hover:bg-[var(--tbc03-hover)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Dashboard</a></li>
<li class="flex items-center before:content-['\203A'] before:mx-2 before:text-[var(--tbc03-sep)]"><a href="#" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-medium text-[var(--tbc03-text)] no-underline transition-colors duration-200 hover:text-[var(--tbc03-strong)] hover:bg-[var(--tbc03-hover)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Projects</a></li>
<li class="flex items-center before:content-['\203A'] before:mx-2 before:text-[var(--tbc03-sep)]"><a href="#" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-medium text-[var(--tbc03-text)] no-underline transition-colors duration-200 hover:text-[var(--tbc03-strong)] hover:bg-[var(--tbc03-hover)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Aurora</a></li>
<li class="flex items-center before:content-['\203A'] before:mx-2 before:text-[var(--tbc03-sep)]"><a href="#" aria-current="page" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-semibold text-[var(--tbc03-strong)] no-underline bg-[color-mix(in_oklab,var(--color-tbc03-acc)_18%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Settings</a></li>
</ol>
</nav>
<div>
<input type="checkbox" id="tbc03-theme" class="peer sr-only">
<label for="tbc03-theme" class="inline-flex items-center gap-2 min-h-11 px-4 rounded-full select-none cursor-pointer bg-[var(--tbc03-bg)] border border-[var(--tbc03-line)] backdrop-blur-md text-[12.5px] font-semibold text-[var(--tbc03-strong)] transition-colors duration-200 hover:bg-[var(--tbc03-hover)] peer-focus-visible:outline-2 peer-focus-visible:outline-tbc03-acc peer-focus-visible:outline-offset-2 motion-reduce:transition-none">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" class="w-3.5 h-3.5 peer-checked:hidden"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" class="w-3.5 h-3.5 hidden peer-checked:block"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>
Theme
</label>
</div>
</div>
</section><section class="tbc-03 w-full min-h-svh grid place-items-center px-5 py-9 font-tbc03-sans [--tbc03-bg:oklch(1_0_0/.7)] [--tbc03-text:oklch(0.5_0.02_265)] [--tbc03-strong:oklch(0.25_0.02_265)] [--tbc03-sep:oklch(0.75_0.02_265)] [--tbc03-hover:oklch(0.95_0.01_265)] [--tbc03-line:oklch(0.85_0.01_265/.7)] [--tbc03-stage:oklch(0.97_0.005_265)] bg-[var(--tbc03-stage)] [color-scheme:light] transition-colors duration-300 has-checked:[--tbc03-bg:oklch(0.2_0.02_265/.7)] has-checked:[--tbc03-text:oklch(0.72_0.02_265)] has-checked:[--tbc03-strong:oklch(0.96_0.01_265)] has-checked:[--tbc03-sep:oklch(0.5_0.02_265)] has-checked:[--tbc03-hover:oklch(0.28_0.02_265)] has-checked:[--tbc03-line:oklch(0.4_0.02_265/.5)] has-checked:[--tbc03-stage:oklch(0.14_0.02_265)] has-checked:[color-scheme:dark] motion-reduce:transition-none">
<div class="flex flex-wrap items-center justify-center gap-4">
<nav aria-label="Breadcrumb">
<ol class="flex flex-wrap items-center list-none m-0 px-3.5 py-2 rounded-xl bg-[var(--tbc03-bg)] border border-[var(--tbc03-line)] backdrop-blur-md transition-colors duration-300 motion-reduce:transition-none">
<li class="flex items-center"><a href="#" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-medium text-[var(--tbc03-text)] no-underline transition-colors duration-200 hover:text-[var(--tbc03-strong)] hover:bg-[var(--tbc03-hover)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Dashboard</a></li>
<li class="flex items-center before:content-['\203A'] before:mx-2 before:text-[var(--tbc03-sep)]"><a href="#" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-medium text-[var(--tbc03-text)] no-underline transition-colors duration-200 hover:text-[var(--tbc03-strong)] hover:bg-[var(--tbc03-hover)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Projects</a></li>
<li class="flex items-center before:content-['\203A'] before:mx-2 before:text-[var(--tbc03-sep)]"><a href="#" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-medium text-[var(--tbc03-text)] no-underline transition-colors duration-200 hover:text-[var(--tbc03-strong)] hover:bg-[var(--tbc03-hover)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Aurora</a></li>
<li class="flex items-center before:content-['\203A'] before:mx-2 before:text-[var(--tbc03-sep)]"><a href="#" aria-current="page" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-semibold text-[var(--tbc03-strong)] no-underline bg-[color-mix(in_oklab,var(--color-tbc03-acc)_18%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Settings</a></li>
</ol>
</nav>
<div>
<input type="checkbox" id="tbc03-theme" class="peer sr-only">
<label for="tbc03-theme" class="inline-flex items-center gap-2 min-h-11 px-4 rounded-full select-none cursor-pointer bg-[var(--tbc03-bg)] border border-[var(--tbc03-line)] backdrop-blur-md text-[12.5px] font-semibold text-[var(--tbc03-strong)] transition-colors duration-200 hover:bg-[var(--tbc03-hover)] peer-focus-visible:outline-2 peer-focus-visible:outline-tbc03-acc peer-focus-visible:outline-offset-2 motion-reduce:transition-none">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" class="w-3.5 h-3.5 peer-checked:hidden"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" class="w-3.5 h-3.5 hidden peer-checked:block"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>
Theme
</label>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-tbc03-acc: #6f7ede;
--color-tbc03-acc: oklch(0.62 0.16 265);
--font-tbc03-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tbc-03 {
width: 100%;
min-height: 100svh;
}
/* Icon swap needs the checkbox as a preceding sibling of the label, and the SVGs are
inside the label: peer-checked: cannot reach INTO a peer, so the two icon rules are
the one part of this demo utilities cannot express. */
.tbc-03 input:checked ~ label svg:first-of-type {
display: none;
}
.tbc-03 input:checked ~ label svg:last-of-type {
display: block;
}@import "tailwindcss";
@theme {
--color-tbc03-acc: #6f7ede;
--color-tbc03-acc: oklch(0.62 0.16 265);
--font-tbc03-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tbc-03 {
width: 100%;
min-height: 100svh;
}
/* Icon swap needs the checkbox as a preceding sibling of the label, and the SVGs are
inside the label: peer-checked: cannot reach INTO a peer, so the two icon rules are
the one part of this demo utilities cannot express. */
.tbc-03 input:checked ~ label svg:first-of-type {
display: none;
}
.tbc-03 input:checked ~ label svg:last-of-type {
display: block;
}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-tbc03-acc: #6f7ede;
--color-tbc03-acc: oklch(0.62 0.16 265);
--font-tbc03-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tbc-03 {
width: 100%;
min-height: 100svh;
}
/* Icon swap needs the checkbox as a preceding sibling of the label, and the SVGs are
inside the label: peer-checked: cannot reach INTO a peer, so the two icon rules are
the one part of this demo utilities cannot express. */
.tbc-03 input:checked ~ label svg:first-of-type {
display: none;
}
.tbc-03 input:checked ~ label svg:last-of-type {
display: block;
}@import "tailwindcss";
@theme {
--color-tbc03-acc: #6f7ede;
--color-tbc03-acc: oklch(0.62 0.16 265);
--font-tbc03-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tbc-03 {
width: 100%;
min-height: 100svh;
}
/* Icon swap needs the checkbox as a preceding sibling of the label, and the SVGs are
inside the label: peer-checked: cannot reach INTO a peer, so the two icon rules are
the one part of this demo utilities cannot express. */
.tbc-03 input:checked ~ label svg:first-of-type {
display: none;
}
.tbc-03 input:checked ~ label svg:last-of-type {
display: block;
}<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=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono: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=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Nine
:has(:checked)declarations become ninehas-checked:[--token:value]utilities on the root. The dark skin is now legible as a diff against the light skin, on one element, instead of two rule blocks ninety lines apart. - The icon swap is the honest failure case:
peer-checked:styles siblings of the input, and the icons are inside the label, so the two display rules stay in CSS. Worth stating plainly — the alternative is duplicating both SVGs outside the label for no gain. [color-scheme:dark]as an arbitrary property is the whole native-widget story: scrollbars, date pickers and<select>popups inside the component follow the theme with no extra work.
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 Adaptive Light & Dark Mode Breadcrumb Bar with Theme Tokens
Source: https://codefronts.com/navigation/tailwind-css-breadcrumbs/tailwind-adaptive-light-dark-breadcrumb-theme-tokens/
A trail whose entire skin flips light to dark from one block of custom properties, with no JavaScript and no class-toggling framework: a hidden checkbox flips the tokens through has-checked:, so every crumb, separator and hover tint recolours from the same five variables. The SaaS-dashboard treatment, frosted glass included.
## HTML
```html
<section class="tbc-03 w-full min-h-svh grid place-items-center px-5 py-9 font-tbc03-sans [--tbc03-bg:oklch(1_0_0/.7)] [--tbc03-text:oklch(0.5_0.02_265)] [--tbc03-strong:oklch(0.25_0.02_265)] [--tbc03-sep:oklch(0.75_0.02_265)] [--tbc03-hover:oklch(0.95_0.01_265)] [--tbc03-line:oklch(0.85_0.01_265/.7)] [--tbc03-stage:oklch(0.97_0.005_265)] bg-[var(--tbc03-stage)] [color-scheme:light] transition-colors duration-300 has-checked:[--tbc03-bg:oklch(0.2_0.02_265/.7)] has-checked:[--tbc03-text:oklch(0.72_0.02_265)] has-checked:[--tbc03-strong:oklch(0.96_0.01_265)] has-checked:[--tbc03-sep:oklch(0.5_0.02_265)] has-checked:[--tbc03-hover:oklch(0.28_0.02_265)] has-checked:[--tbc03-line:oklch(0.4_0.02_265/.5)] has-checked:[--tbc03-stage:oklch(0.14_0.02_265)] has-checked:[color-scheme:dark] motion-reduce:transition-none">
<div class="flex flex-wrap items-center justify-center gap-4">
<nav aria-label="Breadcrumb">
<ol class="flex flex-wrap items-center list-none m-0 px-3.5 py-2 rounded-xl bg-[var(--tbc03-bg)] border border-[var(--tbc03-line)] backdrop-blur-md transition-colors duration-300 motion-reduce:transition-none">
<li class="flex items-center"><a href="#" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-medium text-[var(--tbc03-text)] no-underline transition-colors duration-200 hover:text-[var(--tbc03-strong)] hover:bg-[var(--tbc03-hover)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Dashboard</a></li>
<li class="flex items-center before:content-['\203A'] before:mx-2 before:text-[var(--tbc03-sep)]"><a href="#" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-medium text-[var(--tbc03-text)] no-underline transition-colors duration-200 hover:text-[var(--tbc03-strong)] hover:bg-[var(--tbc03-hover)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Projects</a></li>
<li class="flex items-center before:content-['\203A'] before:mx-2 before:text-[var(--tbc03-sep)]"><a href="#" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-medium text-[var(--tbc03-text)] no-underline transition-colors duration-200 hover:text-[var(--tbc03-strong)] hover:bg-[var(--tbc03-hover)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Aurora</a></li>
<li class="flex items-center before:content-['\203A'] before:mx-2 before:text-[var(--tbc03-sep)]"><a href="#" aria-current="page" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-semibold text-[var(--tbc03-strong)] no-underline bg-[color-mix(in_oklab,var(--color-tbc03-acc)_18%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Settings</a></li>
</ol>
</nav>
<div>
<input type="checkbox" id="tbc03-theme" class="peer sr-only">
<label for="tbc03-theme" class="inline-flex items-center gap-2 min-h-11 px-4 rounded-full select-none cursor-pointer bg-[var(--tbc03-bg)] border border-[var(--tbc03-line)] backdrop-blur-md text-[12.5px] font-semibold text-[var(--tbc03-strong)] transition-colors duration-200 hover:bg-[var(--tbc03-hover)] peer-focus-visible:outline-2 peer-focus-visible:outline-tbc03-acc peer-focus-visible:outline-offset-2 motion-reduce:transition-none">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" class="w-3.5 h-3.5 peer-checked:hidden"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" class="w-3.5 h-3.5 hidden peer-checked:block"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>
Theme
</label>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tbc03-acc: #6f7ede;
--color-tbc03-acc: oklch(0.62 0.16 265);
--font-tbc03-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tbc-03 {
width: 100%;
min-height: 100svh;
}
/* Icon swap needs the checkbox as a preceding sibling of the label, and the SVGs are
inside the label: peer-checked: cannot reach INTO a peer, so the two icon rules are
the one part of this demo utilities cannot express. */
.tbc-03 input:checked ~ label svg:first-of-type {
display: none;
}
.tbc-03 input:checked ~ label svg:last-of-type {
display: block;
}
```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 Adaptive Light & Dark Mode Breadcrumb Bar with Theme Tokens
Source: https://codefronts.com/navigation/tailwind-css-breadcrumbs/tailwind-adaptive-light-dark-breadcrumb-theme-tokens/
A trail whose entire skin flips light to dark from one block of custom properties, with no JavaScript and no class-toggling framework: a hidden checkbox flips the tokens through has-checked:, so every crumb, separator and hover tint recolours from the same five variables. The SaaS-dashboard treatment, frosted glass included.
## HTML
```html
<section class="tbc-03 w-full min-h-svh grid place-items-center px-5 py-9 font-tbc03-sans [--tbc03-bg:oklch(1_0_0/.7)] [--tbc03-text:oklch(0.5_0.02_265)] [--tbc03-strong:oklch(0.25_0.02_265)] [--tbc03-sep:oklch(0.75_0.02_265)] [--tbc03-hover:oklch(0.95_0.01_265)] [--tbc03-line:oklch(0.85_0.01_265/.7)] [--tbc03-stage:oklch(0.97_0.005_265)] bg-[var(--tbc03-stage)] [color-scheme:light] transition-colors duration-300 has-checked:[--tbc03-bg:oklch(0.2_0.02_265/.7)] has-checked:[--tbc03-text:oklch(0.72_0.02_265)] has-checked:[--tbc03-strong:oklch(0.96_0.01_265)] has-checked:[--tbc03-sep:oklch(0.5_0.02_265)] has-checked:[--tbc03-hover:oklch(0.28_0.02_265)] has-checked:[--tbc03-line:oklch(0.4_0.02_265/.5)] has-checked:[--tbc03-stage:oklch(0.14_0.02_265)] has-checked:[color-scheme:dark] motion-reduce:transition-none">
<div class="flex flex-wrap items-center justify-center gap-4">
<nav aria-label="Breadcrumb">
<ol class="flex flex-wrap items-center list-none m-0 px-3.5 py-2 rounded-xl bg-[var(--tbc03-bg)] border border-[var(--tbc03-line)] backdrop-blur-md transition-colors duration-300 motion-reduce:transition-none">
<li class="flex items-center"><a href="#" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-medium text-[var(--tbc03-text)] no-underline transition-colors duration-200 hover:text-[var(--tbc03-strong)] hover:bg-[var(--tbc03-hover)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Dashboard</a></li>
<li class="flex items-center before:content-['\203A'] before:mx-2 before:text-[var(--tbc03-sep)]"><a href="#" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-medium text-[var(--tbc03-text)] no-underline transition-colors duration-200 hover:text-[var(--tbc03-strong)] hover:bg-[var(--tbc03-hover)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Projects</a></li>
<li class="flex items-center before:content-['\203A'] before:mx-2 before:text-[var(--tbc03-sep)]"><a href="#" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-medium text-[var(--tbc03-text)] no-underline transition-colors duration-200 hover:text-[var(--tbc03-strong)] hover:bg-[var(--tbc03-hover)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Aurora</a></li>
<li class="flex items-center before:content-['\203A'] before:mx-2 before:text-[var(--tbc03-sep)]"><a href="#" aria-current="page" class="flex items-center min-h-9 px-2.5 rounded-lg text-[13.5px] font-semibold text-[var(--tbc03-strong)] no-underline bg-[color-mix(in_oklab,var(--color-tbc03-acc)_18%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc03-acc focus-visible:outline-offset-2">Settings</a></li>
</ol>
</nav>
<div>
<input type="checkbox" id="tbc03-theme" class="peer sr-only">
<label for="tbc03-theme" class="inline-flex items-center gap-2 min-h-11 px-4 rounded-full select-none cursor-pointer bg-[var(--tbc03-bg)] border border-[var(--tbc03-line)] backdrop-blur-md text-[12.5px] font-semibold text-[var(--tbc03-strong)] transition-colors duration-200 hover:bg-[var(--tbc03-hover)] peer-focus-visible:outline-2 peer-focus-visible:outline-tbc03-acc peer-focus-visible:outline-offset-2 motion-reduce:transition-none">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" class="w-3.5 h-3.5 peer-checked:hidden"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" class="w-3.5 h-3.5 hidden peer-checked:block"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>
Theme
</label>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tbc03-acc: #6f7ede;
--color-tbc03-acc: oklch(0.62 0.16 265);
--font-tbc03-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tbc-03 {
width: 100%;
min-height: 100svh;
}
/* Icon swap needs the checkbox as a preceding sibling of the label, and the SVGs are
inside the label: peer-checked: cannot reach INTO a peer, so the two icon rules are
the one part of this demo utilities cannot express. */
.tbc-03 input:checked ~ label svg:first-of-type {
display: none;
}
.tbc-03 input:checked ~ label svg:last-of-type {
display: block;
}
```How this works
Tokens stay variables; utilities read them. Tailwind's dark: variant is the usual answer, but it keys off a document-level class or media query. This component themes itself, so the port keeps the CSS collection's architecture — live custom properties on the root — and moves only the switch into a variant:
<div class="[--tbc03-bg:oklch(1_0_0/.7)]
has-checked:[--tbc03-bg:oklch(0.2_0.02_265/.7)]
has-checked:[color-scheme:dark]">Nine :has(:checked) declarations sit in one class list, on the element they apply to.
The toggle is a real control. A visually hidden checkbox plus a <label> with min-h-11; the sun and moon icons swap with peer-checked:hidden / peer-checked:block, and the focus ring lands on the label via peer-focus-visible:. No JavaScript, full keyboard support.
Why not dark:. Add @custom-variant dark (&:where(.dark, .dark *)) and the same tokens can follow a site-wide theme instead; the demo keeps the local switch because a component that themes in isolation is the harder and more instructive case.
Make it yours
- Re-skin either mode by editing one arbitrary property per role — the crumbs never name a colour directly.
- Follow the OS instead of the checkbox: move the dark values into a
@media (prefers-color-scheme:dark)block in the stylesheet, keeping thehas-checked:set as the manual override. - Persist the choice with three lines of JS writing the checkbox state to
localStorage— the only reason this demo would ever need script.
Gotchas — read before shipping
- Arbitrary property values cannot contain spaces:
has-checked:[--tbc03-bg:oklch(0.2_0.02_265/.7)]needs the underscore escape. color-schememust be set on the element whose descendants render native widgets; setting it on<html>only would miss a self-theming component.- Translucent token plus
backdrop-blurmeans contrast depends on what is behind the bar — check the current-crumb text against both stage colours, not just one.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
:has() is the gate for the switch (Firefox 121); color-mix() and backdrop-filter are Baseline. Without :has() the bar renders in its light skin and the toggle does nothing — a safe degradation.