Elevation
Shadows
Elevation in Material Design is measured as the distance between Material surfaces. The distance from the front of one Material surface to the front of another is measured along the z-axis in density-independent pixels (dps) and depicted (by default) using shadows (source).
In Kustom set the elevation global to an appropriate lower value and change the dark theme overlay.
Default elevations
All elements have default values for resting elevation and dynamic elevation offsets. Certain components are positioned at higher elevations than others, establishing a consistent elevation order across all components. For example, dialogs always appear in front of all other components.
The following table lists default values for resting elevation and dynamic elevation offsets.
Shadows in Android
Android uses a lighting engine to draw shadows; it contains a light source that creates ambient and spot shadows. The light is aligned to the top edge of the display and is located 600dp away from it.
Shadows on Android change Y and X offset depending on their location in relation to the light source. Items that are closer to the top edge will have a shadow with a null Y offset value. Items that are closer to the bottom edge will have a large Y offset, with visible shadows that go far below their background. This all happens dynamically, even as you scroll, but the effect is subtle.
Google Design provides a Material Design Stickersheet with elevation shadows. However, those do not match the elevation shadows on Android, as they are based off of the web components.
Shadows on Android are much softer.
Below are listed values and settings for both options. When building a Material komponent you can choose whichever one you like and want to use most.
The "Android Sdapted Shadow" values were based on the Material Theming + Android 10 Figma Community file, created by Eduardo Pratti and Tom Wellington.
Kustom Shadows
The shadow of a Material is combined from multiple shadows. Below are the formulas for blur, distance and color of each shadow.
To easily control the color of the shadow, make a global text called "Shadow".
You can set that global to the Color Name (like Primary and Secondary) or a hex value of choice (default = #000000).
For the actual color formula that the shadows will use, make a global text called "Shade":
$if(gv(shadow) ~= #, gv(shadow),
gv(theme)=Color | (gv(theme)=Color Auto & ai(isday)) | (gv(theme)=Color System & si(darkmode)=0),
tc(cut, tc(split, tc(split, gv(palette), gv(shadow), 1), "S900", 1), 7),
#000000)$
And lastly, make a global list called "elevation" with options:
0##0dp, 1##1dp, 2##2dp, 3##3dp, 4##4dp, 6##6dp, 8##8dp, 12##12dp, 16##16dp, 24##24dp
DEFAULT CSS SHADOWS (web)
Umbra Shadow
Blur
$12.5 * tc(split,
"0,1,1,3,4,5,5,5,5,6,6,7,8,8,9,9,10,11,11,12,13,13,14,14,15",
",", gv(elevation))$
Distance
$2 * tc(split,
"0,2,3,3,2,3,3,4,5,5,6,6,7,7,7,8,8,8,9,9,10,10,10,11,11",
",", gv(elevation))$
Color
$ce(gv(shade), alpha, 20)$
Penumbra Shadow
Blur
$12.5 * tc(split,
"0,1,2,4,5,8,10,10,10,12,14,15,17,19,21,22,24,26,28,29,31,33,35,36,38",
",", gv(elevation))$
Distance
$2 * gv(elevation)$
Color
$ce(gv(shade), alpha, 14)$
Ambient Shadow
Blur
$12.5 * tc(split,
"0,3,5,8,10,14,18,16,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46",
",", gv(elevation))$
Distance
$2 * tc(split,
"0,1,1,1,1,1,1,2,3,3,4,4,5,5,5,6,6,6,7,7,8,8,8,9,9",
",", gv(elevation))$
Color
$ce(gv(shade), alpha, 12)$
ANDROID ADAPTED SHADOWS
Spot Shadow
Blur
$12.5 * tc(split,
"0,1.5,3,4.5,6.25,7.7,9,10,11,12.4,13.7,14.85,16,18,20,22,24,25.5,27,28.5,30,31.5,33,34.5,36",
",", gv(elevation))$
Distance
$2 * tc(split,
"0,.5,.85,1.35,1.85,2.3,2.75,3.25,3.75,4.1,4.55,5,5.5,5.85,6.25,6.6,7,7.4,7.85,8.25,8.65,9.15,9.6,10.1,10.5",
",", gv(elevation))$
Color
$ce(gv(shade), alpha, 19)$
Ambient Shadow
Blur
$12.5 * tc(split,
"0,1,1,1.35,1.75,2.35,3,4,5,5.25,5.5,5.75,6,6,6,6,6,6.15,6.5,7,7.75,8.75,10,11.5,13",
",", gv(elevation))$
Distance
$2 * tc(split,
"0,0,.25,.35,.5,.35,.25,.35,.5,.6,.75,.85,1,1.5,2,2.5,3,3,3,3,3,3,3,3,3",
",", gv(elevation))$
Color
$ce(gv(shade), alpha, 4)$
Technically it's 3.9, but Kustom rounds down all values.Kustom Outline @0dp
When a Card has an elevation of 0dp (desktop - resting), the shadows are replaced with an outline.
The outline's color is the On Surface color with the quaternary opacity level:
$ce(gv(ons), alpha, if(gv(elevation)=0, gv(ons.3), 0))$
Dark Theme Elevation Overlay
When dark mode is turned on, elevation overlays are shown above views that have any elevation applied. This overlay is white by default, but can also be customized.
The overlay changes opacity depending on the elevation:
0dp = 0%
1dp = 5%
2dp = 7%
3dp = 8%
4dp = 9%
6dp = 11%
8dp = 12%
12dp = 14%
16dp = 15%
24dp = 16%
Kustom Overlay
Kustom can also handle overlays automatically. But instead of using another translucent shape on top of the surface, the overlay can simply be mixed into the surface color.
To easily transfer the elevation overlay color from the root to every komponent, make a global color called "Overlay".
You can set that global to any color, provided that its alpha is always set to 100% (default = #FFFFFFFF).
Whilst the black color of the shadow only darkens the surface below, the default white overlay can make the current surface color diluted, losing its vibrancy. This issue can be resolved by picking a custom overlay color.
Mix the Surface color with the Overlay color by the appropriate amount based on the elevation global:
$ce(gv(overlay), gv(surface),
if(gv(surface)=gv(dark),
if(gv(elevation)=1, 5,
gv(elevation)=2, 7,
gv(elevation)=3, 8,
gv(elevation)=4, 9,
gv(elevation)=6, 11,
gv(elevation)=8, 12,
gv(elevation)=12, 14,
gv(elevation)=16, 15,
gv(elevation)=24, 16, 0), 0))$
The formula can change based on what component it's applied to.You can also ignore the elevation overlays, if you’d like to use your own ‘elevated’ surface colors instead (unlink colors).
Surface Opacity
The Material can also express elevation through its opacity.
Kustom Opacity
Make a global list (or number - list suggested) called Opacity:
100##Opaque, 93##Slightly transparent
Add or change the options based on your setup.To override the preset list options, turn the global into a formula and write in a custom value (0-100).
Add opacity to the Surface color mix:
$ce(ce(gv(overlay), gv(surface),
if(gv(surface)=gv(dark),
if(gv(elevation)=1, 5,
...
gv(elevation)=24, 16, 0), 0)), alpha, gv(opacity))$
Using Opacity in Surface Gradients (BETA)
Here you have 3 ways of implementation:
ignore the opacity global;
use 2 options from the opacity global or
put 2 values into one option of the opacity global.
2 options from the list
100##Solid, 50##Gradient
Color:
$ce(gv(surface), alpha, gv(opacity, 0))$
Gradient:
$ce(gv(surface), alpha, gv(opacity, 1))$
2 values from 1 list option
100g0##Gradient 1, 93g0##Gradient 2
Color:
$ce(gv(surface), alpha, tc(split, gv(opacity), "g", 0))$
Gradient:
$ce(gv(surface), alpha, tc(split, gv(opacity), "g", 1))$