39 CSS Breadcrumbs16 / 39
Neumorphic Soft Inset-Shadow CSS Breadcrumbs
A neumorphic breadcrumb where the whole trail sits in a soft pressed 'channel' carved into the surface, and each crumb is a subtle inset well — the tactile soft-UI treatment focused on inset shadows (the counterpart to demo 10's extruded nodes). The current crumb rises as the one raised node in the groove.
Published
The code
<nav class="bc-16" aria-label="Breadcrumb">
<ol>
<li><a href="#">Home</a></li>
<li><a href="#">Devices</a></li>
<li><a href="#">Thermostat</a></li>
<li><a href="#" aria-current="page">Schedule</a></li>
</ol>
</nav><nav class="bc-16" aria-label="Breadcrumb">
<ol>
<li><a href="#">Home</a></li>
<li><a href="#">Devices</a></li>
<li><a href="#">Thermostat</a></li>
<li><a href="#" aria-current="page">Schedule</a></li>
</ol>
</nav>.bc-16 {
display: grid;
width: 100%;
min-height: 100vh;
--surface: oklch(0.9 0.008 250);
--dark: oklch(0.78 0.015 250);
--light: oklch(0.99 0.004 250);
--accent: oklch(0.5 0.15 260);
font-family: system-ui,'Segoe UI',sans-serif;
padding: 38px 30px;
background: var(--surface);
place-items: center;
}
.bc-16 * {
box-sizing: border-box;
}
.bc-16 ol {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
list-style: none;
margin: 0;
padding: 10px 14px;
border-radius: 16px;
background: var(--surface);
box-shadow: inset 5px 5px 10px var(--dark),inset -5px -5px 10px var(--light);
}
.bc-16 li {
display: flex;
align-items: center;
}
.bc-16 li:not(:last-child)::after {
content: "›";
margin: 0 6px;
color: oklch(0.62 0.01 250);
}
.bc-16 a {
display: inline-block;
padding: 8px 14px;
border-radius: 11px;
font: 600 13px/1 system-ui,sans-serif;
color: var(--accent);
text-decoration: none;
transition: box-shadow .2s ease,color .2s ease;
}
.bc-16 a:hover {
box-shadow: inset 2px 2px 5px var(--dark),inset -2px -2px 5px var(--light);
}
.bc-16 a:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.bc-16 li[aria-current="page"] a {
color: oklch(0.38 0.03 250);
box-shadow: 5px 5px 10px var(--dark),-5px -5px 10px var(--light);
}
@media (prefers-reduced-motion: reduce) {
.bc-16 a {
transition: none;
}
}.bc-16 {
display: grid;
width: 100%;
min-height: 100vh;
--surface: oklch(0.9 0.008 250);
--dark: oklch(0.78 0.015 250);
--light: oklch(0.99 0.004 250);
--accent: oklch(0.5 0.15 260);
font-family: system-ui,'Segoe UI',sans-serif;
padding: 38px 30px;
background: var(--surface);
place-items: center;
}
.bc-16 * {
box-sizing: border-box;
}
.bc-16 ol {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
list-style: none;
margin: 0;
padding: 10px 14px;
border-radius: 16px;
background: var(--surface);
box-shadow: inset 5px 5px 10px var(--dark),inset -5px -5px 10px var(--light);
}
.bc-16 li {
display: flex;
align-items: center;
}
.bc-16 li:not(:last-child)::after {
content: "›";
margin: 0 6px;
color: oklch(0.62 0.01 250);
}
.bc-16 a {
display: inline-block;
padding: 8px 14px;
border-radius: 11px;
font: 600 13px/1 system-ui,sans-serif;
color: var(--accent);
text-decoration: none;
transition: box-shadow .2s ease,color .2s ease;
}
.bc-16 a:hover {
box-shadow: inset 2px 2px 5px var(--dark),inset -2px -2px 5px var(--light);
}
.bc-16 a:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.bc-16 li[aria-current="page"] a {
color: oklch(0.38 0.03 250);
box-shadow: 5px 5px 10px var(--dark),-5px -5px 10px var(--light);
}
@media (prefers-reduced-motion: reduce) {
.bc-16 a {
transition: none;
}
}/* No JavaScript — the trail sits in an inset soft-UI channel; hover gives a crumb its own well and the current page is the one raised node popping out of the groove. */
/* No JavaScript — the trail sits in an inset soft-UI channel; hover gives a crumb its own well and the current page is the one raised node popping out of the groove. */Here's a working CSS Breadcrumb 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: Neumorphic Soft Inset-Shadow CSS Breadcrumbs
Source: https://codefronts.com/navigation/css-breadcrumbs/neumorphic-soft-inset-shadow-css-breadcrumbs/
A neumorphic breadcrumb where the whole trail sits in a soft pressed 'channel' carved into the surface, and each crumb is a subtle inset well — the tactile soft-UI treatment focused on inset shadows (the counterpart to demo 10's extruded nodes). The current crumb rises as the one raised node in the groove.
## HTML
```html
<nav class="bc-16" aria-label="Breadcrumb">
<ol>
<li><a href="#">Home</a></li>
<li><a href="#">Devices</a></li>
<li><a href="#">Thermostat</a></li>
<li><a href="#" aria-current="page">Schedule</a></li>
</ol>
</nav>
```
## CSS
```css
.bc-16 {
display: grid;
width: 100%;
min-height: 100vh;
--surface: oklch(0.9 0.008 250);
--dark: oklch(0.78 0.015 250);
--light: oklch(0.99 0.004 250);
--accent: oklch(0.5 0.15 260);
font-family: system-ui,'Segoe UI',sans-serif;
padding: 38px 30px;
background: var(--surface);
place-items: center;
}
.bc-16 * {
box-sizing: border-box;
}
.bc-16 ol {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
list-style: none;
margin: 0;
padding: 10px 14px;
border-radius: 16px;
background: var(--surface);
box-shadow: inset 5px 5px 10px var(--dark),inset -5px -5px 10px var(--light);
}
.bc-16 li {
display: flex;
align-items: center;
}
.bc-16 li:not(:last-child)::after {
content: "›";
margin: 0 6px;
color: oklch(0.62 0.01 250);
}
.bc-16 a {
display: inline-block;
padding: 8px 14px;
border-radius: 11px;
font: 600 13px/1 system-ui,sans-serif;
color: var(--accent);
text-decoration: none;
transition: box-shadow .2s ease,color .2s ease;
}
.bc-16 a:hover {
box-shadow: inset 2px 2px 5px var(--dark),inset -2px -2px 5px var(--light);
}
.bc-16 a:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.bc-16 li[aria-current="page"] a {
color: oklch(0.38 0.03 250);
box-shadow: 5px 5px 10px var(--dark),-5px -5px 10px var(--light);
}
@media (prefers-reduced-motion: reduce) {
.bc-16 a {
transition: none;
}
}
```
## JavaScript
```js
/* No JavaScript — the trail sits in an inset soft-UI channel; hover gives a crumb its own well and the current page is the one raised node popping out of the groove. */
```Here's a working CSS Breadcrumb 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: Neumorphic Soft Inset-Shadow CSS Breadcrumbs
Source: https://codefronts.com/navigation/css-breadcrumbs/neumorphic-soft-inset-shadow-css-breadcrumbs/
A neumorphic breadcrumb where the whole trail sits in a soft pressed 'channel' carved into the surface, and each crumb is a subtle inset well — the tactile soft-UI treatment focused on inset shadows (the counterpart to demo 10's extruded nodes). The current crumb rises as the one raised node in the groove.
## HTML
```html
<nav class="bc-16" aria-label="Breadcrumb">
<ol>
<li><a href="#">Home</a></li>
<li><a href="#">Devices</a></li>
<li><a href="#">Thermostat</a></li>
<li><a href="#" aria-current="page">Schedule</a></li>
</ol>
</nav>
```
## CSS
```css
.bc-16 {
display: grid;
width: 100%;
min-height: 100vh;
--surface: oklch(0.9 0.008 250);
--dark: oklch(0.78 0.015 250);
--light: oklch(0.99 0.004 250);
--accent: oklch(0.5 0.15 260);
font-family: system-ui,'Segoe UI',sans-serif;
padding: 38px 30px;
background: var(--surface);
place-items: center;
}
.bc-16 * {
box-sizing: border-box;
}
.bc-16 ol {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
list-style: none;
margin: 0;
padding: 10px 14px;
border-radius: 16px;
background: var(--surface);
box-shadow: inset 5px 5px 10px var(--dark),inset -5px -5px 10px var(--light);
}
.bc-16 li {
display: flex;
align-items: center;
}
.bc-16 li:not(:last-child)::after {
content: "›";
margin: 0 6px;
color: oklch(0.62 0.01 250);
}
.bc-16 a {
display: inline-block;
padding: 8px 14px;
border-radius: 11px;
font: 600 13px/1 system-ui,sans-serif;
color: var(--accent);
text-decoration: none;
transition: box-shadow .2s ease,color .2s ease;
}
.bc-16 a:hover {
box-shadow: inset 2px 2px 5px var(--dark),inset -2px -2px 5px var(--light);
}
.bc-16 a:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.bc-16 li[aria-current="page"] a {
color: oklch(0.38 0.03 250);
box-shadow: 5px 5px 10px var(--dark),-5px -5px 10px var(--light);
}
@media (prefers-reduced-motion: reduce) {
.bc-16 a {
transition: none;
}
}
```
## JavaScript
```js
/* No JavaScript — the trail sits in an inset soft-UI channel; hover gives a crumb its own well and the current page is the one raised node popping out of the groove. */
```How this works
Demo 10 extruded nodes outward; this one presses inward. The bar container is an inset well — box-shadow:inset 5px 5px 10px var(--dark), inset -5px -5px 10px var(--light) — a soft channel recessed into the same-colour surface. Crumbs sit in that groove as flat text; the surface, well and crumbs share one --surface tone, and depth is entirely light-modelled. Hover gives a crumb its own faint inset well; the effect is of buttons set into a control panel.
The current page inverts the local physics: it's the one raised node in the recessed channel (box-shadow:5px 5px 10px var(--dark), -5px -5px 10px var(--light)), so 'you are here' pops out of the groove — the strongest soft-UI contrast available in a single surface colour. The same accessibility discipline as demo 10 applies: text uses a genuinely darker accent (never tone-on-tone), and focus is a solid accent ring, because soft shadows alone can't carry meaning for low-vision or colour-blind users.
Make it yours
- Well depth = inset shadow offset/blur; deeper reads as a more pronounced channel.
- Derive
--dark/--lightfrom--surfacewithcolor-mix()so one edit re-tunes the lighting. - Combine inset well + raised current for a control-panel feel, or make every crumb a small well for a keypad look.
- Warm the surface (slightly warm mid-tone) for a more physical, less clinical soft-UI.
Gotchas — read before shipping
- Same contrast trap as all neumorphism — tone-on-tone text fails WCAG; keep link text a real darker/accent colour.
- Element and background must share the exact surface colour or the inset illusion breaks into a plain shadow.
- Inset shadows need enough blur to read as a well; too tight looks like a border.
- Never rely on raised-vs-pressed alone for current page — pair with
aria-currentand a weight change.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 15.4+ | 113+ | 111+ |
Floor set by oklch() as this demo is written. The core technique itself goes back further — Chrome all.
inset/outset box-shadow is universal; color-mix() (2023) is optional sugar for deriving shadow tones. The look works anywhere.