In https://www.youtube.com/watch?v=PYSOnC2CrD8, @surma and @jakearchibald talked about what a proper crossfade is, why it is complicated to do with the current technologies. And at the end of the video, they mentioned that they just proposed this to the CSS working group.
What is a proper cross fade?
If we want to transition from a text A
to a text B
, the easiest is to vary the opacity from 1 to 0 on A
, and from 0 to 1 on B
.
The main issue with this method is that, for instance, during the middle of the animation, both will have a 50% opacity. Due to how CSS composes layers, we'll still have a color with 75% opacity. But in cross fade, the opacity should always be 100% as we are animating from the start to the end, without any notion of "this is on top of the other".
Here you can see the difference between improper and proper cross fade:
Incorrect 75% opacity | Fixed version |
---|---|
How to achieve this
The way to do it is to add mix-blend-mode: plus-lighter
on the second text, so that CSS knows how to blend this layer with the other ones.
In addition to setting the mix-blend-mode
, we should add isolation: isolate
on the container so that CSS knows that the composition operation should only be computed within this element, and that we shouldn't also apply it with the full background.
Here is the MDN article on mix-blend-mode
: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode.
Top comments (3)
I learned something new, thanks. But after looking at your demo several times, in practice I prefer the simple (incorrect) method of cross-fading, for two reasons: first, it makes the fact that a transition is happening clearer by doing at least a 25% overall fadeout of whatever is displayed. Second, the "correct" method fails to make any change at all to that part of the text or images that is identical. This looks very strange, that just part of the overall content seems to cross-fade, but not all of it: it is not good from a psychological point of view because in the middle of the crossfade identical content looks like it isn't changing. You want to see that all of the content is changing, not have your attention abnormally drawn to the part that is not changing.
That is expected, the goal of this article was mention how to do this operation in CSS now that the feature has been shipped.
The video I linked at the beginning really highlights what this tries to achieve.
When I wrote "proper", I didn't mean to say "this should be how things should be done", but as a "a correct cross-fade, from a mathematical point of view".
I think that the use case of this cross fade may be more visible on content with different colors (I'm gonna use examples from this video):
That is a very interesting point, and a subtle one. It is correct as far as it goes. But the truth is that cross-fading polychrome images is going to generate many false colors during the transition. This is similar to the fact that during a cross-fade, text will display incorrectly as strange unreadable glyphs, regardless of method.
So the difference between your method and mine is that you insist that the z-order matters and I insist on the reasons I gave above, and here. And, considering your method, if the transition colors must be "incorrect" anyway, why does it matter which incorrect colors are displayed? It doesn't matter at all.
And one more subtle point: if you consider that the eye actually sees an image in grayscale at very low illumination/brightness levels, my method above (the usual naive cross-fade) works better for humans than your very sophisticated one.
To summarize, both cross-fading methods can produce lots of false colors between the beginning and end keyframes. But only my method succeeds when considering just the equivalent monochromatic brightness levels. The z-order of rendering doesn't matter to human perception, while allowing a brightness increase (a fade) across the entire image during the cross-fade does.