Gerillass 2.0.0 is out. It renames every utility function and replaces two mixins with one, so read the migration guide before you upgrade.

Gerillass

v2.1.1

Motion Safe

Type: Mixin
@include motion-safe();

* You can call mixins with or without the gls- namespace (e.g. @include gls-motion-safe();).

Some people turn on reduce motion in their operating system, because animation on screen gives them dizziness, nausea or a migraine. The Motion Safe Sass mixin applies the animation you give it only for everyone else, by writing it inside @media (prefers-reduced-motion: no-preference).

It is one media query, and the point is its direction. Motion written inside the block is opt-in, so a user who asked for less motion never gets it.

Opt in, rather than switch off

The usual way round is to write the animation and then turn it off:

Sass
.card { transition: transform 0.2s; }

@media (prefers-reduced-motion: reduce) {
  .card { transition: none; }
}

That override has to name every animation and every transition on the page, including the ones somebody adds next month, and the one it misses keeps moving. Written the other way, nothing moves unless it is inside the block, so there is no list to keep complete.

Examples

A transition that only runs for people who have not asked for less motion. Hover over the card. With reduce motion turned on, the card still lifts, but at once rather than gliding.

Sass
.card {
  @include motion-safe {
    transition: transform 0.2s ease, box-shadow 0.2s ease;
  }
}
CSS
@media (prefers-reduced-motion: no-preference) {
  .card {
    transition: transform 0.2s ease, box-shadow 0.2s ease;
  }
}
Result

Called at the root, the block can hold whole rules. The fade starts from opacity: 0 in the keyframes, not in the base rule, so with reduce motion turned on the badge is simply there.

Sass
@keyframes fade-in {
  from { opacity: 0; transform: translateY(6px); }
}

@include motion-safe {
  .badge {
    animation: fade-in 0.6s ease both;
  }
}
CSS
@keyframes fade-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
}
@media (prefers-reduced-motion: no-preference) {
  .badge {
    animation: fade-in 0.6s ease both;
  }
}
Result

What it refuses

Called without a block it has nothing to wrap, and would emit nothing at all, so it stops the build instead.

Sass
.card {
  @include motion-safe;
}
Error: `motion-safe` wraps the motion you pass it, so call it with a block, such as `.card { @include motion-safe { transition: transform 0.2s; } }`.