Skip to content

Neumorphism in 2026: The Dual-Shadow Recipe for Soft UI in WordPress

Key Takeaways

  • Neumorphism uses two mirrored box-shadows on one element: a dark shadow offset one way and a light shadow offset the opposite way, such as 8px 8px 16px #bebebe paired with -8px -8px 16px #ffffff.
  • The element background must match the parent background exactly. The effect collapses on white, black, gradients and images, because the light shadow needs a surface darker than itself to be visible.
  • Pressed states flip both shadows to inset. Tying that state to [aria-pressed="true"] as well as :active keeps a toggle button visually in sync with its ARIA semantics.
  • A neumorphic switch pairs an inset track with an outset knob, built on a real checkbox input so it stays keyboard operable and screen-reader friendly without JavaScript.
  • Every common neumorphic palette fails WCAG Success Criterion 1.4.11, which requires 3:1 for UI component boundaries. The best case measured is 1.86:1, so the shadow must be treated as decoration and paired with a text label, a visible focus ring and a non-positional state indicator.

A designer sent me a Figma file last spring with twelve soft, pillowy buttons on a light grey board and asked why they looked flat the moment they hit the staging site. The CSS had been copied correctly. The shadows were there. What had changed was the section background: the developer had dropped the buttons into a container with a white background, and the entire illusion collapsed. Neumorphism is one of the few UI styles where the element and the thing behind it have to agree, and almost every broken implementation I have looked at since traces back to that one rule.

Table Of Contents

What Neumorphism Actually Is

Neumorphism, sometimes written as soft UI, makes an element look like it was pushed up from underneath the surface rather than dropped on top of it. There is no floating card and no separate panel. The button appears to be made of the same material as the page, extruded slightly.

That effect comes from a single idea: real objects lit from one direction cast a shadow on one side and catch a highlight on the other. So instead of one shadow, you use two, pointing in opposite directions. One is darker than the background, one is lighter, and both sit on the same element.

This puts it in a different family from the other soft styles. Glassmorphism simulates a frosted pane floating above a busy background and depends on blur. Claymorphism uses a three shadow stack to make chunky, rounded, toy-like objects. Neumorphism does neither. It flattens everything into one continuous surface and uses light alone to suggest depth.

The Dual-Shadow Recipe

Here is the complete effect. Everything else in this article is a variation on these four lines.

.neu-card {
  background: #e0e0e0;          /* must match the parent */
  border-radius: 20px;
  box-shadow:
     8px  8px 16px #bebebe,     /* dark, bottom right */
    -8px -8px 16px #ffffff;     /* light, top left */
}

Per the MDN box-shadow reference, each shadow reads as offset-x, offset-y, blur-radius, spread-radius, then color, with the length values interpreted in that order. In the snippet above there is no spread, so the three numbers are horizontal offset, vertical offset, and blur.

Three constraints make or break it:

  1. The offsets must mirror each other. If the dark shadow is 8px 8px, the light one has to be -8px -8px. Break the symmetry and the light source becomes incoherent, which reads as a smudge rather than a raised surface.
  2. The element background must match the parent background. Not approximately. Exactly. The moment they differ, the eye sees an edge, and an edge means a separate object sitting on top, which is the opposite of what the style is for.
  3. The shadow colors are derived from the background, not picked. Take the base color and lighten it about 10 to 12 percent for the highlight, darken it by the same amount for the shadow. On #e0e0e0 that lands you near #ffffff and #bebebe.

MDN also notes that with multiple comma-separated shadows, the first one specified is painted on top. That rarely matters when the offsets are symmetrical, but it starts to matter the moment you add a third shadow or use large spread values that overlap.

Why It Breaks on White (and on Images)

This is the failure I opened with, and it is worth being precise about the cause.

The highlight shadow is lighter than the background. If the background is already #ffffff, there is no lighter color available. The highlight renders as white on white, which is nothing at all, and you are left with a plain drop shadow on the bottom right. The button does not look extruded. It looks like a normal card with a slightly odd shadow.

The same logic rules out pure black backgrounds in the other direction, and it rules out photographic or gradient backgrounds entirely. A gradient parent means the color behind the element changes across its width, so a single flat element background cannot match it everywhere. You get a visible rectangle.

Practically, neumorphism needs a mid-tone, flat, solid background. Light grey around #e0e0e0 is the usual choice. Dark mode works too, around #2e3440, but with a caveat covered further down.

Pressed States: Flipping the Shadows Inward

The reason neumorphism works well for controls is that it has a natural pressed state. Add the inset keyword to both shadows and the element appears to sink into the surface.

.neu-button {
  background: #e0e0e0;
  border: none;
  border-radius: 16px;
  padding: 16px 28px;
  box-shadow:
     6px  6px 12px #bebebe,
    -6px -6px 12px #ffffff;
  transition: box-shadow .18s ease;
}

.neu-button:active,
.neu-button[aria-pressed="true"] {
  box-shadow:
    inset  6px  6px 12px #bebebe,
    inset -6px -6px 12px #ffffff;
}

