Jetpack Compose Shadows
Add depth and realism to your UI using shadows - from simple elevation to expressive effects like gradients, neumorphism, and realism.
What You’ll Learn
- Create basic Material-style shadows
- Customize with dropShadow()
- Use innerShadow() for pressed effects
- Animate shadows on interaction
- Apply gradient shadows with Brush
- Design neumorphic soft shadows
- Build bold neobrutalist effects
- Layer realistic multi-shadow designs
Basic Shadows
Create elevation-based shadows following Material Design guidelines using Modifier.shadow().
Simulates a light source from above, clipped to the composable’s shape.
@Composable
fun ElevationBasedShadow() {
Box(
modifier = Modifier
.size(100.dp)
.shadow(10.dp, RectangleShape)
.background(Color.White)
)
}
Drop Shadows
Draw customizable, realistic shadows behind elements using Modifier.dropShadow().
Control blur, spread, color, and offset to create depth and glow effects.
@Composable
fun DropShadowBox() {
Box(
Modifier
.size(200.dp)
.dropShadow(
shape = RoundedCornerShape(20.dp),
shadow = Shadow(
radius = 10.dp,
spread = 6.dp,
color = Color(0x40000000),
offset = DpOffset(4.dp, 4.dp)
)
)
.background(Color.White, RoundedCornerShape(20.dp))
)
}
Inner Shadows
Use Modifier.innerShadow() to create a recessed, pressed look - perfect for neumorphic or tactile UIs.
Always apply .background() before the shadow for visibility.
@Composable
fun InnerShadowBox() {
Box(
Modifier
.size(200.dp)
.background(Color.White, RoundedCornerShape(20.dp))
.innerShadow(
shape = RoundedCornerShape(20.dp),
shadow = Shadow(
radius = 10.dp,
spread = 2.dp,
color = Color(0x40000000),
offset = DpOffset(6.dp, 7.dp)
)
)
)
}
Animated Shadows
Make shadows respond to user input with animation APIs - for example, pressing a button lowers elevation dynamically.
Use updateTransition and animateColor for fluid effects.
@Composable
fun AnimatedShadowButton() {
val interaction = remember { MutableInteractionSource() }
val pressed by interaction.collectIsPressedAsState()
val transition = updateTransition(pressed, label = "press")
val alpha by transition.animateFloat(label = "") { if (it) 0.5f else 1f }
Box(
Modifier
.size(200.dp)
.clickable(interaction, null) {}
.dropShadow(
RoundedCornerShape(50),
shadow = Shadow(10.dp, 0.dp, Color.Gray, alpha = alpha)
)
.background(Color.White, RoundedCornerShape(50))
)
}
Gradient Shadows
Use Brush to colorize shadows - perfect for expressive, animated effects.
Combine dropShadow() with Brush.sweepGradient() for rainbow or breathing effects.
@Composable
fun GradientShadowBox() {
Box(
Modifier
.size(200.dp)
.dropShadow(
shape = RoundedCornerShape(70.dp),
shadow = Shadow(
radius = 10.dp,
brush = Brush.sweepGradient(listOf(Color.Cyan, Color.Magenta, Color.Yellow)),
offset = DpOffset(0.dp, 0.dp)
)
)
.background(Color.White, RoundedCornerShape(70.dp))
)
}
Neumorphic Shadows
Soft, minimal shadows on both sides to create a smooth 3D surface feel.
Use opposing dropShadow() calls with light and dark tones.
@Composable
fun NeumorphicBox() {
val bg = Color(0xFFe0e0e0)
Box(
Modifier
.size(200.dp)
.background(bg)
.dropShadow(RoundedCornerShape(30.dp),
Shadow(15.dp, color = Color.White, offset = DpOffset(-10.dp, -10.dp))
)
.dropShadow(RoundedCornerShape(30.dp),
Shadow(15.dp, color = Color(0xFFb1b1b1), offset = DpOffset(10.dp, 10.dp))
)
.background(bg, RoundedCornerShape(30.dp))
)
}
Neobrutalist Shadows
Bold and modern - high-contrast, flat edges, and visible color shadows.
Use dropShadow() with zero blur for a sharp, graphic look.
@Composable
fun NeoBrutalShadow() {
Box(
Modifier
.size(200.dp)
.dropShadow(
RoundedCornerShape(0.dp),
Shadow(0.dp, 0.dp, Color.Blue, offset = DpOffset(8.dp, 8.dp))
)
.border(8.dp, Color.Red)
.background(Color.White)
)
}
Realistic Shadows
Layer multiple drop and inner shadows for lifelike lighting and soft diffusion.
Mix light and dark layers to simulate real-world depth and glow.
@Composable
fun RealisticShadowBox() {
Box(
Modifier
.size(200.dp)
.dropShadow(
RoundedCornerShape(100.dp),
Shadow(40.dp, color = Color(0xB3000000), offset = DpOffset(2.dp, 8.dp))
)
.dropShadow(
RoundedCornerShape(100.dp),
Shadow(4.dp, color = Color(0x66000000), offset = DpOffset(0.dp, 4.dp))
)
.background(Color.Black, RoundedCornerShape(100.dp))
}
Thank You - Follow Boltuix
Daily Jetpack Compose insights - Material 3, graphics, and expressive UI tips.
#Android #JetpackCompose #MaterialDesign #ComposeGraphics #Kotlin












