Skip to content

Instantly share code, notes, and snippets.

@TMMC
Last active January 25, 2018 23:15
Show Gist options
  • Save TMMC/ff050d9fe74fb3404e5604e9352631ba to your computer and use it in GitHub Desktop.
Save TMMC/ff050d9fe74fb3404e5604e9352631ba to your computer and use it in GitHub Desktop.
Sass mixins for CSS3 animations and keyframes. Created at CodePen.io, demo: http://codepen.io/TMMC/pen/xRaqje.
// == Sass mixins for animation and keyframes
// --------------------------------------------------
// @author TMMC <http://www.tmmc.pl>
// @licence MIT <https://opensource.org/licenses/MIT)>
// --------------------------------------------------
// IMPORTANT: using these mixins with autoprefixer is rather pointless as autoprefixer itself will do its job. The mixins give more control over prefixed properties and supported browsers. Anyways, even with autoprefixer, it will save time for defining all animation properties.
// == Animation
// Create animation properties and optionally classes for elements.
// Each argument can have `null` value, to exclude it.
// TODO: support for multiple animations.
// @param $name (null|string) - animation name or null
// @param $duration (time) - seconds or miliseconds animation takes to complete
// @param $timing-function (string) - the name of speed curve from CSS set [ease|ease-in|ease-out|ease-in-out| linear|cubic-bezier(x1, y1, x2, y2)]
// @param $delay (time) - seconds or miliseconds before the animation will start
// @param $iterations (number|infinite|initial|inherit) - number of times the animation is played
// @param $direction (normal|reverse|alternate|alternate-reverse|initial|inherit) - direction of animation playing cycles
// @param $fill-mode (none|forwards|backwards|both|initial|inherit) -style for the element when the animation is not playing
// @param $play-state (running|paused) - whether the animation is initially running or paused
// @param $create-class (false|true|string) - whether to create class name for element: false: no, true: create classname same as animation name, string: name for the class
// Animation shorthand: animation-name animation-duration animation-timing-function animation-delay animation-iteration-count <animation-direction> <animation-fill-mode> <animation-play-state>
@mixin _animate($name: null, $duration: 5s, $timing-function: linear, $delay: 0s, $iterations: infinite, $direction: normal, $fill-mode: none, $play-state: running, $create-class: false) {
@if ($create-class == true and $name != null) { // Create class from animation name.
.#{$name} {
@include _animate($name, $duration, $timing-function, $delay, $iterations, $direction, $fill-mode, $play-state, $create-class: false)
}
} @else if (type-of($create-class) == string) { // Create class from given string.
.#{$create-class} {
@include _animate($name, $duration, $timing-function, $delay, $iterations, $direction, $fill-mode, $play-state, $create-class: false)
}
} @else { // Ment to be included within selector.
@include _prefix((
animation-name: #{$name},
animation-duration: #{$duration},
animation-timing-function: #{$timing-function},
animation-delay: #{$delay},
animation-iteration-count: #{$iterations},
animation-direction: #{$direction},
animation-fill-mode: #{$fill-mode},
animation-play-state: #{$play-state}
), (webkit moz));
// Animation shorthand (for first five properties)
// @include _prefix((animation: #{$name} #{$duration} #{$timing-function} #{$delay} #{$iterations}), (webkit moz));
// Separate declarations for direction, fill mode and play state
// @include _prefix((
// animation-direction: #{$direction},
// animation-fill-mode: #{$fill-mode},
// animation-play-state: #{$play-state}
// ), (webkit moz));
}
}
// == Prefixes
// Prefix choosen declarations for browsers you want to support.
// @param $declarations (map) - sass map of css declarations to prefix
// @param $property-prefixes (list) - space separeted sass list of vendor prefixes (w/out dashes)
@mixin _prefix($declarations, $property-prefixes: webkit moz ms o) {
@each $property, $value in $declarations { // Take property and value from each declaration
@each $property-prefix in $property-prefixes { // Take each vendor prefix from list
-#{$property-prefix}-#{$property}: #{$value}; // Output each declaration with each property prefixed
}
#{$property}: #{$value}; // Output declaration with unprefixed property (W3C standard)
}
}
// == Keyframes
// Create keyframes for animation.
// @param $name (string) - keyframes (and animation) name (no spaces)
// @param $vendors (map) - sass map of browsers to support (actually prefixes w/out dashes for each one of them).
@mixin _keyframes($name, $vendors) {
@if (length($vendors) > 0) {
@at-root {
@if (map-get($vendors, moz) == true) {
@-moz-keyframes #{$name} {
$_vendor-prefixes: moz !global; // Pollution of global scope (just live with that).
@content;
}
}
@if (map-get($vendors, webkit) == true) {
@-webkit-keyframes #{$name} {
$_vendor-prefixes: webkit !global; // Pollution of global scope (just live with that).
@content;
}
}
@if (map-get($vendors, o) == true) {
@-o-keyframes #{$name} {
$_vendor-prefixes: o !global; // Pollution of global scope (just live with that).
@content;
}
}
@if (map-get($vendors, ms) == true) {
@-ms-keyframes #{$name} {
$_vendor-prefixes: ms !global; // Pollution of global scope (just live with that).
@content;
}
}
@keyframes #{$name} {
$_vendor-prefixes: ();
@each $key, $val in $vendors {
@if ($val == true) {
$_vendor-prefixes: append($_vendor-prefixes, #{$key});
}
}
$_vendor-prefixes: $_vendor-prefixes !global; // Pollution of global scope (just live with that).
@content;
}
}
}
}
// == Crucial variables for animations and keyframes
// Supported browsers
$_vendors: (
moz : true,
webkit : true,
o : false, // pointless
ms : false // pointless
) !default;
// Reset polluted global variable (just live with that).
$_vendor-prefixes: null !global;
// == Usage
// Unrelated styling for examples
.container-fluid {
margin-top: 1rem;
margin-bottom: 1rem;
[class*="col-"] {
margin-top: 1rem;
margin-bottom: 1rem;
}
}
.animation-test {
padding: 1rem;
text-shadow: 1px 1px 0 rgba(#fff,.25);
border-radius: .2rem;
border: 1px solid rgba(#000,.125);
font-size: .9rem;
line-height: 1rem;
text-transform: uppercase;
text-align: center;
overflow: hidden;
text-overflow: clip; // fallback
text-overflow: ellipsis;
white-space: nowrap;
@include _prefix((box-sizing: border-box), (webkit moz));
}
// Keyframes for all examples
@include _keyframes(test, $_vendors) {
0% {
opacity: 0;
background-color: #c0c0c0;
@include _prefix((transform: scale(0)), $_vendor-prefixes);
}
50% {
opacity: .5;
background-color: #ffa500;
@include _prefix((transform: scale(1), filter: grayscale(25)), $_vendor-prefixes);
}
100% {
opacity: 1;
background-color: lighten(#ffa500,10%);
@include _prefix((transform: scale(0), filter: grayscale(0)), $_vendor-prefixes);
}
};
// Usage example 01: include all animation properties for a class within a rule-set
// Default values, defined animation name, modified duration and timing function
.example-01 {
@include _animate(test, 10s, ease-in-out);
// Declarations which have nothing to do with animation itself.
border-color: rgba(#000,.0625);
}
// Usage example 02: create class with all animation properties within a single rule-set
// Default values, defined animation name, modified duration and timing function, defined a general usage class with all animation properties.
@include _animate(test, 10s, ease-in-out, $create-class: 'example-02');
// Usage example 03: create reusable general usage classes (one for common animation properties and one for specific animation properties)
// Default values w/out animation name, modified duration and timing function, defined general usage class name.
@include _animate($duration: 10s, $timing-function: ease-in-out, $create-class: animated);
// Defined animation name, `null` for excluded properties, modified timing function, $create-class: true (creates class name from animation name)
@include _animate(test, null, ease-in-out, null, null, null, null, null, true);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment