Skip to content

Instantly share code, notes, and snippets.

@adilsonfsantos
Last active January 9, 2020 15:51
Show Gist options
  • Save adilsonfsantos/ccf93893fd80351b584bffdcee46e345 to your computer and use it in GitHub Desktop.
Save adilsonfsantos/ccf93893fd80351b584bffdcee46e345 to your computer and use it in GitHub Desktop.
Sass mixin for easy Material Design elevation
// Elevation map https://material.io/design/environment/elevation.html#default-elevations
// Overlay map https://material.io/design/color/dark-theme.html#properties
// TO DO add all values from the material design guidelines
$elevation-map: (
body: (
elevation: 0dp,
overlay: 0%
),
header: (
elevation: 4dp,
overlay: 9%
),
card: (
elevation: 1dp,
overlay: 5%
),
card-hover: (
elevation: 8dp,
overlay: 12%
),
button: (
elevation: 2dp,
overlay: 7%
),
button-hover: (
elevation: 8dp,
overlay: 12%
),
dialog: (
elevation: 12dp,
overlay: 15%
),
divider-white: (
elevation: 0dp,
overlay: 20%
),
divider-black: (
elevation: 0dp,
overlay: 12%
)
);
// Shadow map from https://material-components.github.io/material-components-web-catalog/#/component/elevation
$elevation-umbra-map: (
0: "0px 0px 0px 0px",
1: "0px 2px 1px -1px",
2: "0px 3px 1px -2px",
3: "0px 3px 3px -2px",
4: "0px 2px 4px -1px",
5: "0px 3px 5px -1px",
6: "0px 3px 5px -1px",
7: "0px 4px 5px -2px",
8: "0px 5px 5px -3px",
9: "0px 5px 6px -3px",
10: "0px 6px 6px -3px",
11: "0px 6px 7px -4px",
12: "0px 7px 8px -4px",
13: "0px 7px 8px -4px",
14: "0px 7px 9px -4px",
15: "0px 8px 9px -5px",
16: "0px 8px 10px -5px",
17: "0px 8px 11px -5px",
18: "0px 9px 11px -5px",
19: "0px 9px 12px -6px",
20: "0px 10px 13px -6px",
21: "0px 10px 13px -6px",
22: "0px 10px 14px -6px",
23: "0px 11px 14px -7px",
24: "0px 11px 15px -7px",
) !default;
$elevation-penumbra-map: (
0: "0px 0px 0px 0px",
1: "0px 1px 1px 0px",
2: "0px 2px 2px 0px",
3: "0px 3px 4px 0px",
4: "0px 4px 5px 0px",
5: "0px 5px 8px 0px",
6: "0px 6px 10px 0px",
7: "0px 7px 10px 1px",
8: "0px 8px 10px 1px",
9: "0px 9px 12px 1px",
10: "0px 10px 14px 1px",
11: "0px 11px 15px 1px",
12: "0px 12px 17px 2px",
13: "0px 13px 19px 2px",
14: "0px 14px 21px 2px",
15: "0px 15px 22px 2px",
16: "0px 16px 24px 2px",
17: "0px 17px 26px 2px",
18: "0px 18px 28px 2px",
19: "0px 19px 29px 2px",
20: "0px 20px 31px 3px",
21: "0px 21px 33px 3px",
22: "0px 22px 35px 3px",
23: "0px 23px 36px 3px",
24: "0px 24px 38px 3px",
) !default;
$elevation-ambient-map: (
0: "0px 0px 0px 0px",
1: "0px 1px 3px 0px",
2: "0px 1px 5px 0px",
3: "0px 1px 8px 0px",
4: "0px 1px 10px 0px",
5: "0px 1px 14px 0px",
6: "0px 1px 18px 0px",
7: "0px 2px 16px 1px",
8: "0px 3px 14px 2px",
9: "0px 3px 16px 2px",
10: "0px 4px 18px 3px",
11: "0px 4px 20px 3px",
12: "0px 5px 22px 4px",
13: "0px 5px 24px 4px",
14: "0px 5px 26px 4px",
15: "0px 6px 28px 5px",
16: "0px 6px 30px 5px",
17: "0px 6px 32px 5px",
18: "0px 7px 34px 6px",
19: "0px 7px 36px 6px",
20: "0px 8px 38px 7px",
21: "0px 8px 40px 7px",
22: "0px 8px 42px 7px",
23: "0px 9px 44px 8px",
24: "0px 9px 46px 8px",
) !default;
// The overlay color
$elevation-overlay-color: #fff;
// The background color
$elevation-baseline-color: rgb(0, 0, 0) !default;
// Shadow calculation properties
$elevation-umbra-opacity: .2 !default;
$elevation-penumbra-opacity: .14 !default;
$elevation-ambient-opacity: .12 !default;
$elevation-property: box-shadow !default;
$elevation-overlay-property: opacity !default;
// If the elevation is animated
$elevation-transition-duration: 280ms !default;
// Remove the unit of a value
// Return a unitless value
@function strip-unit($number) {
@if type-of($number) == 'number' and not unitless($number) {
@return $number / ($number * 0 + 1);
}
@return $number;
}
@mixin elevation($level, $background, $shadow: true, $color: $elevation-baseline-color, $overlay: $elevation-overlay-color, $opacity-boost: 0) {
$z-elevation: map-get(map-get($elevation-map, $level), elevation);
$z-overlay: map-get(map-get($elevation-map, $level), overlay);
// If you only want the overlay effect
@if $shadow == false {}@else {
$z-value: strip-unit($z-elevation);
@if $z-value < 0 or $z-value > 24 {
@error "$z-value must be between 0 and 24, but received '#{$z-value}'";
}
$umbra-z-value: map-get($elevation-umbra-map, $z-value);
$penumbra-z-value: map-get($elevation-penumbra-map, $z-value);
$ambient-z-value: map-get($elevation-ambient-map, $z-value);
$umbra-color: rgba($color, $elevation-umbra-opacity + $opacity-boost);
$penumbra-color: rgba($color, $elevation-penumbra-opacity + $opacity-boost);
$ambient-color: rgba($color, $elevation-ambient-opacity + $opacity-boost);
box-shadow: (#{$umbra-z-value} #{$umbra-color},
#{$penumbra-z-value} #{$penumbra-color},
#{$ambient-z-value} $ambient-color);
}
// For the background color change the opacity with the elevation
@if $background == 'none' {}@else if $overlay == 'none' {
background-color: $background;
}@else {
$percent: alpha($overlay) * $z-overlay;
$opaque: opacify($overlay, 1);
$solid-color: mix($overlay, $background, $percent);
background-color: $solid-color;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment