Neumorphism is the look where a button or card seems to be pressed out of the page itself, like a shape molded from soft plastic. There is no border, no fill color that differs from the background, just a pale highlight on one side and a soft shadow on the other. It photographs beautifully in design mockups. In a real interface it is easy to get wrong in two ways: the effect disappears, or the controls become hard to see.
Both problems come down to a small amount of arithmetic about colors and shadows. This guide explains how the soft UI effect is built from two box-shadow layers, how the light and dark shades are derived from one surface color, what the flat, concave, convex and pressed shapes change, and how to keep a neumorphic interface usable under the WCAG contrast rules. The CSS Neumorphism Generator produces all of the code below with a live preview.
TL;DR: A neumorphic element has the same background color as the page and two box-shadows: a darker one offset down and right, and a lighter one offset up and left. Using the inset keyword on both makes the element look pressed. The CSS Neumorphism Generator derives both shadow colors from your surface color, with sliders for distance (2 to 50 px), blur (0 to 100 px), intensity (2 to 40%) and radius (0 to 80 px), plus flat, concave, convex and pressed shapes. The default light surface gives
box-shadow: 12px 12px 24px #bababa, -12px -12px 24px #ffffff. Those shadows reach only about 1.5:1 contrast against the surface, well under the 3:1 WCAG asks for on control boundaries, so interactive elements need a visible border or focus state. It is client-side, free, no signup.
What is neumorphism in UI design?
Neumorphism, also called soft UI, is a visual style in which interface elements appear extruded from or pressed into their background using paired light and dark shadows instead of borders or contrasting fills. The name blends "new" and "skeuomorphism", the older style that imitated physical materials. Neumorphism imitates one material, a single continuous surface, and relies on an imagined light source at the top left.
The style became popular on design showcase sites around 2020. It is well suited to decorative panels, dashboards viewed on good screens and one-off hero graphics. It is poorly suited to dense forms, anything used outdoors, and any control a user must find quickly, for reasons covered in the accessibility section.
How does the neumorphic effect work in CSS?
The effect needs three things: a background color on the element that matches the page, a border radius, and two shadows cast in opposite directions. The CSS box-shadow property accepts a comma-separated list of shadows, each with an x offset, a y offset, a blur radius and a color, as documented on MDN's box-shadow reference and specified in CSS Backgrounds and Borders Level 3.
Here is the output of the generator's default Light preset:
border-radius: 24px;
background: #e0e0e0;
box-shadow: 12px 12px 24px #bababa, -12px -12px 24px #ffffff;
Read the shadow list left to right. The first shadow is offset 12 pixels right and 12 down, blurred over 24 pixels, in a gray darker than the surface: that is the shade on the side away from the light. The second is offset 12 pixels left and 12 up in a color lighter than the surface: the highlight on the side facing the light. Because the element's own background is the same #e0e0e0 as the page, there is no visible edge. The shape exists only as the boundary where the two shadows meet.
Why does my neumorphism effect not show up?
The most common cause is a mismatch between the element's background and whatever is behind it. If the page is white and the card is #e0e0e0, you see a gray card with a shadow, not a soft extrusion. Set the parent's background to the same color as the element. The generator's preview panel does this automatically, which is why it looks right there and wrong when pasted onto a white page.
The second cause is a highlight color that cannot be seen. On a very light surface the "light" shadow may already be pure white, and on a pure white page a white shadow is invisible. That is also why neumorphism is almost never done on #ffffff.
How are the light and dark shadow colors calculated?
The generator shifts each red, green and blue channel of the surface color by the same amount: the intensity percentage of 255. The light shade adds that amount and the dark shade subtracts it, and each channel is clamped to the 0 to 255 range and rounded.
Here is the calculation for the default Light preset, surface #e0e0e0 (224, 224, 224) at 15% intensity:
- Shift amount: 15% of 255 = 38.25.
- Dark shade: 224 - 38.25 = 185.75, rounded to 186, which is hex
ba. Result:#bababa. - Light shade: 224 + 38.25 = 262.25, clamped to 255, hex
ff. Result:#ffffff.
Step 3 shows a limit worth knowing. On #e0e0e0 the highlight hits pure white once intensity passes (255 - 224) / 255 = 12.2%. Any intensity above that makes the shadow darker without making the highlight any brighter, so the effect becomes lopsided. On light surfaces, keep intensity near that clamp point, or choose a slightly darker surface so the highlight has room.
The same rule gives the other presets:
| Preset | Surface | Distance / blur | Intensity | Dark shade | Light shade |
|---|---|---|---|---|---|
| Light | #e0e0e0 |
12 / 24 px | 15% | #bababa |
#ffffff |
| Card | #f0f0f3 |
10 / 20 px | 12% | #d1d1d4 |
#ffffff |
| Dark | #2d2f34 |
12 / 24 px | 12% | #0e1015 |
#4c4e53 |
| Pressed | #e0e0e0 |
12 / 24 px | 15% | #bababa |
#ffffff |
| Convex | #e0e0e0 |
12 / 24 px | 15% | #bababa |
#ffffff |
On the Dark preset, subtracting 30.6 from each channel of (45, 47, 52) gives (14, 16, 21), or #0e1015, and adding it gives (76, 78, 83), or #4c4e53. Because the shift is equal across channels, the slight blue tint of the surface carries into both shades, so a dark neumorphic card does not turn into flat neutral gray.
What do the four shapes change?
Shape controls the element's background fill and whether the shadows sit outside or inside it. Distance, blur and radius behave the same for all four.
| Shape | Background | Shadows | Looks like |
|---|---|---|---|
| Flat | Solid surface color | Outer | A raised plateau |
| Convex | linear-gradient(145deg, light, dark) |
Outer | A raised dome, lit from the top left |
| Concave | linear-gradient(145deg, dark, light) |
Outer | A raised dish curving inward |
| Pressed | Solid surface color | Both inset |
A hollow pushed into the page |
The Pressed preset produces:
border-radius: 24px;
background: #e0e0e0;
box-shadow: inset 12px 12px 24px #bababa, inset -12px -12px 24px #ffffff;
With inset, the shadows are drawn inside the element's padding box, so the dark shade appears along the top-left inner edge and the highlight along the bottom-right. That reverses the lighting cue and reads as a depression. It is the natural "active" or "on" state for a toggle whose resting state is flat.
The Convex preset uses the full light and dark shades as gradient stops, linear-gradient(145deg, #ffffff, #bababa), which is a fairly strong curve at 15% intensity. For a subtler dome, lower the intensity; that softens the gradient and the shadows together, since both come from the same two colors.
How do distance, blur and radius interact?
The sliders are independent, but the look depends on their ratios.
- Distance (2 to 50 px) sets how far each shadow is offset on both axes. It controls apparent height: larger distances make the element float higher above the page.
- Blur (0 to 100 px) sets how soft the shadow edges are. A blur around twice the distance, as in every preset, gives the characteristic pillowy look. Blur equal to or below the distance produces hard-edged shadows that look more like a cutout.
- Radius (0 to 80 px) rounds the corners. Soft UI almost always uses generous rounding; square corners with soft shadows look like a rendering error.
- Intensity (2 to 40%) sets how far the shades move from the surface color.
A practical starting ratio is blur = 2 x distance, radius = 2 x distance, intensity near the clamp point for your surface. For small elements such as a 40-pixel icon button, scale distance down to 4 to 6 pixels; a 12-pixel offset on a 40-pixel button makes the shadow larger than the control.
Is neumorphism accessible?
Not by default. A neumorphic control's edge is defined by shadows that differ from the surface by only a few percent in luminance, and that fails the WCAG requirement for the visible boundary of interactive components.
WCAG 2.2 Success Criterion 1.4.11, Non-text Contrast, requires the visual information needed to identify a user interface component, and its states, to have a contrast ratio of at least 3:1 against adjacent colors. The contrast ratio uses the relative luminance formula defined in WCAG 2.2. Working it through for the default preset:
| Pair | Relative luminance | Contrast ratio | Meets 3:1? |
|---|---|---|---|
Dark shade #bababa vs surface #e0e0e0 |
0.491 vs 0.745 | About 1.47:1 | No |
Light shade #ffffff vs surface #e0e0e0 |
1.000 vs 0.745 | About 1.32:1 | No |
Border #7f7f7f vs surface #e0e0e0 |
0.212 vs 0.745 | About 3.03:1 | Just |
Border #767676 vs surface #e0e0e0 |
0.181 vs 0.745 | About 3.44:1 | Yes, with margin |
Text #333333 vs surface #e0e0e0 |
0.033 vs 0.745 | About 9.6:1 | Yes (also passes 4.5:1 for text) |
And those shadow figures are the best case. The blur spreads the shadow color out, so most of the visible shadow is lighter than #bababa. Raising intensity does not help much on a light surface, because the highlight is already clamped at white.
To check your own colors, the color contrast checker computes the ratio for any pair, and the guide to color contrast checking explains the formula in detail.
How to keep the look and pass the contrast rules
You do not have to abandon the style. You have to stop relying on it for anything a user must perceive.
- Use soft UI for containers, not for controls. Cards, panels and decorative wells can be purely neumorphic. Criterion 1.4.11 is about interactive components and meaningful graphics, so a container whose content identifies itself carries far less risk than a button whose edge is the only sign it exists.
- Give every interactive element a real cue. A 1 or 2 pixel border in a color of 3:1 or better, a contrasting icon, or a text label.
- Make focus obvious. Add a
:focus-visibleoutline in a high-contrast color. Soft shadows are not a focus indicator. - Do not signal state with depth alone. If pressed means "on", also change an icon, a label or a color.
- Respect user settings. The prefers-contrast media query lets you add borders or drop the effect when a user asks for more contrast.
.neu-button {
border-radius: 16px;
background: #e0e0e0;
box-shadow: 8px 8px 16px #bababa, -8px -8px 16px #ffffff;
border: 2px solid #767676;
color: #333333;
}
.neu-button:focus-visible {
outline: 3px solid #1d4ed8;
outline-offset: 3px;
}
.neu-button[aria-pressed="true"] {
box-shadow: inset 8px 8px 16px #bababa, inset -8px -8px 16px #ffffff;
}
@media (prefers-contrast: more) {
.neu-button { box-shadow: none; border-color: #333333; }
}
How to generate neumorphism CSS, step by step
- Open the neumorphism generator and pick a preset as a starting point: Light, Card, Dark, Pressed or Convex.
- Set the surface color with the color picker to match the background your element will sit on.
- Adjust distance and blur for height and softness, then intensity for contrast, watching the live preview.
- Choose a shape: flat, concave, convex or pressed.
- Set the radius to suit the element size.
- Click Copy CSS and paste the three declarations into your rule. Remember to give the parent the same background color.
How do you support light and dark themes?
Generate one set of values for each theme and swap them with custom properties. The Light and Dark presets above give a working pair:
:root {
--neu-surface: #e0e0e0;
--neu-dark: #bababa;
--neu-light: #ffffff;
}
@media (prefers-color-scheme: dark) {
:root {
--neu-surface: #2d2f34;
--neu-dark: #0e1015;
--neu-light: #4c4e53;
}
}
body, .neu-card { background: var(--neu-surface); }
.neu-card {
border-radius: 24px;
box-shadow: 12px 12px 24px var(--neu-dark), -12px -12px 24px var(--neu-light);
}
Dark neumorphism has the mirror of the light-surface problem: the shadow clamps toward black, and the highlight carries the effect. Check contrast separately for each theme.
Neumorphism, glassmorphism and plain shadows compared
Soft UI is one of several ways to show depth, and each has different costs.
| Style | Core CSS | Depth cue | Contrast risk | Good for |
|---|---|---|---|---|
| Neumorphism | Two opposing box-shadow layers, matching background |
Extrusion from the page | High | Decorative panels, showcase dashboards |
| Glassmorphism | backdrop-filter: blur() and a translucent fill |
Frosted layer over content | Medium, depends on what is behind | Overlays, cards over imagery |
| Material-style elevation | One or two downward box-shadow layers |
Card floating above the page | Low | General interfaces |
| Flat with borders | border and fill colors |
None | Lowest | Forms, dense data, accessibility-first work |
The glassmorphism generator builds the frosted-glass style, and the box shadow generator guide covers single and layered elevation shadows. For glowing or embossed text rather than boxes, the text shadow generator applies a similar idea to type. All of them are listed on the CSS tools hub.
Is the generator private?
Yes. The preview and CSS are generated in your browser with JavaScript, nothing is uploaded or stored, and the page keeps working offline once loaded. Copying the CSS counts toward a daily usage limit, and a message appears if that limit is reached.