MDN describes inset as changing the shadow from an outer box-shadow to an inner one, as if the content is pressed into the box, and notes that inset shadows are clipped to the padding box. That clipping is why the pressed state stays crisp at the corners instead of bleeding outward.

Note the aria-pressed selector alongside :active. A toggle button that only changes on :active looks pressed while the mouse is held down and then springs back, which is wrong for anything that holds state. Tying the inset state to the ARIA attribute keeps the visual and the semantics in sync.

Building a Neumorphic Switch

The switch is the component people search for most in this style, and it is a genuinely good fit, because a physical switch really does sit in a recessed track.

The construction is two parts with opposite shadow directions. The track is inset, so it reads as a groove cut into the surface. The knob is outset, so it reads as a raised object sitting in that groove.

.neu-switch {
  position: relative;
  width: 84px;
  height: 44px;
  border-radius: 22px;
  background: #e0e0e0;
  box-shadow:
    inset  4px  4px  8px #bebebe,
    inset -4px -4px  8px #ffffff;
}

.neu-switch .knob {
  position: absolute;
  top: 5px;
  left: 5px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: #e0e0e0;
  box-shadow:
     4px  4px  8px #bebebe,
    -4px -4px  8px #ffffff;
  transition: transform .22s ease;
}

.neu-switch input:checked ~ .knob {
  transform: translateX(40px);
}

Build this on top of a real checkbox input rather than a styled div. Visually hide the input, keep it focusable, and drive the knob from :checked. That gives you keyboard operation and screen reader semantics without writing any JavaScript.

There is a real problem here that the next section deals with directly: in the snippet above, the on state and the off state differ only by the knob’s position. There is no color change, no label change, and no contrast change. For a significant number of users that is not a detectable difference.

The Accessibility Problem, With Numbers

Neumorphism has a structural accessibility issue, and it is not a matter of taste or careful color picking. It follows from the definition of the style.

WCAG Success Criterion 1.4.11 Non-text Contrast, Level AA, requires that visual information required to identify user interface components and states have a contrast ratio of at least 3:1 against adjacent colors. A button’s boundary is exactly that kind of information.

In neumorphism, the only thing marking the boundary is the shadow. And the shadow is derived from the background by design, which caps how different it can be. Running the WCAG contrast formula over the palettes in common use gives this:

Palette pairColorsRatio1.4.11 (needs 3:1)
Classic base vs dark shadow#e0e0e0 / #bebebe1.41:1Fail
Classic base vs light shadow#e0e0e0 / #ffffff1.32:1Fail
Dark shadow vs light shadow#bebebe / #ffffff1.86:1Fail
Blue-grey variant#e0e0e0 / #a3b1c61.65:1Fail
Dark mode, light edge#2e3440 / #3b42521.24:1Fail
Dark mode, dark edge#2e3440 / #23272f1.20:1Fail
Contrast ratios computed with the WCAG relative luminance formula. The best case across every common neumorphic palette is 1.86:1, against a 3:1 requirement.

Every one fails, and the best case is barely above half the required ratio. This is not a palette that was chosen badly. Push the shadows far enough apart to reach 3:1 and they stop reading as shadows on a shared surface, which means you are no longer building neumorphism.

So treat the shadow as decoration and give every interactive element a second, compliant signal:

  • A text label with normal body-text contrast, which is governed by 1.4.3 and unaffected by the shadow work.
  • A visible focus ring that does meet 3:1. Do not remove the default outline without replacing it.
  • A state indicator that is not purely positional. On the switch above, add a color fill or a check glyph to the on state.
  • A real border on form inputs, where the boundary carries meaning rather than style.

Used that way the style is defensible. Used as the sole indicator of what is clickable, it is not.

Neumorphism vs Claymorphism vs Glassmorphism

AspectNeumorphismClaymorphismGlassmorphism
Core mechanicTwo mirrored shadowsThree stacked shadowsBackdrop blur plus transparency
Background neededFlat mid-tone, must matchAny solid, usually colorfulBusy or colorful, must show through
Reads asExtruded from the surfaceSoft 3D object on the surfaceFrosted pane above the surface
Boundary contrastStructurally weakWorkableDepends on what is behind
Render costLowLowHigher, blur is expensive
The three soft UI styles compared by mechanic, background requirement, and the practical constraints each one imposes.

Neumorphism is the cheapest of the three to render, since box-shadow costs far less than backdrop-filter. If you are already watching paint cost on a heavy page, that matters. Our notes on Elementor Core Web Vitals go into where those costs actually show up.

Building It in Elementor

Elementor’s box shadow control exposes horizontal offset, vertical offset, blur, spread, and color, but it gives you one shadow per element. Neumorphism needs two. There are two practical routes.

Custom CSS on the widget. Give the container a class and write the full two-shadow declaration in the Custom CSS panel. This is the honest approach for the effect and takes about a minute per component. Define the base color once as a global color so the shadow derivation stays consistent.

