Flutter Neumorphism
Creating soft, 3D-like UI elements with neumorphic design
✨ What is Neumorphism?
Neumorphism is a modern design trend that creates soft, extruded shapes using subtle shadows and highlights. It gives UI elements a tactile, three-dimensional appearance as if they're embossed or debossed into the background, creating an elegant and minimalist aesthetic that's both modern and intuitive.
Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: Colors.grey[500]!,
offset: Offset(4, 4),
blurRadius: 15,
),
BoxShadow(
color: Colors.white,
offset: Offset(-4, -4),
blurRadius: 15,
),
],
),
)
Output:
Neumorphic Elements
Raised Elements
Elements that appear to pop out
boxShadow: [
BoxShadow(
color: Colors.grey[500]!,
offset: Offset(4, 4),
blurRadius: 15,
),
]
Pressed Elements
Elements that appear pushed in
boxShadow: [
BoxShadow(
color: Colors.grey[500]!,
offset: Offset(4, 4),
blurRadius: 15,
inset: true,
),
]
Soft Shadows
Dual shadows for depth effect
boxShadow: [
BoxShadow(color: dark, ...),
BoxShadow(color: light, ...),
]
Rounded Corners
Smooth, rounded borders
borderRadius:
BorderRadius.circular(15)
🔹 Basic Neumorphic Container
Create a simple neumorphic container:
import 'package:flutter/material.dart';
class NeumorphicContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 200,
height: 200,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(20),
boxShadow: [
// Dark shadow (bottom-right)
BoxShadow(
color: Colors.grey[500]!,
offset: Offset(6, 6),
blurRadius: 15,
spreadRadius: 1,
),
// Light shadow (top-left)
BoxShadow(
color: Colors.white,
offset: Offset(-6, -6),
blurRadius: 15,
spreadRadius: 1,
),
],
),
child: Center(
child: Text(
'Neumorphic',
style: TextStyle(
fontSize: 20,
color: Colors.grey[700],
fontWeight: FontWeight.bold,
),
),
),
);
}
}
Output:
🔹 Neumorphic Button
Create an interactive neumorphic button:
class NeumorphicButton extends StatefulWidget {
@override
_NeumorphicButtonState createState() => _NeumorphicButtonState();
}
class _NeumorphicButtonState extends State {
bool _isPressed = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (_) => setState(() => _isPressed = true),
onTapUp: (_) => setState(() => _isPressed = false),
child: AnimatedContainer(
duration: Duration(milliseconds: 150),
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 15),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(15),
boxShadow: _isPressed
? [
BoxShadow(
color: Colors.grey[500]!,
offset: Offset(2, 2),
blurRadius: 5,
),
]
: [
BoxShadow(
color: Colors.grey[500]!,
offset: Offset(4, 4),
blurRadius: 15,
),
BoxShadow(
color: Colors.white,
offset: Offset(-4, -4),
blurRadius: 15,
),
],
),
child: Text(
'Press Me',
style: TextStyle(
color: Colors.grey[700],
fontWeight: FontWeight.bold,
),
),
),
);
}
}
Output:
🔹 Neumorphic Card
Create a neumorphic card with content:
Container(
width: 300,
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.grey[500]!,
offset: Offset(8, 8),
blurRadius: 15,
spreadRadius: 1,
),
BoxShadow(
color: Colors.white,
offset: Offset(-8, -8),
blurRadius: 15,
spreadRadius: 1,
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Neumorphic Card',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.grey[800],
),
),
SizedBox(height: 10),
Text(
'This is a beautiful neumorphic card with soft shadows.',
style: TextStyle(
fontSize: 14,
color: Colors.grey[600],
),
),
],
),
)
Output:
🔹 Neumorphic Icon Button
Create circular neumorphic icon buttons:
Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: Colors.grey[300],
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.grey[500]!,
offset: Offset(4, 4),
blurRadius: 15,
spreadRadius: 1,
),
BoxShadow(
color: Colors.white,
offset: Offset(-4, -4),
blurRadius: 15,
spreadRadius: 1,
),
],
),
child: Icon(
Icons.favorite,
color: Colors.red[300],
size: 30,
),
)
Output:
🔹 Neumorphism Best Practices
Design Guidelines:
- Use neutral backgrounds: Light grays work best (e.g., #E0E0E0)
- Dual shadows: Always use both dark and light shadows
- Subtle depth: Keep shadow offsets small (4-8px)
- Rounded corners: Use border radius for softer appearance
- Low contrast: Avoid high contrast colors
- Accessibility: Ensure sufficient contrast for text
// Recommended neumorphic color palette
Color background = Color(0xFFE0E0E0);
Color darkShadow = Color(0xFFBEBEBE);
Color lightShadow = Colors.white;
Color textColor = Color(0xFF666666);
// Shadow configuration
List neumorphicShadow = [
BoxShadow(
color: darkShadow,
offset: Offset(6, 6),
blurRadius: 15,
spreadRadius: 1,
),
BoxShadow(
color: lightShadow,
offset: Offset(-6, -6),
blurRadius: 15,
spreadRadius: 1,
),
];