SCSS Library to implement Material Design Shadows Can be used through either SCSS mixins or CSS classes
Credit goes to the Angular Material 2 team, Scott Hyndman and to the Material Design team. While reading the Angular Material 2 design docs on elevation I found reference to Scott Hyndman working with the Material Design team to create a Material Shadow Interpolator. This starts out with hand-crafted CSS box-shadows at 6 of the 24 defined Material Design elevations. From there the rest of the 24 elevations are interpolated using the next closest lower and higher defined shadows. In the case where there is no higher shadow, the highest two shadows are used and the result is extrapolated.
All I have done is replaced Scott's Javascript logic with SCSS functions, and added a few helper functions to make it easier to include in other projects.
bower install scss-material-shadows --save-dev
Demo on CodePen. This is my SCSS rewrite of the Material Shadow Interpolator.
Primary use is through a mixin called mdElevation()
mdElevation accepts 3 parameters, $elevation1, $elevation2, and a $state property to change from one to the other.
mdElevation($elevation1, $elevation2, $state);
$elevation2 and $state are optional, but must be used together
Specify the elevation of the element
The mdElevation($elevation) mixin takes an elevation from 0dp to 24dp
.my-panel {
@include mdElevation(2);
}
- Long form
You can use selectors to change the elevation of an element.
When an element changes elevation use the mdElevationTransition($deltaElevation) mixin to animate the change. Pass in the change in elevation and mdElevationTransition($deltaElevation) will change the animation duration. Smaller changes are quicker than longer changes.
.my-card {
@include mdElevation(2);
@include mdElevationTransition(6);
&:hover {
@include mdElevation(8);
}
}
- Short form
The below code will product the same output as the code above. I have tested 'hover' and 'active' states to trigger a change. If there is a use case I didn't account for please contact me.
.my-card {
@include mdElevation(2, 8, 'hover');
}
The library contains predifined elevation values for all the Material elements found here.
$materialElements: (
dialog: (24),
picker: (24),
nav-drawer: (16),
right-drawer: 16,
bottom-sheet: 16,
fab: 6 12 active,
sub-menu-3: 11,
sub-menu-2: 10,
sub-menu-1: 9,
menu: 8,
bottom-nav-bar: 8,
card: 2 8 hover,
raised-button: 2 8 active,
snackbar: 6,
app-bar: 4,
refresh-indicator: 3,
quick-entry: 2 3 active,
search-bar: 2 3 active,
switch: 1
);
To use one of these predefined elements use the mdElevationElement mixin:
.my-card {
@include mdElevationElement('card'); // Includes :hover state and elevation change from 2dp to 8dp
}
.dialog {
@include mdElevationElement('dialog'); // Is a static 24dp high
}
Along with the SCSS mixins, the SCSS file will generate static CSS classes that can be used in your HTML markup. The CSS file provided for download in the /css folder.
Like the mdElevation mixin above you have the choice of specifying a elevation value or an element
Elevation values follow the form:
md-elevation-z#, with # from 0 to 24
<div class="card md-elevation-z2">
</div>
<div class="dialog md-elevation-z24">
</div>
The above $materialElements list is also available in CSS classes
<div class="menu md-elevation-menu">
</div>
<div class="fab md-elevation-fab">
</div>
md-elevation-transition is available to apply a transition to the box-shadow property. Please note however that it is currently fixed at a 280ms duration and that to use this you will need some way of applying a different md-elevation-* class on the element to trigger a change.
- Change mdElevationTransition() to detect units of ms and use directly as the duration. If unitless it would be treated as a delta elevation change.
- Inlcude multiple duration options for the css class .md-elevation-transition
Material Design - Elevation and Shadows Material Shadow Interpolator