RESOLVED DUPLICATE of bug 156435 164949
-webkit-overflow-scrolling: touch completely breaks 3D perspective functionality
https://bugs.webkit.org/show_bug.cgi?id=164949
Summary -webkit-overflow-scrolling: touch completely breaks 3D perspective functionality
AliG
Reported 2016-11-18 13:27:19 PST
CSS perspective and translateZ provide an efficient way of creating scroll parallax effect however in iOS Safari, adding -webkit-overflow-scrolling: touch; completely breaks all the 3D and perspective effects. Please see http://codepen.io/aghassemi/pen/QGdKbZ for an example. The only difference between the two divs is the value of webkit-overflow-scrolling but notice how perspective is ignored on the second div.
Attachments
testcase (547 bytes, text/html)
2018-05-22 01:02 PDT, Frédéric Wang (:fredw)
no flags
Radar WebKit Bug Importer
Comment 1 2016-12-01 12:42:09 PST
Jayden Seric
Comment 2 2018-01-09 03:03:47 PST
Sad to see there has been no activity for over a year for such a visually disruptive bug without a decent workaround. This is the best I could come up with for displaying a scrollable list of cards, stacked on an angle. It looks weird though because there is not a single perspective origin: .container { perspective: 1000px; overflow: auto; -webkit-overflow-scrolling: touch; } .child { transform: rotateY(45deg); } @supports (-webkit-overflow-scrolling: touch) { .container { perspective: none; } .child { transform: perspective(1000px) rotateY(45deg); } }
Frédéric Wang (:fredw)
Comment 3 2018-05-22 01:02:41 PDT
Created attachment 340960 [details] testcase
Frédéric Wang (:fredw)
Comment 4 2018-05-22 05:43:45 PDT
Some preliminary debugging: When webkit-overflow-scrolling is absent RenderLayerCompositor::computeCompositingRequirements will execute if (!willBeComposited && canBeComposited(layer) && requiresCompositingForIndirectReason(layer.renderer(), childState.subtreeIsCompositing, anyDescendantHas3DTransform, indirectCompositingReason)) { layer.setIndirectCompositingReason(indirectCompositingReason); childState.compositingAncestor = &layer; overlapMap.pushCompositingContainer(); addToOverlapMapRecursive(overlapMap, layer); willBeComposited = true; } where requiresCompositingForIndirectReason returns true because of the perspective property on the overflow node and the 3D transform on its descendants. If the overflow node has overflow-scrolling:touch, willBeComposited is however set to true at the top of the function so this conditional is never executed. I'm not yet sure how/whether this is causing the bug, though.
Ali Juma
Comment 5 2018-05-22 06:53:33 PDT
(In reply to Frédéric Wang (:fredw) from comment #4) > Some preliminary debugging: When webkit-overflow-scrolling is absent > RenderLayerCompositor::computeCompositingRequirements will execute > > if (!willBeComposited && canBeComposited(layer) > && requiresCompositingForIndirectReason(layer.renderer(), > childState.subtreeIsCompositing, anyDescendantHas3DTransform, > indirectCompositingReason)) { > layer.setIndirectCompositingReason(indirectCompositingReason); > childState.compositingAncestor = &layer; > overlapMap.pushCompositingContainer(); > addToOverlapMapRecursive(overlapMap, layer); > willBeComposited = true; > } > > where requiresCompositingForIndirectReason returns true because of the > perspective property on the overflow node and the 3D transform on its > descendants. If the overflow node has overflow-scrolling:touch, > willBeComposited is however set to true at the top of the function so this > conditional is never executed. I'm not yet sure how/whether this is causing > the bug, though. I'd suggest looking at the corresponding RenderLayerBacking to see which GraphicsLayers are created, and which of these GraphicsLayers have preserves3D() true. Probably in the overflow-scrolling:touch case, there's a GraphicsLayer which ends up flattening the transform (because of preserves3D() being false), so the Z component ends up having no visual effect.
Frédéric Wang (:fredw)
Comment 6 2018-05-22 06:56:26 PDT
(In reply to Ali Juma from comment #5) > I'd suggest looking at the corresponding RenderLayerBacking to see which > GraphicsLayers are created, and which of these GraphicsLayers have > preserves3D() true. Probably in the overflow-scrolling:touch case, there's a > GraphicsLayer which ends up flattening the transform (because of > preserves3D() being false), so the Z component ends up having no visual > effect. Thanks for the hint! Indeed I started to debug RenderLayerBacking this morning and the perspective / z-translate transform seemed to be correctly taken into account. I'll check preserves3D later...
Simon Fraser (smfr)
Comment 7 2018-05-22 08:30:51 PDT
I think this is because, in the WebKit 3D transforms implementation, overflow necessarily triggers flattening, turning off preserve-3D.
Simon Fraser (smfr)
Comment 8 2018-05-23 11:48:14 PDT
if (style.preserves3D() && (style.overflowX() != OVISIBLE || style.overflowY() != OVISIBLE ... style.setTransformStyle3D(TransformStyle3DFlat);
Frédéric Wang (:fredw)
Comment 9 2018-05-23 12:12:03 PDT
Thanks, this code was added a long time ago in bug 83337. "The CSS3 Transforms spec says that some properties should cause flattening of things with transform-style: preserve-3d." Is it still valid? I can't find it in https://www.w3.org/TR/css-transforms/
Simon Fraser (smfr)
Comment 10 2018-05-23 12:32:01 PDT
Frédéric Wang (:fredw)
Comment 11 2018-05-30 07:21:21 PDT
(In reply to Simon Fraser (smfr) from comment #8) > if (style.preserves3D() && (style.overflowX() != OVISIBLE > || style.overflowY() != OVISIBLE > ... > style.setTransformStyle3D(TransformStyle3DFlat); That code is only executed when the element has "transform-style: preserve-3d;" (which is not the case in the repro cases) so probably the flattening happens somewhere else.
Jayden Seric
Comment 12 2019-10-29 18:05:03 PDT
(In reply to Jayden Seric from comment #2) > Sad to see there has been no activity for over a year for such a visually > disruptive bug without a decent workaround. > > This is the best I could come up with for displaying a scrollable list of > cards, stacked on an angle. It looks weird though because there is not a > single perspective origin: > > .container { > perspective: 1000px; > overflow: auto; > -webkit-overflow-scrolling: touch; > } > > .child { > transform: rotateY(45deg); > } > > @supports (-webkit-overflow-scrolling: touch) { > .container { > perspective: none; > } > .child { > transform: perspective(1000px) rotateY(45deg); > } > } -webkit-overflow-scrolling: touch was deprecated in Safari 13 for iPad (but not iPhone): https://developer.apple.com/documentation/safari_release_notes/safari_13_release_notes#3314667 This means @supports (-webkit-overflow-scrolling: touch) can't be used anymore for a workaround. The perspective for all the scrollable 3d cards on my live websites are now broken on iPad! Not sure the best way to deal with this, some dirty user agent sniffing?
Simon Fraser (smfr)
Comment 13 2019-10-29 18:25:27 PDT
*** This bug has been marked as a duplicate of bug 156435 ***
Frédéric Wang (:fredw)
Comment 14 2020-06-26 07:36:42 PDT
(In reply to Simon Fraser (smfr) from comment #13) > > *** This bug has been marked as a duplicate of bug 156435 *** Thanks Simon. The testcase seems to work in iOS 14 beta
Note You need to log in before you can comment on or make changes to this bug.