Two years ago, I wrote about
prefers-reduced-motion, a media query introduced into Safari 10.1 to help people with vestibular and seizure disorders use the web. The article provided some background about the media query, why it was needed, and how to work with it to avoid creating disability-triggering visual effects.
We’re now four months into 2019, and it makes me happy to report that we have support for the feature in all major desktop browsers! Safari was first, with Firefox being a close second. Chrome was a little late to the party, but introduced it as of version 74.
Reduce isn’t necessarily remove
We may not need to throw the baby out with the bathwater when it comes to using animation. Remember, it’s
If the meaning of a component is diminished by removing its animation altogether, we could slow down and simplify the component’s animation to the point where the concept can be communicated without potentially being an accessibility trigger.
FLIP is an approach to animations that remaps animating expensive properties, like width, height, left and top to significantly cheaper changes using transforms. It does this by taking two snapshots, one of the element’s First position (F), another of its Last position (L). It then uses a transform to Invert (I) the element’s changes, such that the element appears to still be in the First position. Lastly it Plays (P) the animation forward by removing the transformations applied in the Invert step.
clip-pathis one of those CSS properties we generally know is there but might not reach for often for whatever reason. It’s a little intimidating in the sense that it feels like math class because it requires working with geometric shapes, each with different values that draw certain shapes in certain ways.
We’re going to dive right into
clip-pathin this article, specifically looking at how we can use it to create pretty complex animations. I hope you’ll see just how awesome the property and it’s shape-shifting powers can be.
Splitting creates elements and adds CSS variables to unlock amazing possibilities for animating text, grids, and more!
DoubleDash your CSS
The previously impractical becomes easy with Splitting’s CSS Variables.
A shocking amount of features in a 1.5kb (minified & gzipped) package.
Upgrade websites for modern browsers without breaking IE.
WebKit now supports the
prefers-reduced-motionmedia feature, part of CSS Media Queries Level 5, User Preferences. The feature can be used in a CSS
@mediablock or through the
I haven’t checked how accessible this is, and I’m torn on the concept of custom scrollbars, but this is interesting at the very least:
Use scale transforms when animating clips. You can prevent the children from being stretched and skewed during the animation by counter-scaling them.
In this post we’re going to look over what’s involved if you want performant clip animations. If you want to see a demo, check out the Sample UI Elements GitHub repo.
We’ve all been there. You’ve got an element you want to be able to collapse and expand smoothly using CSS transitions, but its expanded size needs to be content-dependent. You’ve set
transition: height 0.2s ease-out. You’ve created a
collapsedCSS class that applies
height: 0. You try it out, and… the height doesn’t transition. It snaps between the two sizes as if
transitionhad never been set. After some fiddling, you figure out that this problem only happens when the height starts out or ends up as
auto. Percentages, pixel values, any absolute units work as expected. But all of those require hard coding a specific height beforehand, rather than allowing it to naturally result from the size of the element content.
If you were hoping I had a magical, complete solution to this problem, I’m sorry to disappoint you. There’s no one solution that achieves the desired effect without downsides. There are, however, multiple workarounds that each come with a different set of advantages and disadvantages, and in most use cases at least one of them will get the job done in an acceptable manner. I’ll outline the major ones, and list out their ups and downs so you can hopefully pick the best one for your situation.
If you web search this problem, the
max-heightapproach will probably be mentioned in all of the first five to ten results. It’s actually pretty unideal, but I thought it was worth including here for the sake of comparison.
It works like this: CSS values can only be transitioned to and from fixed unit values. But imagine we have an element whose
heightis set to
auto, but whose
max-heightis set to a fixed value; say,
1000px. We can’t transition
height, but we can transition
max-height, since it has an explicit value. At any given moment, the actual height of the element will be the maximum of the
max-height. So as long as
max-height’s value is greater than what
autocomes out to, we can just transition
max-heightand achieve a version of the desired effect.
Implementation works like this: we set a
transitionfor the element’s
transformproperty, then toggle between
transform: scaleY(0). These mean, respectively, “render this element at the same scale (on the y axis) that it starts out at” and “render this element at a scale of 0 (on the y axis)”. Transitioning between these two states will neatly “squish” the element to and from its natural, content-based size.
Managing a CSS transition in CSS would be ideal, but as we’re learning, sometimes it just isn’t entirely possible.
The basic strategy is to manually do what the browser refuses to: calculate the full size of the element’s contents, then CSS transition the element to that explicit pixel size.