Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing card elevation is changing card color in Jetpack compose with Material 3

I am using the Card composable and I want it to be colored white.

But when I add some elevation to it, it changes color to more like the primaryContainer color.

I have seen documentation where they have somehting called as elevationOverlay. But couldn't find an example which says how to use it.

Here is my code:

Card(
      modifier = Modifier.padding(top = 16.dp),
      colors = CardDefaults.cardColors(containerColor = White),
      elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
) {
}

I do know I can use Elevated card instead of card, but there is same problem with elevated card as well.

Also, this is a special case so I am applying the color manually

like image 392
nayan dhabarde Avatar asked Dec 12 '25 19:12

nayan dhabarde


2 Answers

This stumped me for a while, but the solution is quite simple. Material 3 introduces the concept of "Tonal Color Overlays" to help distinguish elevation - https://developer.android.com/jetpack/compose/designsystems/material3#elevation

You can dig into the code for this by getting the colors from the theme with this line of code

MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp)

Command clicking on the surfaceColorAtElevation line shows the function and the return value, stated as this:

Returns: the ColorScheme.surface color with an alpha of the ColorScheme.surfaceTint color overlaid on top of it.

So from this I could see there is a theme color called surfaceTint.

If you - like me - want your cards one color, say White, and for them to stay White at all elevations, then all you need to do is set your surfaceTint color to the same color as your Card. Then at all levels of elevation, it'll just tint with an alpha of the same color, and the result is no change to your container color.

private val LightColorScheme = lightColorScheme(
    primary = Blue200,
    secondary = Blue100,
    tertiary = Blue50,
    primaryContainer = Color.White,
    surface = Color.White,
    background = Color.White,
    surfaceVariant = Color.White,
    surfaceTint = Color.White // THIS ONE
)
like image 124
Vin Norman Avatar answered Dec 15 '25 10:12

Vin Norman


After trying multiple ways found out that there is no way to override this except for to look at the Card.kt file from SDK and create something similar but disable the tonalColor(Thanks for hint @ianhanniballake that it is using tonalelevation)

Following code should do the work, until overriding is officially supported:

@Composable
fun CardWithoutTonalElevation(
    modifier: Modifier = Modifier,
    shape: Shape = CardDefaults.shape,
    colors: Color = White,
    border: BorderStroke? = null,
    elevation: Dp = 0.dp,
    content: @Composable ColumnScope.() -> Unit = {}
)  {
    Surface(
        modifier = modifier,
        shape = shape,
        color = colors,
        tonalElevation = 0.dp,
        shadowElevation = elevation,
        border = border,
    ) {
        Column(content = content)
    }
}
like image 33
nayan dhabarde Avatar answered Dec 15 '25 09:12

nayan dhabarde



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!