Neumorphism (Soft UI)

A design trend that creates soft, extruded shapes using subtle shadows and highlights to simulate physical depth.

Core Principles

1. Soft, Subtle Shadows

Elements appear to emerge from or sink into the background using dual shadows (light and dark).

2. Monochromatic Color Schemes

Usually one base color with slight variations for depth, avoiding high contrast.

3. Low Contrast

Soft, muted interfaces that rely on shadows for definition rather than stark borders.

4. Rounded Corners

Smooth, rounded shapes that enhance the soft, tactile feel.

Visual Characteristics

The Neumorphic Effect

The key is using two shadows: one light (top-left) and one dark (bottom-right) to create depth.

/* Base neumorphic style */
.neumorphic {
  background: #e0e5ec;
  border-radius: 20px;
  box-shadow: 
    9px 9px 16px rgba(163, 177, 198, 0.6),      /* Dark shadow */
    -9px -9px 16px rgba(255, 255, 255, 0.5);    /* Light shadow */
}

/* Pressed/inset version */
.neumorphic-inset {
  background: #e0e5ec;
  border-radius: 20px;
  box-shadow: 
    inset 6px 6px 10px rgba(163, 177, 198, 0.6),
    inset -6px -6px 10px rgba(255, 255, 255, 0.5);
}

Color Palette

Neumorphism works best with neutral, soft colors:

:root {
  /* Light theme (most common) */
  --bg-light: #e0e5ec;
  --shadow-dark: rgba(163, 177, 198, 0.6);
  --shadow-light: rgba(255, 255, 255, 0.5);
  --text: #4a5568;
  --accent: #6b7cff;
  
  /* Dark theme */
  --bg-dark: #2d3748;
  --shadow-dark-dark: rgba(0, 0, 0, 0.4);
  --shadow-light-dark: rgba(74, 85, 104, 0.4);
  --text-dark: #e2e8f0;
}

Implementation Examples

Neumorphic Button

<button class="neuro-btn">
  <span>Click Me</span>
</button>
.neuro-btn {
  padding: 16px 40px;
  background: #e0e5ec;
  border: none;
  border-radius: 15px;
  font-size: 16px;
  font-weight: 600;
  color: #4a5568;
  cursor: pointer;
  box-shadow: 
    8px 8px 16px rgba(163, 177, 198, 0.6),
    -8px -8px 16px rgba(255, 255, 255, 0.5);
  transition: all 0.2s ease;
}

.neuro-btn:hover {
  box-shadow: 
    10px 10px 20px rgba(163, 177, 198, 0.7),
    -10px -10px 20px rgba(255, 255, 255, 0.6);
}

.neuro-btn:active {
  box-shadow: 
    inset 4px 4px 8px rgba(163, 177, 198, 0.6),
    inset -4px -4px 8px rgba(255, 255, 255, 0.5);
}

Neumorphic Card

<div class="neuro-card">
  <div class="neuro-card__icon">
    <svg><!-- Icon --></svg>
  </div>
  <h3>Card Title</h3>
  <p>Soft, subtle depth creates a tactile interface.</p>
</div>
.neuro-card {
  background: #e0e5ec;
  border-radius: 20px;
  padding: 30px;
  box-shadow: 
    12px 12px 24px rgba(163, 177, 198, 0.6),
    -12px -12px 24px rgba(255, 255, 255, 0.5);
}

.neuro-card__icon {
  width: 60px;
  height: 60px;
  background: #e0e5ec;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 20px;
  box-shadow: 
    6px 6px 12px rgba(163, 177, 198, 0.6),
    -6px -6px 12px rgba(255, 255, 255, 0.5);
}

.neuro-card svg {
  width: 30px;
  height: 30px;
  fill: #6b7cff;
}

.neuro-card h3 {
  margin: 0 0 12px 0;
  color: #2d3748;
  font-size: 1.5rem;
}

.neuro-card p {
  margin: 0;
  color: #4a5568;
  line-height: 1.6;
}

Neumorphic Input Field

<div class="neuro-input-group">
  <label for="email">Email Address</label>
  <input type="email" id="email" class="neuro-input" placeholder="you@example.com">
</div>
.neuro-input-group {
  margin-bottom: 24px;
}

.neuro-input-group label {
  display: block;
  margin-bottom: 8px;
  color: #4a5568;
  font-weight: 500;
  font-size: 14px;
}

.neuro-input {
  width: 100%;
  padding: 14px 20px;
  background: #e0e5ec;
  border: none;
  border-radius: 12px;
  font-size: 16px;
  color: #2d3748;
  box-shadow: 
    inset 4px 4px 8px rgba(163, 177, 198, 0.5),
    inset -4px -4px 8px rgba(255, 255, 255, 0.5);
  transition: box-shadow 0.3s ease;
}

.neuro-input:focus {
  outline: none;
  box-shadow: 
    inset 6px 6px 12px rgba(163, 177, 198, 0.6),
    inset -6px -6px 12px rgba(255, 255, 255, 0.5);
}

