08 / 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 Material Design Flat Breadcrumb Bar with Ink Ripple
Material's flat surface, type scale and state layers in utilities: an elevation-1 card, a masked chevron separator, a color-mix() hover layer, and an ink ripple that fires on :active from a radial-gradient pseudo-element — no ripple library, no JS.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tbc-08 w-full min-h-svh grid place-items-center bg-tbc08-bg font-tbc08-sans px-8 py-8">
<nav aria-label="Breadcrumb">
<ol class="inline-flex flex-wrap items-center list-none m-0 px-2 py-1.5 rounded-lg bg-white shadow-[0_1px_2px_oklch(0_0_0/0.12),0_1px_3px_oklch(0_0_0/0.08)]">
<li class="flex items-center"><a href="#" class="relative overflow-hidden inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-primary no-underline transition-colors duration-200 hover:bg-[color-mix(in_oklab,var(--color-tbc08-primary)_8%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2 after:content-[''] after:absolute after:left-1/2 after:top-1/2 after:w-[160%] after:aspect-square after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:pointer-events-none after:scale-0 after:opacity-0 after:bg-[radial-gradient(circle,color-mix(in_oklab,var(--color-tbc08-primary)_40%,transparent),transparent_60%)] after:transition-[scale,opacity] after:duration-400 active:after:scale-100 active:after:opacity-100 active:after:duration-0 motion-reduce:after:hidden">Home</a></li>
<li class="flex items-center before:content-[''] before:w-4.5 before:h-4.5 before:mx-0.5 before:bg-tbc08-mut before:[mask-image:var(--tbc08-chev)] before:[mask-size:contain] before:[mask-position:center] before:[mask-repeat:no-repeat]"><a href="#" class="relative overflow-hidden inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-primary no-underline transition-colors duration-200 hover:bg-[color-mix(in_oklab,var(--color-tbc08-primary)_8%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2 after:content-[''] after:absolute after:left-1/2 after:top-1/2 after:w-[160%] after:aspect-square after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:pointer-events-none after:scale-0 after:opacity-0 after:bg-[radial-gradient(circle,color-mix(in_oklab,var(--color-tbc08-primary)_40%,transparent),transparent_60%)] after:transition-[scale,opacity] after:duration-400 active:after:scale-100 active:after:opacity-100 active:after:duration-0 motion-reduce:after:hidden">Materials</a></li>
<li class="flex items-center before:content-[''] before:w-4.5 before:h-4.5 before:mx-0.5 before:bg-tbc08-mut before:[mask-image:var(--tbc08-chev)] before:[mask-size:contain] before:[mask-position:center] before:[mask-repeat:no-repeat]"><a href="#" class="relative overflow-hidden inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-primary no-underline transition-colors duration-200 hover:bg-[color-mix(in_oklab,var(--color-tbc08-primary)_8%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2 after:content-[''] after:absolute after:left-1/2 after:top-1/2 after:w-[160%] after:aspect-square after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:pointer-events-none after:scale-0 after:opacity-0 after:bg-[radial-gradient(circle,color-mix(in_oklab,var(--color-tbc08-primary)_40%,transparent),transparent_60%)] after:transition-[scale,opacity] after:duration-400 active:after:scale-100 active:after:opacity-100 active:after:duration-0 motion-reduce:after:hidden">Components</a></li>
<li class="flex items-center before:content-[''] before:w-4.5 before:h-4.5 before:mx-0.5 before:bg-tbc08-mut before:[mask-image:var(--tbc08-chev)] before:[mask-size:contain] before:[mask-position:center] before:[mask-repeat:no-repeat]"><a href="#" aria-current="page" class="inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-on no-underline cursor-default focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2">Navigation</a></li>
</ol>
</nav>
</section><section class="tbc-08 w-full min-h-svh grid place-items-center bg-tbc08-bg font-tbc08-sans px-8 py-8">
<nav aria-label="Breadcrumb">
<ol class="inline-flex flex-wrap items-center list-none m-0 px-2 py-1.5 rounded-lg bg-white shadow-[0_1px_2px_oklch(0_0_0/0.12),0_1px_3px_oklch(0_0_0/0.08)]">
<li class="flex items-center"><a href="#" class="relative overflow-hidden inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-primary no-underline transition-colors duration-200 hover:bg-[color-mix(in_oklab,var(--color-tbc08-primary)_8%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2 after:content-[''] after:absolute after:left-1/2 after:top-1/2 after:w-[160%] after:aspect-square after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:pointer-events-none after:scale-0 after:opacity-0 after:bg-[radial-gradient(circle,color-mix(in_oklab,var(--color-tbc08-primary)_40%,transparent),transparent_60%)] after:transition-[scale,opacity] after:duration-400 active:after:scale-100 active:after:opacity-100 active:after:duration-0 motion-reduce:after:hidden">Home</a></li>
<li class="flex items-center before:content-[''] before:w-4.5 before:h-4.5 before:mx-0.5 before:bg-tbc08-mut before:[mask-image:var(--tbc08-chev)] before:[mask-size:contain] before:[mask-position:center] before:[mask-repeat:no-repeat]"><a href="#" class="relative overflow-hidden inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-primary no-underline transition-colors duration-200 hover:bg-[color-mix(in_oklab,var(--color-tbc08-primary)_8%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2 after:content-[''] after:absolute after:left-1/2 after:top-1/2 after:w-[160%] after:aspect-square after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:pointer-events-none after:scale-0 after:opacity-0 after:bg-[radial-gradient(circle,color-mix(in_oklab,var(--color-tbc08-primary)_40%,transparent),transparent_60%)] after:transition-[scale,opacity] after:duration-400 active:after:scale-100 active:after:opacity-100 active:after:duration-0 motion-reduce:after:hidden">Materials</a></li>
<li class="flex items-center before:content-[''] before:w-4.5 before:h-4.5 before:mx-0.5 before:bg-tbc08-mut before:[mask-image:var(--tbc08-chev)] before:[mask-size:contain] before:[mask-position:center] before:[mask-repeat:no-repeat]"><a href="#" class="relative overflow-hidden inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-primary no-underline transition-colors duration-200 hover:bg-[color-mix(in_oklab,var(--color-tbc08-primary)_8%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2 after:content-[''] after:absolute after:left-1/2 after:top-1/2 after:w-[160%] after:aspect-square after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:pointer-events-none after:scale-0 after:opacity-0 after:bg-[radial-gradient(circle,color-mix(in_oklab,var(--color-tbc08-primary)_40%,transparent),transparent_60%)] after:transition-[scale,opacity] after:duration-400 active:after:scale-100 active:after:opacity-100 active:after:duration-0 motion-reduce:after:hidden">Components</a></li>
<li class="flex items-center before:content-[''] before:w-4.5 before:h-4.5 before:mx-0.5 before:bg-tbc08-mut before:[mask-image:var(--tbc08-chev)] before:[mask-size:contain] before:[mask-position:center] before:[mask-repeat:no-repeat]"><a href="#" aria-current="page" class="inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-on no-underline cursor-default focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2">Navigation</a></li>
</ol>
</nav>
</section>@import "tailwindcss";
@theme {
--color-tbc08-bg: #f6f6f9;
--color-tbc08-bg: oklch(0.97 0.004 265);
--color-tbc08-primary: #4d5fc0;
--color-tbc08-primary: oklch(0.5 0.15 265);
--color-tbc08-on: #52555c;
--color-tbc08-on: oklch(0.35 0.01 265);
--color-tbc08-mut: #8f9199;
--color-tbc08-mut: oklch(0.6 0.01 265);
--font-tbc08-sans: 'Roboto', system-ui, sans-serif;
}
/* Mask data-URI as a plain custom property: not a design-scale value, so it should
not mint utilities. */
.tbc-08 {
width: 100%;
min-height: 100svh;
--tbc08-chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 6l6 6-6 6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* Safari < 15.4 mask prefix. */
.tbc-08 li::before {
-webkit-mask: var(--tbc08-chev) center/contain no-repeat;
}@import "tailwindcss";
@theme {
--color-tbc08-bg: #f6f6f9;
--color-tbc08-bg: oklch(0.97 0.004 265);
--color-tbc08-primary: #4d5fc0;
--color-tbc08-primary: oklch(0.5 0.15 265);
--color-tbc08-on: #52555c;
--color-tbc08-on: oklch(0.35 0.01 265);
--color-tbc08-mut: #8f9199;
--color-tbc08-mut: oklch(0.6 0.01 265);
--font-tbc08-sans: 'Roboto', system-ui, sans-serif;
}
/* Mask data-URI as a plain custom property: not a design-scale value, so it should
not mint utilities. */
.tbc-08 {
width: 100%;
min-height: 100svh;
--tbc08-chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 6l6 6-6 6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* Safari < 15.4 mask prefix. */
.tbc-08 li::before {
-webkit-mask: var(--tbc08-chev) center/contain no-repeat;
}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-tbc08-bg: #f6f6f9;
--color-tbc08-bg: oklch(0.97 0.004 265);
--color-tbc08-primary: #4d5fc0;
--color-tbc08-primary: oklch(0.5 0.15 265);
--color-tbc08-on: #52555c;
--color-tbc08-on: oklch(0.35 0.01 265);
--color-tbc08-mut: #8f9199;
--color-tbc08-mut: oklch(0.6 0.01 265);
--font-tbc08-sans: 'Roboto', system-ui, sans-serif;
}
/* Mask data-URI as a plain custom property: not a design-scale value, so it should
not mint utilities. */
.tbc-08 {
width: 100%;
min-height: 100svh;
--tbc08-chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 6l6 6-6 6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* Safari < 15.4 mask prefix. */
.tbc-08 li::before {
-webkit-mask: var(--tbc08-chev) center/contain no-repeat;
}@import "tailwindcss";
@theme {
--color-tbc08-bg: #f6f6f9;
--color-tbc08-bg: oklch(0.97 0.004 265);
--color-tbc08-primary: #4d5fc0;
--color-tbc08-primary: oklch(0.5 0.15 265);
--color-tbc08-on: #52555c;
--color-tbc08-on: oklch(0.35 0.01 265);
--color-tbc08-mut: #8f9199;
--color-tbc08-mut: oklch(0.6 0.01 265);
--font-tbc08-sans: 'Roboto', system-ui, sans-serif;
}
/* Mask data-URI as a plain custom property: not a design-scale value, so it should
not mint utilities. */
.tbc-08 {
width: 100%;
min-height: 100svh;
--tbc08-chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 6l6 6-6 6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* Safari < 15.4 mask prefix. */
.tbc-08 li::before {
-webkit-mask: var(--tbc08-chev) center/contain no-repeat;
}<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=Roboto:wght@400;500;700&family=JetBrains+Mono:wght@400;500&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=Roboto:wght@400;500;700&family=JetBrains+Mono:wght@400;500&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The ripple's eleven
after:utilities are the longest class run in the collection, and the payoff is that the press state sits beside the hover state on the same element — the CSS version split them across three rules and a media query. color-mix()inside an arbitrarybg-*is how Material's state-layer percentages survive the port literally. Anopacity-based approximation would fade the label too.- UI change from the CSS original: links grew to
min-h-11, and the current crumb lost the ripple and gainedcursor-default. Material specifies no press feedback for the current destination.
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 Material Design Flat Breadcrumb Bar with Ink Ripple
Source: https://codefronts.com/navigation/tailwind-css-breadcrumbs/tailwind-material-design-flat-breadcrumb-ink-ripple/
Material's flat surface, type scale and state layers in utilities: an elevation-1 card, a masked chevron separator, a color-mix() hover layer, and an ink ripple that fires on :active from a radial-gradient pseudo-element — no ripple library, no JS.
## HTML
```html
<section class="tbc-08 w-full min-h-svh grid place-items-center bg-tbc08-bg font-tbc08-sans px-8 py-8">
<nav aria-label="Breadcrumb">
<ol class="inline-flex flex-wrap items-center list-none m-0 px-2 py-1.5 rounded-lg bg-white shadow-[0_1px_2px_oklch(0_0_0/0.12),0_1px_3px_oklch(0_0_0/0.08)]">
<li class="flex items-center"><a href="#" class="relative overflow-hidden inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-primary no-underline transition-colors duration-200 hover:bg-[color-mix(in_oklab,var(--color-tbc08-primary)_8%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2 after:content-[''] after:absolute after:left-1/2 after:top-1/2 after:w-[160%] after:aspect-square after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:pointer-events-none after:scale-0 after:opacity-0 after:bg-[radial-gradient(circle,color-mix(in_oklab,var(--color-tbc08-primary)_40%,transparent),transparent_60%)] after:transition-[scale,opacity] after:duration-400 active:after:scale-100 active:after:opacity-100 active:after:duration-0 motion-reduce:after:hidden">Home</a></li>
<li class="flex items-center before:content-[''] before:w-4.5 before:h-4.5 before:mx-0.5 before:bg-tbc08-mut before:[mask-image:var(--tbc08-chev)] before:[mask-size:contain] before:[mask-position:center] before:[mask-repeat:no-repeat]"><a href="#" class="relative overflow-hidden inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-primary no-underline transition-colors duration-200 hover:bg-[color-mix(in_oklab,var(--color-tbc08-primary)_8%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2 after:content-[''] after:absolute after:left-1/2 after:top-1/2 after:w-[160%] after:aspect-square after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:pointer-events-none after:scale-0 after:opacity-0 after:bg-[radial-gradient(circle,color-mix(in_oklab,var(--color-tbc08-primary)_40%,transparent),transparent_60%)] after:transition-[scale,opacity] after:duration-400 active:after:scale-100 active:after:opacity-100 active:after:duration-0 motion-reduce:after:hidden">Materials</a></li>
<li class="flex items-center before:content-[''] before:w-4.5 before:h-4.5 before:mx-0.5 before:bg-tbc08-mut before:[mask-image:var(--tbc08-chev)] before:[mask-size:contain] before:[mask-position:center] before:[mask-repeat:no-repeat]"><a href="#" class="relative overflow-hidden inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-primary no-underline transition-colors duration-200 hover:bg-[color-mix(in_oklab,var(--color-tbc08-primary)_8%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2 after:content-[''] after:absolute after:left-1/2 after:top-1/2 after:w-[160%] after:aspect-square after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:pointer-events-none after:scale-0 after:opacity-0 after:bg-[radial-gradient(circle,color-mix(in_oklab,var(--color-tbc08-primary)_40%,transparent),transparent_60%)] after:transition-[scale,opacity] after:duration-400 active:after:scale-100 active:after:opacity-100 active:after:duration-0 motion-reduce:after:hidden">Components</a></li>
<li class="flex items-center before:content-[''] before:w-4.5 before:h-4.5 before:mx-0.5 before:bg-tbc08-mut before:[mask-image:var(--tbc08-chev)] before:[mask-size:contain] before:[mask-position:center] before:[mask-repeat:no-repeat]"><a href="#" aria-current="page" class="inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-on no-underline cursor-default focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2">Navigation</a></li>
</ol>
</nav>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tbc08-bg: #f6f6f9;
--color-tbc08-bg: oklch(0.97 0.004 265);
--color-tbc08-primary: #4d5fc0;
--color-tbc08-primary: oklch(0.5 0.15 265);
--color-tbc08-on: #52555c;
--color-tbc08-on: oklch(0.35 0.01 265);
--color-tbc08-mut: #8f9199;
--color-tbc08-mut: oklch(0.6 0.01 265);
--font-tbc08-sans: 'Roboto', system-ui, sans-serif;
}
/* Mask data-URI as a plain custom property: not a design-scale value, so it should
not mint utilities. */
.tbc-08 {
width: 100%;
min-height: 100svh;
--tbc08-chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 6l6 6-6 6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* Safari < 15.4 mask prefix. */
.tbc-08 li::before {
-webkit-mask: var(--tbc08-chev) center/contain no-repeat;
}
```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 Material Design Flat Breadcrumb Bar with Ink Ripple
Source: https://codefronts.com/navigation/tailwind-css-breadcrumbs/tailwind-material-design-flat-breadcrumb-ink-ripple/
Material's flat surface, type scale and state layers in utilities: an elevation-1 card, a masked chevron separator, a color-mix() hover layer, and an ink ripple that fires on :active from a radial-gradient pseudo-element — no ripple library, no JS.
## HTML
```html
<section class="tbc-08 w-full min-h-svh grid place-items-center bg-tbc08-bg font-tbc08-sans px-8 py-8">
<nav aria-label="Breadcrumb">
<ol class="inline-flex flex-wrap items-center list-none m-0 px-2 py-1.5 rounded-lg bg-white shadow-[0_1px_2px_oklch(0_0_0/0.12),0_1px_3px_oklch(0_0_0/0.08)]">
<li class="flex items-center"><a href="#" class="relative overflow-hidden inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-primary no-underline transition-colors duration-200 hover:bg-[color-mix(in_oklab,var(--color-tbc08-primary)_8%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2 after:content-[''] after:absolute after:left-1/2 after:top-1/2 after:w-[160%] after:aspect-square after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:pointer-events-none after:scale-0 after:opacity-0 after:bg-[radial-gradient(circle,color-mix(in_oklab,var(--color-tbc08-primary)_40%,transparent),transparent_60%)] after:transition-[scale,opacity] after:duration-400 active:after:scale-100 active:after:opacity-100 active:after:duration-0 motion-reduce:after:hidden">Home</a></li>
<li class="flex items-center before:content-[''] before:w-4.5 before:h-4.5 before:mx-0.5 before:bg-tbc08-mut before:[mask-image:var(--tbc08-chev)] before:[mask-size:contain] before:[mask-position:center] before:[mask-repeat:no-repeat]"><a href="#" class="relative overflow-hidden inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-primary no-underline transition-colors duration-200 hover:bg-[color-mix(in_oklab,var(--color-tbc08-primary)_8%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2 after:content-[''] after:absolute after:left-1/2 after:top-1/2 after:w-[160%] after:aspect-square after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:pointer-events-none after:scale-0 after:opacity-0 after:bg-[radial-gradient(circle,color-mix(in_oklab,var(--color-tbc08-primary)_40%,transparent),transparent_60%)] after:transition-[scale,opacity] after:duration-400 active:after:scale-100 active:after:opacity-100 active:after:duration-0 motion-reduce:after:hidden">Materials</a></li>
<li class="flex items-center before:content-[''] before:w-4.5 before:h-4.5 before:mx-0.5 before:bg-tbc08-mut before:[mask-image:var(--tbc08-chev)] before:[mask-size:contain] before:[mask-position:center] before:[mask-repeat:no-repeat]"><a href="#" class="relative overflow-hidden inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-primary no-underline transition-colors duration-200 hover:bg-[color-mix(in_oklab,var(--color-tbc08-primary)_8%,transparent)] focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2 after:content-[''] after:absolute after:left-1/2 after:top-1/2 after:w-[160%] after:aspect-square after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:pointer-events-none after:scale-0 after:opacity-0 after:bg-[radial-gradient(circle,color-mix(in_oklab,var(--color-tbc08-primary)_40%,transparent),transparent_60%)] after:transition-[scale,opacity] after:duration-400 active:after:scale-100 active:after:opacity-100 active:after:duration-0 motion-reduce:after:hidden">Components</a></li>
<li class="flex items-center before:content-[''] before:w-4.5 before:h-4.5 before:mx-0.5 before:bg-tbc08-mut before:[mask-image:var(--tbc08-chev)] before:[mask-size:contain] before:[mask-position:center] before:[mask-repeat:no-repeat]"><a href="#" aria-current="page" class="inline-flex items-center min-h-11 px-3.5 rounded-lg text-sm font-medium text-tbc08-on no-underline cursor-default focus-visible:outline-2 focus-visible:outline-tbc08-primary focus-visible:outline-offset-2">Navigation</a></li>
</ol>
</nav>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tbc08-bg: #f6f6f9;
--color-tbc08-bg: oklch(0.97 0.004 265);
--color-tbc08-primary: #4d5fc0;
--color-tbc08-primary: oklch(0.5 0.15 265);
--color-tbc08-on: #52555c;
--color-tbc08-on: oklch(0.35 0.01 265);
--color-tbc08-mut: #8f9199;
--color-tbc08-mut: oklch(0.6 0.01 265);
--font-tbc08-sans: 'Roboto', system-ui, sans-serif;
}
/* Mask data-URI as a plain custom property: not a design-scale value, so it should
not mint utilities. */
.tbc-08 {
width: 100%;
min-height: 100svh;
--tbc08-chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 6l6 6-6 6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* Safari < 15.4 mask prefix. */
.tbc-08 li::before {
-webkit-mask: var(--tbc08-chev) center/contain no-repeat;
}
```How this works
State layers are colour mixes, not opacities. Material tints by compositing the primary colour at a fixed percentage over the surface. color-mix(in oklab, var(--color-tbc08-primary) 8%, transparent) in an arbitrary bg-* is the exact expression of the spec, and it stays correct when the primary token changes.
The ripple is one pseudo-element and two variants. A 160%-wide radial gradient, centred and scaled to zero. On :active it snaps to full with duration-0 and then relaxes back over 400ms when released — the asymmetry is what makes it read as ink rather than a fade.
The separator is a mask. One chevron data-URI in a plain custom property, painted by four arbitrary mask utilities on before:. That keeps the glyph recolourable through before:bg-tbc08-mut and the markup free of repeated inline SVG.
Make it yours
- Primary colour:
--color-tbc08-primarydrives link ink, the 8% hover layer, the ripple gradient and the focus ring. - Ripple reach: the
after:w-[160%]and the gradient's 60% stop. - For a pointer-origin ripple, set
--x/--yonpointerdownand read them inafter:[left:var(--x)]— the only thing here that needs script.
Gotchas — read before shipping
- The link needs
relative overflow-hidden, or the ripple paints outside the rounded rectangle. active:after:duration-0is load-bearing: without it the ripple eases in and reads as a hover fade rather than a press.aria-currentcrumbs getcursor-defaultand no ripple — a press animation on the page you are already on is a false affordance.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
color-mix() is the gate (Baseline 2023) and is Tailwind v4's own floor anyway; masks need the -webkit- prefix on older Safari, which the stylesheet ships.