Last updated
Basic Raised Button
A neumorphic button that appears to protrude from the surface:
.button-raised {
background: #e0e5ec;
border-radius: 12px;
box-shadow:
6px 6px 12px #b8bec7,
-6px -6px 12px #ffffff;
border: none;
padding: 12px 24px;
cursor: pointer;
}
The light shadow (#ffffff) goes top-left, the dark shadow (#b8bec7) goes bottom-right. Both are derived from the background color #e0e5ec — lightened and darkened by the same amount.
Pressed / Active State
When the button is clicked, it appears to press into the surface:
.button-pressed {
background: #e0e5ec;
border-radius: 12px;
box-shadow:
inset 6px 6px 12px #b8bec7,
inset -6px -6px 12px #ffffff;
}
Adding inset to both shadows reverses the effect — the element now appears to sink into the surface. Use this for the :active state of buttons and the selected state of toggle switches.
Complete Interactive Button
Combining raised, hover, and pressed states:
.neu-button {
background: #e0e5ec;
border-radius: 12px;
box-shadow: 6px 6px 12px #b8bec7, -6px -6px 12px #ffffff;
border: none;
padding: 14px 28px;
font-size: 16px;
color: #6b7280;
cursor: pointer;
transition: box-shadow 0.15s ease;
}
.neu-button:hover {
box-shadow: 8px 8px 16px #b8bec7, -8px -8px 16px #ffffff;
}
.neu-button:active {
box-shadow: inset 6px 6px 12px #b8bec7, inset -6px -6px 12px #ffffff;
}
Neumorphic Card
A card component with the neumorphic raised effect:
.neu-card {
background: #e0e5ec;
border-radius: 20px;
box-shadow: 10px 10px 20px #b8bec7, -10px -10px 20px #ffffff;
padding: 24px;
max-width: 320px;
}
.neu-card h3 {
color: #4a5568;
margin-bottom: 8px;
}
.neu-card p {
color: #718096;
line-height: 1.6;
}
Neumorphic Input Field
An input that appears recessed into the surface:
.neu-input {
background: #e0e5ec;
border: none;
border-radius: 10px;
box-shadow: inset 4px 4px 8px #b8bec7, inset -4px -4px 8px #ffffff;
padding: 12px 16px;
font-size: 16px;
color: #4a5568;
outline: 2px solid #4a90e2;
width: 100%;
}
.neu-input:focus {
box-shadow:
inset 4px 4px 8px #b8bec7,
inset -4px -4px 8px #ffffff,
0 0 0 2px #6366f1;
}
Input fields use the inset (pressed) style because they represent a space where content is entered — visually recessed into the surface.
Neumorphic Toggle Switch
A circular toggle with raised/pressed states:
.neu-toggle {
width: 60px;
height: 30px;
background: #e0e5ec;
border-radius: 15px;
box-shadow: inset 4px 4px 8px #b8bec7, inset -4px -4px 8px #ffffff;
position: relative;
cursor: pointer;
}
.neu-toggle-thumb {
width: 22px;
height: 22px;
background: #e0e5ec;
border-radius: 50%;
box-shadow: 3px 3px 6px #b8bec7, -3px -3px 6px #ffffff;
position: absolute;
top: 4px;
left: 4px;
transition: left 0.2s ease;
}
.neu-toggle.active .neu-toggle-thumb {
left: 34px;
}
Color Calculation for Shadow Values
How to derive shadow colors from any background color:
Background: #e0e5ec (HSL: 216°, 18%, 90%)
Light shadow: lighten by 8% → #ffffff (or close to white)
Dark shadow: darken by 8% → #b8bec7
Background: #2d3748 (dark theme)
Light shadow: lighten by 8% → #3d4f66
Dark shadow: darken by 8% → #1d2535
The generator calculates these values automatically. The key rule: both shadows must be derived from the background color, not pure white and black. Pure white/black shadows look harsh and artificial.
Dark Theme Neumorphism
Neumorphism works on dark backgrounds too:
.neu-dark-card {
background: #2d3748;
border-radius: 16px;
box-shadow: 8px 8px 16px #1d2535, -8px -8px 16px #3d4f66;
padding: 20px;
}
.neu-dark-button {
background: #2d3748;
border-radius: 10px;
box-shadow: 5px 5px 10px #1d2535, -5px -5px 10px #3d4f66;
border: none;
padding: 12px 24px;
color: #a0aec0;
cursor: pointer;
}
Accessibility Considerations
Neumorphism can create contrast issues. Check these ratios:
- Text on neumorphic background: minimum 4.5:1 contrast ratio (WCAG AA)
- Avoid using shadow alone to indicate interactive state — add color or text changes
- Ensure focus indicators are visible (add a colored outline on focus)
- Test with users who have low vision — the subtle shadows may be invisible
/* Accessible focus indicator for neumorphic elements */
.neu-button:focus-visible {
outline: 3px solid #6366f1;
outline-offset: 2px;
}
Optimal Background Colors
Neumorphism works best in a specific lightness range:
- Too light (L > 95%): light shadow is invisible, effect disappears
- Optimal range (L 75–90%): both shadows visible, effect looks natural
- Too dark (L < 30%): dark shadow is invisible, effect disappears
- Sweet spot:
#e0e5ec,#dde1e7,#e8ecf0for light themes
The generator warns you when your chosen background color is outside the optimal range and suggests adjustments to maintain the neumorphic effect.