The accessibility was in pretty good shape as of last year. It can be used by keyboard only, there are no screen reflow issues and it announces reasonably well. One thing I did improve on this year is that the placeholder “8” was being announced.
The structure is that the “8” is replaced with random text, and I chose to keep it that way, but I added aria-hidden="true"
to the default state. When the “Who will win?” button is clicked several things that happen, mostly adding and removing class selectors to hide and show the different elements.
This year’s ‘ah ha’ JavaScript moment was to realize that I could also manipulate attributes, so I added the following to the function to change aria-hidden
from “true” to “false”:
document.getElementById('answer-container').setAttribute("aria-hidden", false);
Now the answer is announced but the “8” is not.
I rarely use any kind of animations. There are a number of reasons for this. Mostly my mind just doesn’t work in a way that would think “a little flourish or movement here would be just the thing”. Similarly when I look at animation code it doesn’t click for me the way grid or flexbox does.
One of the rare instances where it did occur to me that some animation would be just thing was the Magic 8 ball. And it seemed like straightforward shaking and fading would go a long way. Admittedly, I found some examples and made some adjustments rather than trying to figure out how to write it from scratch. That aside, I think does add to the overall Magic 8 ball-ness, which is nice.
While the animations are nice, what about accessibility? Motion can cause a variety of problems for people with motion sensitivities. Fortunately there are ways to help ensure that viewing animations and motion are a viewer’s choice.
As I was preparing to create this year’s 8 Ball Tatiana Mac’s article on prefers-reduced-motion was in my reading stream. Originally I was going to use the universal selector approach found in resets , but after reading Mac’s article I wanted to be a little more deliberate.
There are three items with motion.
I particularly liked the suggestion of changing my mindset on the approach, so instead of the default being to allow animations, I set the default experience to no animations.
Instead of using prefers-reduced-motion: reduce
to hide animations, I’m using prefers-reduced-motion: no-preference
to allow the animations. The advantage of this approach, as Mac points out, is that browsers that don’t support the media query get the default no animation approach.
Default experience:
.shake {
animation: none;
}
button:active {
transform: none;
}
.reveal {
animation: none;
}
Animation experience for those who have not selected to reduce motion and are using a browser that supports the media query:
@media (prefers-reduced-motion: no-preference) {
.shake {
animation: shake 0.82s cubic-bezier(.36,.07,.19,.97) both;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
perspective: 1000px;
}
@keyframes shake {
10%, 90% {
transform: translate3d(-1px, 0, 0);
}
20%, 80% {
transform: translate3d(2px, 0, 0);
}
30%, 50%, 70% {
transform: translate3d(-4px, 0, 0);
}
40%, 60% {
transform: translate3d(4px, 0, 0);
}
}
.reveal {
animation: fadeIn ease 4s;
} @keyframes fadeIn {
0% {
opacity:0;
}
100% {
opacity:1;
}
}
button:active {
transform: scale(0.95);
}
}
I’m usually so focused on how I can improve my dev skills that I overlook design. After adding the animations I realized it would also be nice to it make it look more like an actual 8 ball.
After checking some reference material I made the circle containing the 8 white and used Exo font for the geometric 8 vibe. The blue triangle would be a nice touch, but it’s hard enough to get some of the longer character names to display well, and this is 8 ball-esque enough for me at the moment. Maybe next year I’ll try to improve the animation to make it look like the 8 ball is being turned over, but maybe not!
You can read all the about the improvements on a year-by-year basis at the project page.