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).

Depicting elevation with shadows
1. One surface at 1dp elevation and another surface at 8dp elevation, as viewed from the front2. The difference in elevation between the two surfaces is 7dp, as viewed from the side
The shadow of a component changes, if there is another elevated element already below it.
1. Both surfaces A and B are at the same 8dp elevation. They cast different shadows because Surface B is in front of another surface (C) that already has elevation.2. Elevation differences between surfaces (A), (B), and (C), as viewed from the side.

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.

Elevation
Cross-section diagram showing the resting elevation and dynamic elevation offsets for multiple components.

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.

Elevation Overlays

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.

1. Material can change opacity uniformly across its entire surface.2. Material can change opacity across a portion of its surface.

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))$