Cross-Fading Elements? There’s a Quirky CSS Trick for That
Reading Jake Archibald’s deep dive into why cross-fading two DOM elements is “currently impossible” got me thinking. Sure, you can animate both opacities, but that’s not a true cross-fade. It turns out Chrome and WebKit have a CSS function called -webkit-cross-fade() that does exactly that. MDN says it’s specced, but the implemented version differs, so it’s a bit messy—still, it exists and works.
.el {
background: -webkit-cross-fade(url(img1.svg), url(img2.svg), 50%);
}
The first thing that hit me: if one image is just a blank transparent GIF, wouldn’t that apply partial transparency to the other? That makes it a kind of proxy for background-opacity, which doesn’t exist but feels like it should. I tested it, and it works.
Here’s the core technique:
.el {
background-image: -webkit-cross-fade(
url(image.jpg),
url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7),
50%
);
That’s a 1px transparent GIF, Base64-encoded. It doesn’t work in Firefox, but everywhere else it’s fine. Plus, you can test for support right in CSS and fall back to something else if this is only an enhancement.
@supports (background: -webkit-cross-fade(url(), url(), 50%)) {
/* Only apply the idea if supported, do the Firefox fallback outside of this */
}


