vue-transition-a11y
v1.0.1
Published
Vue transition component with a11y considerations
Downloads
28
Maintainers
Readme
vue-transition-a11y
https://vanhoofmaarten.github.io/vue-transition-a11y/
Vue transition component with a11y considerations.
Problem
When using the Vue transitions
component with CSS transitions or CSS Animations, it's pretty easy to disable these for users who prefer this.
<transition name="slide-fade">
<!-- ... -->
</transition>
Transitions
.slide-fade-enter-active,
.slide-fade-leave-active {
transition: all 0.3s ease;
}
@media (prefers-reduced-motion: reduce) {
.slide-fade-enter-active,
.slide-fade-leave-active {
transition: none;
}
}
Animations
.slide-fade-enter-active,
.slide-fade-leave-active {
animation: bounce-in 0.5s;
}
@media (prefers-reduced-motion: reduce) {
.slide-fade-enter-active,
.slide-fade-leave-active {
animation: none;
}
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
Globally
@media (prefers-reduced-motion: reduce) {
* {
animation: none !important;
transition: none !important;
}
}
But when using JavaScript Hooks, things get a little more complicated.
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
<!-- ... -->
</transition>
// ...
methods: {
beforeEnter(el) {
// ...
},
enter(el, done) {
// ...
done()
},
afterEnter(el) {
// ...
},
enterCancelled(el) {
// ...
},
beforeLeave(el) {
// ...
},
leave(el, done) {
// ...
done()
},
afterLeave(el) {
// ...
},
leaveCancelled(el) {
// ...
}
}
Where in all of these functions are you going to disable your complex animations?
Using the window.matchMedia
functionality, you could check if the user's preferences.
const prefersReducedMotion = window.matchMedia(
'screen and (prefers-reduced-motion: reduce)',
).matches;
// Stop every animation method if prefersReducedMotion === false
A bit over the top, don't you think?
Solution
To tackle this problem and enable Vue developers to make complex, re-usable and accessible transitions and animations with the transition component, I've created this component.
What is does is very simple. If the user prefers reduced motion, don't render the transition component. If not, render it.
This way, JavaScript Hooks aren't called when unnecessary
Easy.
API
The vue-transition-a11y
components API extends the standard Vue transition
API.
Props
| Prop | Default value | Description |
| ------------ | ------------- | -------------------------------------------------------------------- |
| reduceMotion | true
| Take the prefers-reduced-motion: reduce
media query in to account. |
Usage
<div class="outer">
<transition-a11y>
<div class="inner">
<!-- ... -->
</div>
</transition-a11y>
</div>
License
Copyright (c) 2020 Maarten Van Hoof