Overflow scroll on scaled child: different behavior on X and Y axis

Overflow scroll on scaled child: different behavior on X and Y axis



Here is a code showing my issue




.container
width: 200px;
height: 200px;
overflow: auto;


.child
width: 400px;
height: 400px;
/* When scaling down, no more X scrolling because size is 200px, but still Y scrolling :( */
transform: scale(0.5);
/* Both axis working the same (no more scrolling) when absolutely positioned */
/* position: absolute; */


/* Irrelevant styling */
.container
border: 2px solid palevioletred;
position: relative;


.child
background-color: pink;
transform-origin: top left;


<div class="container">
<div class="child">
Child
</div>
</div>

Try to scroll down or right within the box.



Then I scale down the child with a transformation, halving its size.



I can somewhat understand the behavior of each axis, but not why they're acting differently.



Ideally I'd like the Y axis to act like the X axis.



If I set position:absolute on the child, then the Y axis acts as the X axis (Both scrolls disappears).


position:absolute




.container
width: 200px;
height: 200px;
overflow: auto;


.child
width: 400px;
height: 400px;
position:absolute;
transform: scale(0.5);


/* Irrelevant styling */
.container
border: 2px solid palevioletred;
position: relative;


.child
background-color: pink;
transform-origin: top left;


<div class="container">
<div class="child">
Child
</div>
</div>

Try to scroll down or right within the box.



Same thing when I set display:inline-block. Both axis behave the sames (Both scrolls aren't affected by scale)


display:inline-block




.container
width: 200px;
height: 200px;
overflow: auto;


.child
width: 400px;
height: 400px;
display:inline-block;
transform: scale(0.5);


/* Irrelevant styling */
.container
border: 2px solid palevioletred;
position: relative;


.child
background-color: pink;
transform-origin: top left;


<div class="container">
<div class="child">
Child
</div>
</div>

Try to scroll down or right within the box.



Why in the initial case, we have a different behavior? And why in some cases, the scale change the scroll (when we used position:absolute) and in other cases it doesn't (when we used display:inline-block).


position:absolute


display:inline-block



As a side note, transform is a visual effect that doesn't affect the layout so logically the scroll shouldn't change in all the cases.


transform





here is another one: make the child element inline-block and the scroll will not change at all
– Temani Afif
Sep 3 '18 at 0:38






Hehe nice find :)
– Renaud
Sep 3 '18 at 19:42





I edited the question to add more details ;) let's hope it will attract more attention
– Temani Afif
Sep 3 '18 at 20:11






Thanks :) I forgot to mention it's working as intended on Edge (scrolling is never affected)
– Renaud
Sep 4 '18 at 8:23




2 Answers
2



I've found a few confusing statements in w3.org website about scollable overflow that might explain why the implementation is inconsistent. They look more like TODO marks, since it's a draft:



ISSUE 1:



There’s disagreement on the scrolling model. 2.1 apparently defined
that you scrolled the content area; the content would overflow the
content-box, and you would union that overflow with the content box to
find the scrollable area. In particular, this means that the content
would be offset by the start-sides padding, but if it overflowed, it
would go right to the edge on the end sides. This is what Firefox and
IE do. At least some authors (and spec authors) instead have the
mental model that the padding box is what’s scrollable, so when you
scroll to the end of the overflow, there’s the right/bottom padding.
Chrome/WebKit do this for the block axis, at least. They’re somewhat
inconsistent for the inline axis; there’s something weird about how
they handle lineboxes.



It seems that the block-axis padding is probably web-compatible to
honor. It’s unclear that the inline-axis padding will be. Further
experimentation is needed.



ISSUE 2:



Is this description of handling transforms sufficiently accurate?



Note:



The scrollable overflow rectangle is always a rectangle in the
box’s own coordinate system, but might be non-rectangular in other
coordinate systems due to transforms [CSS3-TRANSFORMS]. This means
scrollbars can sometimes appear when not actually necessary.



Anyway, it seems that we need to rely on "position:absolute" as a workaround for Chrome. Or transform the container instead of the child. Or even create an extra cointainer level.



Hope it helps!





The first issue seems only about padding, not about transforms. The second issue needs a little context. Could you please elaborate on that? The note seems only applicable on other coordinate systems and not on this question.
– JoostS
Sep 5 '18 at 22:14





Issue 1 refers to padding as it is described by w3c's "scrollable overflow" definition: "The scrollable overflow of a box is the set of things extending outside of that box’s padding edge for which a scrolling mechanism needs to be provided."
– Fabio Manzano
Sep 5 '18 at 22:24





Issue 2 refers to part of the scrollable overflow region: "the border boxes of all boxes for which it is the containing block and whose border boxes are positioned not wholly outside its block-start or inline-start padding edges, accounting for transforms by projecting each box onto the plane of the element that establishes its 3D rendering context."
– Fabio Manzano
Sep 5 '18 at 22:25





In general, I'm trying to point references proving that there's no solid definition for transformation behavior inside scrollable overflow.
– Fabio Manzano
Sep 5 '18 at 22:29






Thanks... good job!
– JoostS
Sep 5 '18 at 22:36



I believe the discrepancy in behaviour is linked to the transform-origin. When the origin is adjusted so that the child is placed to the right rather than the left (and the inline-block display removed), the horizontal scroll reappears and the child is only visible on scroll-over (see code snippet). As the child's default 'static' position (even without being transformed) would display from the top of the container, this is why it doesn't affect the vertical scroll in the same manner as I understand it.



As others have pointed out, there are outstanding tasks regarding CSS transforms. I would't regard it as a bug (although I see your point). Perhaps better explanations/more clarity will become available in future from the w3c.




.container
width: 200px;
height: 200px;
overflow: auto;
border: 2px solid palevioletred;
position: relative;


.child
width: 400px;
height: 400px;
transform: scale(0.5);
background-color: pink;
transform-origin: top right;


<div class="container">
<div class="child">
Child
</div>
</div>

Transform-origin changed to top right (as opposed to top left)



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)