SolutionsCase StudiesAI ToolsResourcesAboutContact
Get Your Free AI Automation Audit Book a Free 30-Minute Strategy Call
Playground~/frontend Open editor

~/css/neumorphism

7 CSS Neumorphism

2 Pure CSS5 with JSPublished 2026-10-05Free · no sign-up

Seven soft UI components: raised buttons that press in, a switch with an inset track, a restyled range slider, a profile card with an inset avatar, a sunken search field, a rotary knob driven by a real range input and a neumorphic panel on a dark base.

01. Raised and Pressed Buttons

NeumorphismButton

Soft UI buttons that look pushed out of the background with a light shadow on the top left and a dark one on the bottom right, and pushed in when pressed with inset shadows. A darker text colour and a focus ring add the contrast the style lacks on its own.

View code
<div class="nm1"><button>Play</button><button aria-pressed="true">Shuffle</button></div>
.nm1 { display: flex; gap: 18px; padding: 24px; border-radius: 20px; background: #e6e9ef; }
.nm1 button { padding: 14px 22px; border: 0; border-radius: 14px; background: #e6e9ef; color: #2d3748; font: 700 14px Inter, system-ui, sans-serif; cursor: pointer; box-shadow: 6px 6px 12px #c4c8cf, -6px -6px 12px #ffffff; }
.nm1 button:active, .nm1 [aria-pressed=true] { box-shadow: inset 5px 5px 10px #c4c8cf, inset -5px -5px 10px #ffffff; color: #4338ca; }
.nm1 button:focus-visible { outline: 3px solid #6366f1; outline-offset: 3px; }
document.querySelectorAll('.nm1 [aria-pressed]').forEach(function (b) { b.onclick = function () { b.setAttribute('aria-pressed', b.getAttribute('aria-pressed') !== 'true'); }; });

02. Soft Toggle Switch

NeumorphismSwitch

A neumorphic switch: an inset track and a raised knob that slides across, with an accent dot that lights when on. The accent colour gives the on state a clear signal, since soft shadows alone are hard to read.

View code
<div class="nm2"><button role="switch" aria-checked="true" aria-label="Notifications"><span></span></button></div>
.nm2 { padding: 24px; border-radius: 20px; background: #e6e9ef; }
.nm2 button { position: relative; width: 74px; height: 38px; padding: 0; border: 0; border-radius: 19px; background: #e6e9ef; box-shadow: inset 4px 4px 8px #c4c8cf, inset -4px -4px 8px #fff; cursor: pointer; }
.nm2 span { position: absolute; top: 5px; left: 5px; width: 28px; height: 28px; border-radius: 50%; background: #e6e9ef; box-shadow: 3px 3px 6px #c4c8cf, -3px -3px 6px #fff; transition: transform .25s ease; }
.nm2 span::after { content: ""; position: absolute; inset: 10px; border-radius: 50%; background: #9ca3af; }
.nm2 [aria-checked=true] span { transform: translateX(36px); } .nm2 [aria-checked=true] span::after { background: #16a34a; }
.nm2 button:focus-visible { outline: 3px solid #6366f1; outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .nm2 span { transition: none; } }
var b = document.querySelector('.nm2 button');
b.onclick = function () { b.setAttribute('aria-checked', b.getAttribute('aria-checked') !== 'true'); };

03. Neumorphic Range Slider

NeumorphismRange

A native range input restyled with an inset groove and a raised round thumb. Styling the real input keeps keyboard, touch and screen reader support, and the visible value next to it adds the clarity soft UI needs.

View code
<div class="nm3"><label for="nm3r">Volume <output>60</output></label><input id="nm3r" type="range" min="0" max="100" value="60"></div>
.nm3 { display: grid; gap: 12px; width: 260px; max-width: 100%; padding: 22px; box-sizing: border-box; border-radius: 20px; background: #e6e9ef; font: 600 14px Inter, system-ui, sans-serif; color: #2d3748; }
.nm3 label { display: flex; justify-content: space-between; }
.nm3 input { -webkit-appearance: none; appearance: none; width: 100%; height: 14px; border-radius: 7px; background: #e6e9ef; box-shadow: inset 3px 3px 6px #c4c8cf, inset -3px -3px 6px #fff; }
.nm3 input::-webkit-slider-thumb { -webkit-appearance: none; width: 28px; height: 28px; border-radius: 50%; background: #e6e9ef; box-shadow: 3px 3px 6px #b8bcc4, -3px -3px 6px #fff; cursor: pointer; }
.nm3 input::-moz-range-thumb { width: 28px; height: 28px; border: 0; border-radius: 50%; background: #e6e9ef; box-shadow: 3px 3px 6px #b8bcc4, -3px -3px 6px #fff; cursor: pointer; }
.nm3 input:focus-visible { outline: 3px solid #6366f1; outline-offset: 6px; }
var r = document.getElementById('nm3r'), o = document.querySelector('.nm3 output');
r.oninput = function () { o.textContent = r.value; };

04. Soft UI Profile Card

NeumorphismCard

A raised card with an inset avatar well and soft buttons, the full neumorphic look. Text uses a darker slate rather than the mid grey common in this style, so the name and role pass contrast on the pale background.

View code
<article class="nm4"><span class="av" aria-hidden="true">LS</span><h3>Lena Sato</h3><p>Illustrator</p><button>Follow</button></article>
.nm4 { display: grid; justify-items: center; gap: 4px; width: 220px; max-width: 100%; padding: 24px; box-sizing: border-box; border-radius: 24px; background: #e6e9ef; box-shadow: 10px 10px 20px #c4c8cf, -10px -10px 20px #fff; font: 14px Inter, system-ui, sans-serif; }
.nm4 .av { display: grid; place-items: center; width: 72px; height: 72px; margin-bottom: 8px; border-radius: 50%; background: #e6e9ef; box-shadow: inset 4px 4px 8px #c4c8cf, inset -4px -4px 8px #fff; color: #4338ca; font-weight: 800; }
.nm4 h3 { margin: 0; color: #1f2937; } .nm4 p { margin: 0 0 12px; color: #4b5563; }
.nm4 button { padding: 10px 22px; border: 0; border-radius: 12px; background: #e6e9ef; color: #312e81; font: 700 14px Inter, system-ui, sans-serif; box-shadow: 4px 4px 8px #c4c8cf, -4px -4px 8px #fff; cursor: pointer; }
.nm4 button:active { box-shadow: inset 3px 3px 6px #c4c8cf, inset -3px -3px 6px #fff; }
.nm4 button:focus-visible { outline: 3px solid #6366f1; outline-offset: 3px; }

05. Inset Search Field

NeumorphismInput

A search field pressed into the surface with inset shadows, with a visible label and an icon. Because inset fields can look disabled, the focus state adds an accent ring and the placeholder is dark enough to read.

View code
<div class="nm5"><label for="nm5q">Search recipes</label><div class="f"><span aria-hidden="true">⌕</span><input id="nm5q" type="search" placeholder="e.g. lentil soup"></div></div>
.nm5 { display: grid; gap: 8px; width: 280px; max-width: 100%; padding: 22px; box-sizing: border-box; border-radius: 20px; background: #e6e9ef; font: 14px Inter, system-ui, sans-serif; }
.nm5 label { color: #1f2937; font-weight: 700; }
.nm5 .f { display: flex; align-items: center; gap: 8px; padding: 0 14px; border-radius: 14px; background: #e6e9ef; box-shadow: inset 4px 4px 8px #c4c8cf, inset -4px -4px 8px #fff; }
.nm5 .f:focus-within { box-shadow: inset 4px 4px 8px #c4c8cf, inset -4px -4px 8px #fff, 0 0 0 3px #6366f1; }
.nm5 span { color: #4b5563; font-size: 18px; }
.nm5 input { flex: 1; min-width: 0; padding: 12px 0; border: 0; background: transparent; color: #1f2937; font: inherit; }
.nm5 input::placeholder { color: #6b7280; } .nm5 input:focus { outline: none; }

06. Rotary Knob

NeumorphismControl

A raised round knob with a pointer that turns as the value changes, the kind used for audio and smart home controls. A visually hidden range input does the work, so arrow keys and screen readers operate it, while the knob is only its picture.

View code
<div class="nm6"><div class="knob" aria-hidden="true"><span></span></div><label for="nm6r">Temperature <output>21</output>°C</label><input id="nm6r" type="range" min="16" max="28" value="21"></div>
.nm6 { display: grid; justify-items: center; gap: 12px; padding: 22px; border-radius: 22px; background: #e6e9ef; font: 600 14px Inter, system-ui, sans-serif; color: #1f2937; }
.nm6 .knob { --a: 0deg; position: relative; width: 110px; height: 110px; border-radius: 50%; background: linear-gradient(145deg, #f2f4f8, #d1d5db); box-shadow: 8px 8px 16px #c4c8cf, -8px -8px 16px #fff; transform: rotate(var(--a)); transition: transform .2s; }
.nm6 .knob span { position: absolute; left: 50%; top: 10px; width: 4px; height: 18px; margin-left: -2px; border-radius: 2px; background: #ea580c; }
.nm6 input { width: 160px; accent-color: #ea580c; }
.nm6 input:focus-visible { outline: 3px solid #6366f1; outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) { .nm6 .knob { transition: none; } }
var r = document.getElementById('nm6r'), k = document.querySelector('.nm6 .knob'), o = document.querySelector('.nm6 output');
function set() { k.style.setProperty('--a', ((r.value - 22) * 22) + 'deg'); o.textContent = r.value; }
r.oninput = set; set();

07. Dark Neumorphic Panel

NeumorphismDark

Neumorphism on a dark base: the light shadow becomes a slightly lighter shade of the background and the dark shadow nearly black. Dark soft UI has even less contrast, so the active control also gets a coloured icon and label.

View code
<div class="nm7"><button aria-pressed="true"><span aria-hidden="true">☀</span>Lights</button><button aria-pressed="false"><span aria-hidden="true">♨</span>Heating</button></div>
.nm7 { display: flex; gap: 16px; padding: 24px; border-radius: 22px; background: #1e2230; }
.nm7 button { display: grid; justify-items: center; gap: 6px; width: 96px; padding: 16px 0; border: 0; border-radius: 18px; background: #1e2230; color: #9aa3b8; font: 600 13px Inter, system-ui, sans-serif; box-shadow: 6px 6px 12px #13161f, -6px -6px 12px #292e41; cursor: pointer; }
.nm7 span { font-size: 22px; }
.nm7 [aria-pressed=true] { color: #fde68a; box-shadow: inset 5px 5px 10px #13161f, inset -5px -5px 10px #292e41; }
.nm7 button:focus-visible { outline: 2px solid #a5b4fc; outline-offset: 3px; }
document.querySelectorAll('.nm7 button').forEach(function (b) { b.onclick = function () { b.setAttribute('aria-pressed', b.getAttribute('aria-pressed') !== 'true'); }; });

About these CSS Neumorphism

Two shadows, one background

Neumorphism uses a light shadow toward the light source and a dark shadow away from it, on an element the same colour as its background. Inset versions of the same shadows make an element look pressed in.

Contrast is the weak point

Soft UI often has pale grey text and controls that barely stand out. Use darker text, an accent colour for active states and strong focus rings so it stays usable.

Style real controls

Restyle native inputs and buttons rather than building lookalikes. The range slider and knob here are real range inputs underneath, so keyboards and screen readers work.

Use it sparingly

Neumorphism suits a few tactile controls, such as a music player or smart home panel. A whole site in soft UI quickly becomes hard to scan.

Frequently asked questions

Is neumorphism accessible?

Only with extra contrast and clear states, as these demos add.

Does it work in dark mode?

Yes, with a lighter shade for the highlight and near black for the shadow, as the last demo shows.

Which colours work best?

Light, slightly tinted greys; pure white leaves no room for the highlight shadow.