Animation doesn't play when the following conditions are met: - container uses display: grid - container uses position: relative - element to animate uses position: absolute - element to animate doesn't start on the first grid column (grid-column-start: 2) code snippet for reproducing issue: ```html <!doctype html> <html lang="en"> <head> <style> .main { height: 100px; background-color: #cccccc; display: grid; grid-template-columns: auto 1fr auto; overflow: hidden; position: relative; } .progress-bar { bottom: 0; grid-column-start: 2; height: 20px; position: absolute; width: 100%; } .progress-bar-track { background-color: red; height: 100%; } .progress { animation: progress 3s linear forwards; } @keyframes progress { 0% { width: 100%; } 100% { width: 0; } } </style> </head> <body> <div class="main"> <div class="icon">icon</div> <div class="content">content</div> <div class="close">X</div> <div class="progress-bar"> <div class="progress-bar-track progress"></div> </div> </div> </body> </html> ```
Created attachment 460799 [details] test case https://codepen.io/webcompat/pen/QWmEoJz
Tested in Safari Technology Preview 16.0 Firefox Nightly 104.0a1 Google Chrome Canary 105.0.5172.0 Both Firefox and Chrome plays the animation.
<rdar://problem/96845845>
Resizing the window continuously makes the animation show in some way. My guess is that we correctly animate the data structures but there is some invalidation issue lurking here which makes the animation only show if something else forces a layout or redraw.
To be clear: the animation is for "width" and runs correctly but the rendering fails to update. If you open Web Inspector and pick the Graphics tab, you'll see the animation running and if you hover over it you'll see the target element overlay shrink.
Web inspector shows that layout is changing, and if I turn off grid it animates, so this is a grid repaint bug.
Created attachment 462362 [details] test case 2 This isn't really related to CSS animations, same problem when changing the width with JS. The problem seems to be that, if the width shrinks from e.g. 100px to 90px, then these 10px need to be repainted. However, if the 1st column is 1px wide, only 10-1=9 pixels will be repainted, the other pixel stays red. In the original testcase these non-repainted areas touch each other, so it seems the animation is not playing at all. But in this new testcase it's clearer what's happening.
Created attachment 462387 [details] test case 3 This is the minimal testcase for debugging.
Basically, the problem is in RenderGrid::layoutPositionedObject ```cpp RenderBlock::layoutPositionedObject(child, relayoutChildren, fixedPositionObjectsOnly); setLogicalOffsetForChild(child, ForColumns); setLogicalOffsetForChild(child, ForRows); ``` where RenderBlock::layoutPositionedObject ends up reaching RenderBox::frameRect like this: RenderBlock::layoutPositionedObject RenderElement::layoutIfNeeded RenderBlock::layout RenderBlockFlow::layoutBlock RenderBlockFlow::layoutBlockChildren RenderBlockFlow::layoutBlockChild RenderBlock::layout RenderBlockFlow::layoutBlock LayoutRepainter::LayoutRepainter RenderBox::outlineBoundsForRepaint RenderObject::localToContainerQuad RenderBox::mapLocalToContainer RenderBox::mapLocalToContainer RenderBox::offsetFromContainer RenderBox::topLeftLocationOffset RenderBox::frameRect But the m_frameRect hasn't been updated yet by setLogicalOffsetForChild! And calling setLogicalOffsetForChild first would have its own problems. I guess RenderGrid::layoutPositionedObject needs to use a different approach, it was also problematic for bug 209460. Changing the location after RenderBlock::layoutPositionedObject was done in bug 172117. Not sure in Rego or Sergio remember the details about this.