9

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

nayan dhabarde
  • 1,734
  • 1
  • 19
  • 38
  • 2
    It sounds like you are experiencing the normal [tonal difference](https://m3.material.io/styles/elevation/applying-elevation#8b0ddbc5-201f-441e-93e7-ea9daf260da1) that is part of Material3? – ianhanniballake Jan 31 '23 at 04:07

6 Answers6

3

To resolve the issue of changing card color when modifying the card elevation in Jetpack Compose with Material Design 3, you can use the background modifier and pass it a Color object to set the desired color. Additionally, you can use the elevationOverlay parameter to set the overlay color.

Here's an updated example of your code:

Card(
  modifier = Modifier.padding(top = 16. dp)
  .background(color = Color.White),
  elevation = CardDefaults.cardElevation(defaultElevation = 2. dp),
  elevationOverlay = Color.White
) {}
Fruze Lee
  • 41
  • 1
  • fun Card( modifier: Modifier = Modifier, shape: Shape = CardDefaults.shape, colors: CardColors = CardDefaults.cardColors(), elevation: CardElevation = CardDefaults.cardElevation(), border: BorderStroke? = null, content: @Composable ColumnScope.() -> Unit ) { This is the card constructor of material3 jetpack compose there is no elevationoverlay – nayan dhabarde Jan 31 '23 at 04:11
3

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
)
Vin Norman
  • 2,749
  • 1
  • 22
  • 33
2

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)
    }
}
nayan dhabarde
  • 1,734
  • 1
  • 19
  • 38
0

You can try using some shadow and remove the elevation, this way:

Card(
        modifier = Modifier
            .fillMaxWidth()
            .shadow(
                elevation = 4.dp,
                shape = RoundedCornerShape(8.dp),
            ),
Joel Kanyi
  • 81
  • 1
  • 7
0

A workaround...

Card(
    modifier = Modifier          
        .shadow(
            elevation = 8.dp,
            shape = RoundedCornerShape(4.dp)
        ),
    elevation = CardDefaults.cardElevation(0.dp),
    colors = CardDefaults.cardColors(
        containerColor = Color.white
    )
X-Black...
  • 1,376
  • 2
  • 20
  • 28
0

Well, instead of

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

you should use

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

if you're using elevation in it, then the card is elevated :)