Created attachment 435129 [details] A screen capture showing Chrome working correctly and Safari working incorrectly Repro: 1. Visit https://esbuild.github.io/ on Chrome or Firefox 2. Notice how the progress bars move together 3. Visit https://esbuild.github.io/ on Safari 4. Notice how the progress bars move separately at different speeds The animation is a simple linear CSS animation from left to right, and is completely broken in Safari.
Looks like this is also broken on the latest version of iOS (version 14.7.1).
Created attachment 435130 [details] HTML snapshot of the current state of https://esbuild.github.io/
Created attachment 435240 [details] Testcase
The broken animation has mismatched transform functions: @keyframes scale-bar { 0% { transform: scaleX(0) } to { transform: scale(1) } } so it interpolates via matrix interpolation. This appears to use the wrong timing function.
scaleX(0) is not invertible so we fall back to software animation.
This is about interpolation via matrix decomposition. We decompose the scaleX(0) matrix to: (WebCore::TransformationMatrix::Decomposed2Type) $1 = (scaleX = 0, scaleY = 1, translateX = 0, translateY = 0, angle = 0, m11 = 0, m12 = 0, m21 = 0, m22 = 1) and the scale(1) matrix to: (WebCore::TransformationMatrix::Decomposed2Type) $2 = (scaleX = 1, scaleY = 1, translateX = 0, translateY = 0, angle = 0, m11 = 1, m12 = 0, m21 = 0, m22 = 1) then interpolate scaleX and m11. Recomposing the matrix then causes m11 to affect scaleX in matrix[0][0]
<rdar://problem/81854922>
Thanks for determining the root cause. In that case I'm going to change https://esbuild.github.io/ to use a small but non-zero scale value to avoid a non-invertible matrix. This means the original repro steps will no longer work, but you will still be able to reproduce this with the attached test case.
A small scale would work. You could also use scale(x, y) or scaleX(x) in both keyframes.
> A small scale would work. You could also use scale(x, y) or scaleX(x) in both keyframes. Yes, but the problem is that CSS minifiers convert "scaleX(1)" into "scale(1)" and "scale(0, 1)" into "scaleX(0)", which prevents using both "scale" or both "scaleX" in this case if you're using a CSS minifier. See this code for example: https://github.com/cssnano/cssnano/blob/04bd16e9de5e2d4409fef74034edb7534cd9e457/packages/postcss-reduce-transforms/src/index.js#L93-L123. I believe that this CSS minification transformation is valid since these I'd expect for these forms to generate the equivalent matrix (i.e. "scaleX(0) == scale(0, 1)" and "scaleX(1) == scale(1, 1)"). Please let me know if that's not a valid CSS minification transformation and I can file an issue with the relevant CSS minifiers.
This is working fine in Safari 16.