Nested containers. Put an inner container inside an outer one, apply the dark shadow to one and the light shadow to the other. This keeps everything inside the visual editor, at the cost of an extra DOM node per component. Reasonable for a handful of hero elements, not for a component library.

Whichever route you take, set the section background and the widget background to the same global color rather than typing the hex twice. The single most common way this effect breaks in a page builder is that someone updates the section background later and the elements inside it are left behind. Building a reusable design system in Elementor V4 covers the class and variable setup that prevents exactly this drift.

The Plus Addons for Elementor is useful here mostly for the hover and interaction layer rather than the shadows themselves. The pressed and hover transitions are what make a soft UI feel physical, and getting those consistent across a set of widgets is more work than the base shadow. Our guide to CSS hover effects in Elementor covers that side.

When to Use It, and When Not To

Neumorphism works when the interface is small, self-contained, and the controls are obviously controls from context. Media players, thermostat and smart home dashboards, calculators, audio interfaces, and settings panels all fit, because the user already knows a dial is a dial.

It works badly for anything where discovery matters. Marketing pages, checkout flows, forms filled in by first-time visitors, and dense content pages all depend on the user finding the interactive element quickly, and a 1.4:1 boundary does not support that. It also does not survive a mixed background, which rules out most page templates that alternate section colors.

The most successful use I have seen treats it as a texture for one section rather than a whole design language. A neumorphic settings card on an otherwise conventional page gives you the tactile quality without asking the entire site to live under its constraints.

Frequently Asked Questions

Why Does My Neumorphic Button Look Flat?

Almost always because the parent background is white or does not match the element background. The light shadow needs a background darker than itself to be visible. Move the component onto a mid-tone surface such as #e0e0e0 and set the element background to the identical value.

Can Neumorphism Be Made Accessible?

The shadow boundary itself cannot reach the 3:1 required by WCAG 1.4.11 without ceasing to look like neumorphism. The style can still be used accessibly by treating the shadow as decoration and carrying identification through a compliant text label, a visible focus ring, and a non-positional state indicator.

Does Neumorphism Work in Dark Mode?

Yes, with a base around #2e3440 and shadows lightened and darkened from it. The contrast picture is slightly worse than in light mode, since the ratios compress at the dark end. Our measurements put a typical dark palette at 1.20:1 to 1.24:1 against 1.41:1 for the light equivalent.

Is Neumorphism Bad for Performance?

No. It is the cheapest of the soft UI styles because box-shadow does not force the compositing work that backdrop-filter does. Animating box-shadow on many elements at once can cost more than animating transform, so drive motion with transforms where you can.

What Background Color Should I Use?

A flat mid-tone. Light grey near #e0e0e0 is the default. Avoid pure white, pure black, gradients, and images, since all four remove the room the paired shadows need to work in.

Suggested Reading

Related Frequently Asked Questions

Why does a neumorphic button look flat on a white background?

White kills the highlight side of neumorphism. The style depends on one shadow being lighter than the surface and the other being darker, so if the parent is already #ffffff, the light shadow disappears and the effect collapses into a normal card with a weird shadow. A mid-tone flat background like #e0e0e0 keeps both shadows visible and preserves the extruded look.

What background color works best for neumorphism in WordPress?

A flat mid-tone is the safest choice, and the page uses light grey around #e0e0e0 as the default. That gives the paired shadows room to read as light and dark edges instead of separate objects. Pure white, pure black, gradients, and images all break the illusion because the element can no longer match what is behind it everywhere.

Can neumorphism be made accessible for buttons and toggles?

The shadow boundary itself cannot meet WCAG 1.4.11 at 3:1 without stopping looking like neumorphism. The practical fix is to treat the shadow as decoration and add a real text label, a visible focus ring that also meets 3:1, and a state indicator that is not purely positional. The page also calls out using aria-pressed for pressed states so visuals and semantics stay aligned.

Does neumorphism work in dark mode?

It works in dark mode, but the contrast gets tighter. The page uses a base around #2e3440 with lighter and darker shadows derived from it, but notes that typical dark palettes land around 1.20:1 to 1.24:1, which is even weaker than the light-mode example at 1.41:1. That means dark mode can keep the look, but it makes accessibility even harder.

Is neumorphism bad for performance compared with glassmorphism?

Neumorphism is cheaper to render because it relies on box-shadow, while glassmorphism depends on backdrop-filter and blur, which costs more. The tradeoff is that animating box-shadow on many elements can still be heavier than animating transform. For motion, transform is the safer choice; for static UI texture, neumorphism stays relatively light.

How do you build neumorphism in Elementor without losing consistency?

Elementor’s box shadow control only gives one shadow per element, so neumorphism needs either custom CSS or nested containers. Custom CSS on a widget is the cleanest route because it lets you define both mirrored shadows directly; nested containers keep everything in the visual editor but add an extra DOM node per component. The bigger gotcha is drift, so set both section and widget backgrounds from the same global color.

Last reviewed: September 2, 2026