.neuro-input::placeholder {
  color: #a0aec0;
}

Toggle Switch

<label class="neuro-toggle">
  <input type="checkbox">
  <span class="neuro-toggle__slider"></span>
</label>
.neuro-toggle {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 30px;
}

.neuro-toggle input {
  opacity: 0;
  width: 0;
  height: 0;
}

.neuro-toggle__slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #e0e5ec;
  border-radius: 30px;
  box-shadow: 
    inset 4px 4px 8px rgba(163, 177, 198, 0.5),
    inset -4px -4px 8px rgba(255, 255, 255, 0.5);
  transition: 0.3s;
}

.neuro-toggle__slider::before {
  content: "";
  position: absolute;
  height: 22px;
  width: 22px;
  left: 4px;
  bottom: 4px;
  background: #e0e5ec;
  border-radius: 50%;
  box-shadow: 
    4px 4px 8px rgba(163, 177, 198, 0.6),
    -4px -4px 8px rgba(255, 255, 255, 0.5);
  transition: 0.3s;
}

.neuro-toggle input:checked + .neuro-toggle__slider::before {
  transform: translateX(30px);
  background: #6b7cff;
  box-shadow: 
    4px 4px 8px rgba(163, 177, 198, 0.6),
    -4px -4px 8px rgba(255, 255, 255, 0.5),
    0 0 10px rgba(107, 124, 255, 0.3);
}

Icon Buttons

<div class="neuro-icon-group">
  <button class="neuro-icon-btn">
    <svg><!-- Heart icon --></svg>
  </button>
  <button class="neuro-icon-btn neuro-icon-btn--active">
    <svg><!-- Star icon --></svg>
  </button>
  <button class="neuro-icon-btn">
    <svg><!-- Share icon --></svg>
  </button>
</div>
.neuro-icon-group {
  display: flex;
  gap: 16px;
}

.neuro-icon-btn {
  width: 50px;
  height: 50px;
  background: #e0e5ec;
  border: none;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 
    6px 6px 12px rgba(163, 177, 198, 0.6),
    -6px -6px 12px rgba(255, 255, 255, 0.5);
  transition: all 0.2s ease;
}

.neuro-icon-btn:hover {
  box-shadow: 
    8px 8px 16px rgba(163, 177, 198, 0.7),
    -8px -8px 16px rgba(255, 255, 255, 0.6);
}

.neuro-icon-btn:active,
.neuro-icon-btn--active {
  box-shadow: 
    inset 4px 4px 8px rgba(163, 177, 198, 0.6),
    inset -4px -4px 8px rgba(255, 255, 255, 0.5);
}

.neuro-icon-btn svg {
  width: 24px;
  height: 24px;
  fill: #6b7cff;
}

Dark Mode Neumorphism

/* Dark theme variables */
body.dark {
  --bg: #2d3748;
  --shadow-dark: rgba(0, 0, 0, 0.4);
  --shadow-light: rgba(74, 85, 104, 0.4);
  --text: #e2e8f0;
}

/* Dark neumorphic elements */
.neuro-dark {
  background: #2d3748;
  box-shadow: 
    8px 8px 16px rgba(0, 0, 0, 0.4),
    -8px -8px 16px rgba(74, 85, 104, 0.4);
}

.neuro-dark-inset {
  background: #2d3748;
  box-shadow: 
    inset 6px 6px 12px rgba(0, 0, 0, 0.4),
    inset -6px -6px 12px rgba(74, 85, 104, 0.4);
}

When to Use Neumorphism

Use Sparingly For

  • Smart home controls: Tactile interface feeling
  • Music players: Modern, soft aesthetic
  • Settings panels: Subtle, non-distracting
  • Calculator apps: Tactile button feeling
  • Small UI experiments: Showcase design skills

Avoid For

  • Accessibility-critical apps: Low contrast issues
  • Content-heavy sites: Shadows become tiring
  • Enterprise software: Too trendy, not professional
  • E-commerce: Harder to scan products

Pros and Cons

Advantages

  • ✅ Modern, trendy aesthetic
  • ✅ Soft, pleasant appearance
  • ✅ Creates tactile sensation
  • ✅ Unique visual style
  • ✅ Works well for small apps

Disadvantages

  • Accessibility concerns: Low contrast
  • Trend-dependent: May look dated quickly
  • Limited use cases: Not versatile
  • Performance: Many shadows can be heavy
  • Readability: Text can be hard to read
  • Not suitable for complex interfaces

Common Mistakes

1. Insufficient Contrast

Wrong: Text and background too similar.

/* Wrong - unreadable */
.wrong {
  background: #e0e5ec;
  color: #d0d5dc; /* Too similar to background */
}

Right: Ensure text meets WCAG standards.

/* Right - readable */
.right {
  background: #e0e5ec;
  color: #2d3748; /* Clear contrast */
}

2. Overusing the Effect

Wrong: Every single element is neumorphic.
Right: Use strategically for key interactive elements.

3. Ignoring Accessibility

