Jetpack Compose Shadows

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

Post a Comment

Previous Post Next Post