Bug 1649239 Comment 7 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

(In reply to James Teh [:Jamie] from comment #6)
> Thanks for looking into this. The unfortunate reality is that I have absolutely no clue when it comes to most layout concepts, so I don't really know how to answer this well...
> 
> (In reply to Morgan Reschenberg [:morgan] from comment #4)
> > However! I dumped the frame tree and found something interesting -- our scrollable and ink overflows seem to match what safari and chrome report. 
> 
> What are scrollable and ink overflows? :) I kinda understand the concept of CSS overflow allowing things to flow outside their box, but I imagined that this would change the layout frame size accordingly. Is this not the case; is overflow actually drawn outside the frame? I thought everything that got drawn had to have a frame... but if so, where is the frame for this overflow stuff? Are there separate frames for overflow or something?

Sometimes we have frames that are a fixed size -- imagine, for example, the frame generated by the div in this snippet: `data:text/html,<div style="height: 100px; width: 100px; background: green"></div>`. The background color fits the frame exactly, creating a 100px green square. If I add text within that div, it won't automatically be truncated to fit within the 100x100 bounds. For example, something like `data:text/html,<div style="height: 100px; width: 100px; background: green">HelloWordThisIsAReallyLongSingleWordOfText</div>` means the div is still 100px by 100px, but the line within it overflows in the horizontal (inline-size) direction. The text doesn't expand the frame, so the text within the frame gets the green background, but the piece of the text that overflows has no background. 

The portion of the text that gets painted outside of the frame is what we call 'ink overflow' or 'visual overflow' (these mean the same thing).

Scrollable overflow is content that doesn't fit within the fixed frame size, but that also overflows the page boundary (or container boundary, if we're in a nested frame); its content that the user would have to scroll to be able to see. So, if I have a browser window that is 100px by 150px and I put 100px by 500px piece of text within the square frame in the previous example, I'd have 50px of ink overflow (the distance between the frame and the page bottom), and then I'd have 350px of scrollable overflow (the content that goes off the page, that I'd need to scroll to see). I'm not clear on whether or not scrollable overflow is a superset of ink overflow, but in any case, there's at least 350px of scrollable overflow in the previous example. 

As to your other questions the short answer is: it depends! The long answer is: 
We've talked about fixed frames, but frames are dynamically sized; they expand or shrink depending on their contents. You can think of this type of frame kinda like a dynamic text area -- the more you type in it, the larger (or longer) the input box becomes. In this type, there's really no way to "overflow" -- we're always expanding the frame so that its contents are bound within it. If you add something like "overflow: hidden", no ink or scrollable overflow is painted, if you add "overflow:scroll", then no ink overflow is painted, but scrollable overflow is (within the frame, with a scrollbar on the frame itself)

When we talk about overflow, we aren't talking about additional frames -- we're talking about additional rectangles. So for any one frame, there's (a) the rectangle generated by the frame itself, which might be fixed like in my examples (100x100) or dynamic (b) the rectangle generated by the ink overflow and (c) the rectangle generated by the scrollable overflow. These rects (which eventually become display list items if I remember right?) are all "owned" by the frame, but are not necessarily contained within the frame. By definition, overflow occurs outside the frame's bounds.
 
> > So I guess the question is, does it make sense to alter how we report position, size info (which I assume is through Bounds() ?) to report something like ink overflow instead of inherent frame size for some subset of accessibles? 
> 
> I fear  my understanding is too limited to know what impact this would have. On the other hand, what we're doing right now is clearly broken somehow, so I think everything is on the table at this point. :)
> 
> I guess one question is: if ink/scrollable overflow can report bounds outside a 0-sized frame, I assume they can also report bounds outside of a non-0-sized frame? If so, should we *always* be taking ink/scrollable overflow into account... somehow?

yeah, this was my feeling -- I think ink overflow is a reasonable choice here. If something is visible but overflows the frame, the visual focus is still on the entire element, not just the frame-contained piece (especially when frames have no visible boundary, like in the icloud example). It might make sense to have AT's "focus" in the same way.  

> (In reply to Morgan Reschenberg [:morgan] from comment #5)
> > ```
> > *aBoundingFrame = nsLayoutUtils::GetContainingBlockForClientRect(frame);
> >     nsRect unionRect = nsLayoutUtils::GetAllInFlowRectsUnion(
> >         frame, *aBoundingFrame, nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
> > ```
> 
> Ug. Now I have more questions. What do we mean by bounding frame here? Is the bounding frame the nearest frame completely enclosing this frame... or is it something larger than that? I guess GetAllInFlowRectsUnion is expanding to cover overflow as well... but couldn't we overflow outside the nearest bounding frame? I'm so confused... :(

its okay! a bounding frame is something that constrains your ink or scrollable overflow. Think about this example: `data:text/html,<div style="height:200px; width:100px; background:green; overflow:hidden;"><div style="background:blue;">HelloIAmSomeReallyLongTextThatOverflowsThisFrame</div></div>`

We have an outer frame, of a fixed size, that is "overflow:hidden", this means anything that would be ink or scrollable overflow will be clipped to the frame boundary and won't be painted. The inner frame, however, has no such constraint. It has no fixed size and no overflow rule, which means if it were to stand alone on the page (without its parent), it would expand or shrink to fit the amount of text in it. When I add a really long string of text, like I've done in the example, two things happen:

- The inner frame expands to the length of the text string (which is longer than 100px). There is no overflow generated by this frame's contents, but this frame itself does generate overflow for the outer frame because its width now exceeds the width of its parent.
- The outer frame looks at the inner frame's size (greater than its width) and applies the overflow:hidden property, clipping the text off at the outer frame's boundary (so visually only "HelloIAmSome" is painted). 

In this example, the out frame is the bounding frame for the inner one. If we didn't have the "overflow:hidden" property on the outer frame, then the bounding frame would be the root frame/web area. 

> > `// Note: the ink overflow rect already combines overflow from the things in-flow, so we don't need to aggregate here like above`
> 
> This makes me wonder even more whether we should just be always using ink overflow?

Yeah this is sorta my thought, and I think this is what Safari and Chrome do -- though I'd love to confirm by dumping the frame trees there. I can reach out to layout folks to see if that's possible :) It'd be good data to have.

> I realise you may not have answers to some of this, but it seems like we might need to get some of those answers before we can make an informed decision here. Or I guess we can just try it and see what breaks, but that makes me a little nervous given the craziness on the wild web.

Let me know if you have other questions! hopefully the examples are helpful 🤞
> What are scrollable and ink overflows? :) I kinda understand the concept of CSS overflow allowing things to flow outside their box, but I imagined that this would change the layout frame size accordingly. Is this not the case; is overflow actually drawn outside the frame? I thought everything that got drawn had to have a frame... but if so, where is the frame for this overflow stuff? Are there separate frames for overflow or something?

Sometimes we have frames that are a fixed size -- imagine, for example, the frame generated by the div in this snippet: `data:text/html,<div style="height: 100px; width: 100px; background: green"></div>`. The background color fits the frame exactly, creating a 100px green square. If I add text within that div, it won't automatically be truncated to fit within the 100x100 bounds. For example, something like `data:text/html,<div style="height: 100px; width: 100px; background: green">HelloWordThisIsAReallyLongSingleWordOfText</div>` means the div is still 100px by 100px, but the line within it overflows in the horizontal (inline-size) direction. The text doesn't expand the frame, so the text within the frame gets the green background, but the piece of the text that overflows has no background. 

The portion of the text that gets painted outside of the frame is what we call 'ink overflow' or 'visual overflow' (these mean the same thing).

Scrollable overflow is content that doesn't fit within the fixed frame size, but that also overflows the page boundary (or container boundary, if we're in a nested frame); its content that the user would have to scroll to be able to see. So, if I have a browser window that is 100px by 150px and I put 100px by 500px piece of text within the square frame in the previous example, I'd have 50px of ink overflow (the distance between the frame and the page bottom), and then I'd have 350px of scrollable overflow (the content that goes off the page, that I'd need to scroll to see). I'm not clear on whether or not scrollable overflow is a superset of ink overflow, but in any case, there's at least 350px of scrollable overflow in the previous example. 

As to your other questions the short answer is: it depends! The long answer is: 
We've talked about fixed frames, but frames are dynamically sized; they expand or shrink depending on their contents. You can think of this type of frame kinda like a dynamic text area -- the more you type in it, the larger (or longer) the input box becomes. In this type, there's really no way to "overflow" -- we're always expanding the frame so that its contents are bound within it. If you add something like "overflow: hidden", no ink or scrollable overflow is painted, if you add "overflow:scroll", then no ink overflow is painted, but scrollable overflow is (within the frame, with a scrollbar on the frame itself)

When we talk about overflow, we aren't talking about additional frames -- we're talking about additional rectangles. So for any one frame, there's (a) the rectangle generated by the frame itself, which might be fixed like in my examples (100x100) or dynamic (b) the rectangle generated by the ink overflow and (c) the rectangle generated by the scrollable overflow. These rects (which eventually become display list items if I remember right?) are all "owned" by the frame, but are not necessarily contained within the frame. By definition, overflow occurs outside the frame's bounds.
 
> > So I guess the question is, does it make sense to alter how we report position, size info (which I assume is through Bounds() ?) to report something like ink overflow instead of inherent frame size for some subset of accessibles? 
> 
> I fear  my understanding is too limited to know what impact this would have. On the other hand, what we're doing right now is clearly broken somehow, so I think everything is on the table at this point. :)
> 
> I guess one question is: if ink/scrollable overflow can report bounds outside a 0-sized frame, I assume they can also report bounds outside of a non-0-sized frame? If so, should we *always* be taking ink/scrollable overflow into account... somehow?

yeah, this was my feeling -- I think ink overflow is a reasonable choice here. If something is visible but overflows the frame, the visual focus is still on the entire element, not just the frame-contained piece (especially when frames have no visible boundary, like in the icloud example). It might make sense to have AT's "focus" in the same way.  

> (In reply to Morgan Reschenberg [:morgan] from comment #5)
> > ```
> > *aBoundingFrame = nsLayoutUtils::GetContainingBlockForClientRect(frame);
> >     nsRect unionRect = nsLayoutUtils::GetAllInFlowRectsUnion(
> >         frame, *aBoundingFrame, nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
> > ```
> 
> Ug. Now I have more questions. What do we mean by bounding frame here? Is the bounding frame the nearest frame completely enclosing this frame... or is it something larger than that? I guess GetAllInFlowRectsUnion is expanding to cover overflow as well... but couldn't we overflow outside the nearest bounding frame? I'm so confused... :(

its okay! a bounding frame is something that constrains your ink or scrollable overflow. Think about this example: `data:text/html,<div style="height:200px; width:100px; background:green; overflow:hidden;"><div style="background:blue;">HelloIAmSomeReallyLongTextThatOverflowsThisFrame</div></div>`

We have an outer frame, of a fixed size, that is "overflow:hidden", this means anything that would be ink or scrollable overflow will be clipped to the frame boundary and won't be painted. The inner frame, however, has no such constraint. It has no fixed size and no overflow rule, which means if it were to stand alone on the page (without its parent), it would expand or shrink to fit the amount of text in it. When I add a really long string of text, like I've done in the example, two things happen:

- The inner frame expands to the length of the text string (which is longer than 100px). There is no overflow generated by this frame's contents, but this frame itself does generate overflow for the outer frame because its width now exceeds the width of its parent.
- The outer frame looks at the inner frame's size (greater than its width) and applies the overflow:hidden property, clipping the text off at the outer frame's boundary (so visually only "HelloIAmSome" is painted). 

In this example, the out frame is the bounding frame for the inner one. If we didn't have the "overflow:hidden" property on the outer frame, then the bounding frame would be the root frame/web area. 

> > `// Note: the ink overflow rect already combines overflow from the things in-flow, so we don't need to aggregate here like above`
> 
> This makes me wonder even more whether we should just be always using ink overflow?

Yeah this is sorta my thought, and I think this is what Safari and Chrome do -- though I'd love to confirm by dumping the frame trees there. I can reach out to layout folks to see if that's possible :) It'd be good data to have.

> I realise you may not have answers to some of this, but it seems like we might need to get some of those answers before we can make an informed decision here. Or I guess we can just try it and see what breaks, but that makes me a little nervous given the craziness on the wild web.

Let me know if you have other questions! hopefully the examples are helpful 🤞

Back to Bug 1649239 Comment 7