Wrong: Pretty but unusable for people with vision impairments.
Right: Test with accessibility tools, provide high-contrast alternative.

4. Too Many Shadow Layers

Wrong: Complex, performance-heavy shadows.
Right: Keep it simple with two shadows max.

Accessibility Considerations

Making Neumorphism Accessible

/* Provide a high-contrast mode */
@media (prefers-contrast: high) {
  .neuro-btn {
    /* Switch to clear borders and higher contrast */
    box-shadow: none;
    border: 2px solid #2d3748;
    background: #ffffff;
    color: #000000;
  }
}

/* Ensure focus states are visible */
.neuro-btn:focus {
  outline: 3px solid #6b7cff;
  outline-offset: 2px;
}

/* Provide text alternatives for icons */
<button class="neuro-icon-btn" aria-label="Add to favorites">
  <svg aria-hidden="true"><!-- Icon --></svg>
</button>

Testing Checklist

  • [ ] Text meets WCAG AA contrast ratio (4.5:1 minimum)
  • [ ] Focus indicators are clearly visible
  • [ ] Works with screen readers
  • [ ] Provide high-contrast alternative
  • [ ] Test with grayscale/colorblind simulation

Generator Tool Concept

/* Neumorphism generator mixin (Sass) */
@mixin neumorphic($bg-color, $distance: 10px, $blur: 20px, $intensity: 0.15) {
  $dark-shadow: darken($bg-color, $intensity * 100%);
  $light-shadow: lighten($bg-color, $intensity * 50%);
  
  background: $bg-color;
  box-shadow: 
    #{$distance} #{$distance} #{$blur} rgba($dark-shadow, 0.6),
    -#{$distance} -#{$distance} #{$blur} rgba($light-shadow, 0.5);
}

/* Usage */
.element {
  @include neumorphic(#e0e5ec, 12px, 24px, 0.15);
}

Advanced Techniques

Gradient Neumorphism

.gradient-neuro {
  background: linear-gradient(145deg, #e6ebf1, #d4dae4);
  box-shadow: 
    10px 10px 20px #c5cad3,
    -10px -10px 20px #fbffff;
  border-radius: 20px;
}

Animated Neumorphism

.animated-neuro {
  background: #e0e5ec;
  border-radius: 50%;
  width: 100px;
  height: 100px;
  box-shadow: 
    8px 8px 16px rgba(163, 177, 198, 0.6),
    -8px -8px 16px rgba(255, 255, 255, 0.5);
  transition: all 0.3s ease;
}

.animated-neuro:hover {
  animation: float 3s ease-in-out infinite;
}

@keyframes float {
  0%, 100% {
    box-shadow: 
      8px 8px 16px rgba(163, 177, 198, 0.6),
      -8px -8px 16px rgba(255, 255, 255, 0.5);
  }
  50% {
    box-shadow: 
      4px 4px 8px rgba(163, 177, 198, 0.4),
      -4px -4px 8px rgba(255, 255, 255, 0.3);
    transform: translateY(-10px);
  }
}

Color Neumorphism

.color-neuro {
  background: linear-gradient(145deg, #6b7cff, #5a6bef);
  box-shadow: 
    10px 10px 20px rgba(90, 107, 239, 0.4),
    -10px -10px 20px rgba(117, 136, 255, 0.4);
  color: white;
  padding: 20px;
  border-radius: 16px;
}

Best Practices

Do

  • ✅ Use for small, focused interfaces
  • ✅ Provide high-contrast alternative
  • ✅ Test thoroughly with accessibility tools
  • ✅ Keep backgrounds monochromatic
  • ✅ Use soft, rounded shapes
  • ✅ Animate subtly

Don't

  • ❌ Use for critical UI without alternatives
  • ❌ Apply to every element
  • ❌ Ignore accessibility standards
  • ❌ Use on complex, information-dense interfaces
  • ❌ Mix with other strong visual styles
  • ❌ Use sharp corners (breaks the effect)

Tools and Resources

Online Generators

Figma Plugins

  • Neumorphism/Soft UI: Generate neumorphic designs
  • Claymorphism: Similar soft 3D effects

CSS Libraries

  • No major libraries (it's just CSS shadows)
  • Custom implementations per project

Inspiration

Checklist

  • [ ] Shadows use both light and dark components
  • [ ] Background is soft, muted color
  • [ ] Corners are rounded (minimum 8px)
  • [ ] Text has sufficient contrast (WCAG AA)
  • [ ] Focus states are clearly visible
  • [ ] High-contrast mode available
  • [ ] Used sparingly, not everywhere
  • [ ] Performance tested (shadows can be heavy)
  • [ ] Tested with accessibility tools
  • [ ] Has clear affordances (what's clickable is obvious)

Conclusion

Neumorphism is a distinctive but limited design trend. Use it:

  • For small, focused applications
  • As an accent, not the entire interface
  • Always with accessibility in mind
  • With a backup plan (high-contrast mode)

Remember: Aesthetics should never come at the cost of usability.