-
Notifications
You must be signed in to change notification settings - Fork 715
[css-sizing-4] Scrollbars when intrinsic-width is > width? #4415
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@frivoal Does anything need to be done in Overflow to make this happen? I'm unclear if overflowing happens automatically as a result of intrinsic sizes, or from something more explicit that's essentially the same thing. |
If the But that brings up the question: Do we, in general, have a good definition of how intrinsic/extrinsic sizing, the box model, and scroll overflow work? Because if not, this would be a good time to define it. |
TL;DR: If you want to cause/avoid scrollbars, you need to change the actual size of then content so that it does/doesn't stick out, not the size of the (potentially) scrolling element. If you have an image with 200px intrinsic width, and you set its width to 100px, then it doesn't overflow 100px anymore. By that logic, That's consistent with the point of view of the css-overflow spec (emphasis mine):
However, it gets more interesting/complicated when you consider the min-content size. In most layout modes, the initial value of If a parent/container has overflow:auto and is limited to 100px, then we'll overflow an show scrollbars. But you were asking about the element itself having scrollbars or not, not a container. I think if we don't do/say anything special, the above logic says that it would not. It would just be the size you gave it, and the overflowing or not would depend on the actual size of the element's content. And since fiddling with the element's intrinsic size doesn't do anything to the element's content, I think that behavior is reasonable. A while back, @Loirooriol proposed a div {
intrinsic-width: 200px;
/* and maybe "min-width: min-content;" */
width: 100px;
overflow:auto;
} you'd do div::contents {
display: block; /*the default is display: contents; */
intrinsic-width: 200px;
min-width: min-content;
}
div {
width: 100px;
overflow:auto;
} I suppose we could define something analogous to that to happen automatically for non replaced elements when you assign an I think this way of looking at it works even better if consider the other direction: assigning a smaller than natural intrinsic width a non replaced element. <div>123456789</div> div {
font-family: monospace;
intrinsic-width: 2ch;
/* and maybe "max-width: max-content;" */
width: 4ch;
overflow: auto;
} I don't really see what logic would cause the content to honor the intrinsic size and by fitting, causing the absence of scrollbar in that case. However, you could do something like that: div {
font-family: monospace;
width: 4ch;
overflow: auto;
}
div::contents {
display: block;
intrinsic-width: 2ch;
max-width: max-content;
overflow: hidden; /* or ''overflow-wrap: break-words'',
or " contain: strict",
or some other thing to force the content
to actually stay within the requested max-size. */
} |
Cool, so that confirms that the spec needs a fix, then. ^_^ The point of
In this case we should still pop scrollbars; the contents will still project layout overflow, just not affect intrinsic size itself. |
Is it? It feels to me that it is to replace the calculations of "how big am I", which typically depends on content, but isn't the same. Anyway, leaving the possibility of Asking differently, especially given that it doesn't obviously fall out of how things work, I'd like to see a use-case for wanting scrollbars based on the intrinsic size when there's not actual content to scroll to. |
As anecdotal evidence, and not at all first hand experience, it is common for developers implementing virtual scrollers to have spacer divs placed inside scrollers in order to size the scrollbar to give the impression of long content. When the user scrolls close to the region without "real" content, script would shrink the spacer and replace it with "real" content instead. If intrinsic-height is considered during overflow calculation (ie for overflow purposes, it would the max of intrinsic-height and the height of real contents), then this pattern is much easier achieved by simply specifying the intrinsic-height of the scroller. There would be no need to fiddle with or recalculate the size of the spacer, which wouldn't be required at all. |
This is a common request of web-developers which is (as Vlad said) - done with placeholder elements today. For an example see: From personal experience (when I was a front-end engineer) I used a dummy element to crate scrollable overflow whenever I built scrollers which loaded additional content. cc/ @surma who might be able to provide additional context. |
No, "how big am I" is already handled by 'width' and 'height'. This is definitely replacing "how big are my contents", specifically for the purpose of working with the async-rendering stuff that delays laying out/rendering a container's contents until needed. And that's precisely what the "intrinsic size" concept covers - what's the minimum and maximum size that my content can make me. Further, as Ian and Vlad said in their comments, people are already commonly using hacks to create scrollbars that look approximately right when doing virtual rendering on their own, and having this property provide that functionality intrinsically seems like a nice accidental win. Whether or not to generate scrollbars should, of course, be determined by the larger of the intrinsic-size value and the actual size of the contents, so we don't hide content by accidentally making it unscrollable; this is particularly important for the case where "intrinsic-size: 0;" is used to override the bad intrinsic sizing behavior of scrollable elements in grid/flexbox! |
Questions:
@tabatkins and I are leaning towards it only affects the scrollable overflow area of the contained element itself, if it happens to be a scroll container. |
Proposed wording (appended sentence marked with INS):
|
So the other question is how the scrollbar size should affect the intrinsic size. I guess what happens is, if one axis is specified and contain-intrinsic-size causes overflow in that direction, the scrollbar size is added to the intrinsic size in the other direction...? |
The CSS Working Group just discussed The full IRC log of that discussion<dael> Topic: [css-sizing-4] Scrollbars when intrinsic-width is > width?<dael> github: https://github.com//issues/4415#issuecomment-614345165 <dael> fantasai: Does the phantom content area thing also effect scrolable area? If it does only the contained element or also contents outside of the element? <dael> TabAtkins: Cases for first is your container is 100px.100px and overflow:auto Set contain-intrinisc-size to 200x200 We say you did your child and results in 200x200 and you ahve scrollbars. We believe you shouldg et them. Objections in issue were from a previous definition <dael> TabAtkins: If you have overflow:visible and contain-intrinisic-size to be overflowing value does it set scrollbars elsewhere <dael> AmeliaBR: Clarification: does the contain-intrinsic-size otherwise trigger containment or are you expected to set type and than size? <dael> TabAtkins: ONly applies if size-containment is on <dael> AmeliaBR: So it's separate prop. Doesn't size-containment already have effects on if your'e triggering scrollers on ancestors? <dael> TabAtkins: No, layout does. <dael> AmeliaBR: My intist is keep it as simple as possible and require containment property to spec any trapping of scrolling and whatever <dael> TabAtkins: So it shoudl cause overflow in those cases? <dael> AmeliaBR: Behave same as if child contents had been layed out and generated that intrinsis size <dael> vmpstr: Combined with actual child content? Union of 2? <AmeliaBR> s/intist/instinct/ <dael> TabAtkins: For scrollbars calc yes. It does get combined with actual children <dael> ??: When you say calc scrollbars do you mean prsense? Scrollbars can effect size. <fantasai> s/??/biesi <dael> TabAtkins: Scrollbars don't increase size of element, jsut content <cbiesinger> s/biesi/cbiesinger/ <dael> AmeliaBR: Came up on issue, is intrinsic with or w/o size of scrollbard. Do you add it on top? <dael> TabAtkins: Scrollbars decrease size of content area. <dael> cbiesinger: It can in the block axis. [missed] <cbiesinger> s/missed/it can also get larger in the inline axis, at least in chrome, if it is shrinkwrapped-sized/ <dael> TabAtkins: Can't be the case...wait...if you turn on overflow scroll than scrollbar adds to content area. If you have overflow auto that will never increase area in a way problematic here. <dael> TabAtkins: Only time it will trigger is if you have fixed height <dael> cbiesinger: Auto height and you set multiplier overflow in inline axis increases size in block axis <dael> Rossen___: Only if height is fixed so it is stable <dael> cbiesinger: Why is height fixed <dael> Rossen___: b/c for intrinisic size purpos you always fit if auto <dael> fantasai: Scrollbars increase in opp size of scroll. cbiesinger Is correct <dael> TabAtkins: So yes, if you trigger scrollbar on bottom of element the height would be contain-intrinsic-size height + scrollbar <Rossen___> q? <dael> cbiesinger: Still doesn't matter if has to be union b/c you don't know actual content size. If guess that's the answer is you don't use the union for purpose of scrollabel <dael> TabAtkins: Yeah. <cbiesinger> s/scrollabel/scrollbar presence/ <dael> TabAtkins: Actual content should not effect the size for purpose of telling if have scrollbars...i guess...once you do... <dael> TabAtkins: Back up. I think this is a diversion. Need to answer, but I don't think effects current q. Should ctonain intrinsic size if larger than spec size trigger scrollbars <dael> AmeliaBR: I think my argument is same, it should behave same as if you had one child element of that size and anything about scrollbars fall out of that <dael> cbiesinger: So aginst using union of actual size and contain-intrinisic-size? <dael> AmeliaBR: Whole point of cis is replace calc actual size of child content <dael> florian: Not sure it's eq. If regular block yes, but multicol for example... <dael> TabAtkins: She mispoke. It's the result of laying out your content. <dael> AmeliaBR: Yeah. <dael> TabAtkins: Not on children, it's just easy to say accidently <dael> Rossen___: We're about 5 minutes before and fantasai wanted to go over F2F. Can we close on this or continue in issue? <dael> TabAtkins: There's further detail question, but shoudl not effect how actual content of a contain-size elemtn. If actual content can pop a scrollbar that will continue to. If can't will continue. <dael> florian: TabAtkins I stopped watching on GH a while back. Your assertion that my concern used to be valid I don't rmemeber. Can I jsut trust you? <dael> TabAtkins: I think you can. It was about images not triggering scrollbars. <dael> fantasai: I suggest we pick this up later and do F2F |
For next time, one possible proposed resolution is:
We clearly have some confusion about what that should mean in the details (e.g., differences between |
I'll just note that Amelia's proposal is incompatible with fantasai's proposed spec text above:
To me, the inflating is where the scrollbar difficulties come from. |
To clarify, your concern is, what happens if the actual child content triggers a scrollbar when the intrinsic size didn't? In a simple interpretation of “fit both”, the intrinsic size would then trigger a scrollbar in the other axis, because the first scrollbar reduced the available content size. Yeah, I was assuming that once you had real intrinsic size to work with, the |
Yeah, but that's incompatible with
Indeed! |
The CSS Working Group just discussed
The full IRC log of that discussion<fantasai> Topic: Scrollbars when intrinsic-width is > width?<fantasai> github: https://github.com//issues/4415#issuecomment-614345165 <tantek> wow this seems like a historically painful one <fantasai> TabAtkins: Following along from the linked "top of thread" <fantasai> TabAtkins: now that contain-intrinsic-size defined to give result of doing child layout <fantasai> TabAtkins: basically, pretend that bounding box of your laid-out contents is this size <fantasai> TabAtkins: Should that trigger scrollbars or not? <fantasai> TabAtkins: we think it should <fantasai> TabAtkins: because if the contents were that large, they would indeed create scrollbars <fantasai> TabAtkins: And we're saying, here's a shortcut to running your layout <fantasai> TabAtkins: biesi brought up question of what does this mean for intrinsic size? <fantasai> TabAtkins: is the intrinsic size that plus crollbars or what? <fantasai> TabAtkins: Have a specified width, contain-intrinsic-size is wider than that, adds a scrollbar to the bottom <fantasai> s/width/width and auto height/ <fantasai> TabAtkins: Result of applying that is that width is specified width, auto height is resolved according to 'contain-intrinsic-size' plus mbp <fantasai> TabAtkins: if you add 'overflow: auto' <fantasai> TabAtkins: contents wider than box would add a horizontal scrollbar to the bottom <fantasai> TabAtkins: would height of scrollbar be added to the auto height? <fantasai> s/height/height (based on contain-intrinsic-size)/ <fantasai> cbiesinger: There was a proposal in the issue that the used size should be max of actual content size and contain-intrinsic size, and that is where it gets complicated <fantasai> cbiesinger: because then you need to know the actual content size to know whether there's a scrollbar <fantasai> iank_: For purposes of layout overflow calcualtion, the content size rectangle is unioned with previous calc? <fantasai> TabAtkins: stepping away from contain-itnrinsic-size for the moment <fantasai> TabAtkins: if you have contain + overflow: auto <fantasai> TabAtkins: assume zero size content <fantasai> TabAtkins: if you add content, can you not scroll to it? <fantasai> iank_: depends on impl <fantasai> iank_: we will currently add scrollbars, rerun layout <fantasai> iank_: This will affect intrinsic size of the box <fantasai> iank_: unsure what ff does <fantasai> dholbert: we do not do that relayout <fantasai> dholbert: we treat it as zero height / width as if explicitly specified <fantasai> dholbert: in the case of zero width/height, you wouldn't see it <fantasai> cbiesinger: Don't remember how we handle this, we maybe increase the size of the element <fantasai> TabAtkins: dholbert, if you have 'contain: size' element with specified height of '100px' and ? <fantasai> TabAtkins: would you say that ff wont' show scrollbars? <fantasai> dholbert: if we have space to show scrollbars we will <fantasai> dholbert: just won't influence sizing of the box <fantasai> TabAtkins: That's reasonable to me, and if that's what we want to be more specific about, I'm fine with doing that <fantasai> cbiesinger: I think that's more reasonable behavior <fantasai> AmeliaBR: Balance of that is, if there is room for scrollbars we will put them <fantasai> AmeliaBR: if the intrinsic size is bigger than contain size <fantasai> AmeliaBR: [...] <fantasai> cbiesinger: Downside is that you'll definitely get scrollbars in the other side, too <fantasai> TabAtkins: oh, yes, becaue if you say `contain-intrinsic-size: 200px` <fantasai> TabAtkins: ... <fantasai> AmeliaBR: proposal I suggested was that, as soon as you know you have scrollbars, you only do either the intrinsic sizing or the content and the intrinsic size goes away <fantasai> AmeliaBR: Another thing I just thought of is we have an option for an overflow value where the scrollbars never take away content size <fantasai> AmeliaBR: is there a way maybe to say, for the purpose of the 'contain-intrinsic-size' calculation, we always treat as overlay scrollbar instead of as scrollbar that takes away content size? <fantasai> AmeliaBR: while still laying out content size as normal? <fantasai> TabAtkins: in other words, treat 'contain-intrinsic-size' rectangle as ignoring scrollbar for determining if there's overflow in a given axis <AmeliaBR> s/content size/the actual content/ <TabAtkins> SCribeNick: TabAtkins <TabAtkins> fantasai: I think we should say the actual scrollable overflow area is the union of the content and c-i-s <TabAtkins> fantasai: But size the box as if the scrollable overflow area is only the area given by c-i-s <TabAtkins> fantasai: You'll possibly need to add a scrollbar then, but it's only dependent on c-i-s, not content <AmeliaBR> s/[...]/then there will be scrollbars, the same as for content larger than for the contained size/ <astearns> ack fantasai <tantek> I was only able to follow partially as well. <TabAtkins> fantasai: If your c-i-s is accurate (matches content size), you'll get scrollbars, and size will accommodate the scrollbars as you'd expect <TabAtkins> fantasai: if c-i-s is too big, you'll get to scroll to more area than the contenta ctually takes <tantek> As much as we want to avoid having unviewable content, I'd also like to see us adopt a principle of making it *easy* for web authors to avoid automatic scrollbars showing up especially when "it doesn't seem like they should be needed" <TabAtkins> fantasai: if c-i-s is too small, you might get two scrollbars rathe rthan one, but you'll still bea ble to scroll to everyone <TabAtkins> cbiesinger: The scrollbar is still in the area defined by c-i-s, right? <TabAtkins> fantasai: If you have an element sized to fit content exactly, and then you set that size explicitly, then add more content that creates a scrollbar, you end up adding a scrollbar to the bottom as well. <tantek> yeah I pretty much hate this problem <TabAtkins> fantasai: So you can still scroll to see everything, but one of the scrollbars might just be scrolling a tiny bit <TabAtkins> fantasai: You'll get into that situation if your c-i-s is inaccurate. <TabAtkins> cbiesinger: I think if you overflow in one direction, you'll alway sget two scrollbars. <tantek> would really prefer to avoid situations where we make the layout so scrollbar-fragile that it's too easy to cause scrollbars <dholbert> q+ <TabAtkins> fantasai: Say you have 100x100 box, c-i-s is 200px tall, ou'll get a vertical scrollbar <TabAtkins> cbiesinger: If your scrollable area is the union of content and c-i-s <TabAtkins> cbiesinger: Then c-i-s needs to be scrollable-to. And since scrollbar is in that area defined by c-i-s, you'll always need a scrollbar for it. <tantek> in particular when a vertical scrollbar shows up e.g. due to fantasai's example, it should not *also* cause a horizontal scrollbar <tantek> that's a particularly bad side-effect to avoid <fantasai> ScribeNick: fantasai <fantasai> fantasai: No, that's not what I'm saying <fantasai> fantasai: What I'm saying is, you size based on c-i-size <cbiesinger> <div style="width: 100px; contain-intrinsic-size: 100px 100px; overflow: auto;"><div style="width: 120px;"></div></div> <fantasai> fantasai: and c-i-size increases size of scrollable overflow area <fantasai> fantasai: potentially causing scrollbars, which get accounted for <fantasai> fantasai: based on that, you size the box. <cbiesinger> you get a horiz scrollbar. this covers up the bottom 15px or so of the 100px c-i-s <fantasai> fantasai: then after you lay out the contents, you increase the scrollable overflow area (if needed) to fit the contents, so that you're not clipping anything <cbiesinger> but the scrollable area is the union of actual contant and c-i-s <fantasai> fantasai: this increases the size of the scrollable overflow area, but does not change the size ofthe box <cbiesinger> so you need to be able to scroll to that <cbiesinger> no? <fantasai> fantasai: so you might get extra scrollbars added if your c-i-s value wasn't accurate. But at least you can see all the contents <fantasai> TabAtkins: So, example here, you have a float <fantasai> TabAtkins: it as contain-intrinsic-size of 200px x 200px <fantasai> TabAtkins: specified height of 100px <fantasai> TabAtkins: this should create a vertical scrollbaron the right <fantasai> TabAtkins: what should be the float's width, assuming no mbp? <fantasai> TabAtkins: Should it be 200px or 216px, to account for scrollbar <tantek> Thank you Tabatkings, that's exactly the problem I was referring to <cbiesinger> yes, that's what I was asking too <fantasai> fantasai: Yes, it would be 216px <tantek> s/Tabatkings/TabAtkins <TabAtkins> cbiesinger: How can that be 216px if the scrollbar doesn't affec the size of the box? <fantasai> AmeliaBR: ... <fantasai> AmeliaBR: but if scrollbar is created by c-i-s, that affects the size of the box <TabAtkins> AmeliaBR: So a scrollbar form content shouldn't affect the size of the box, but a scrollbar from c-i-s should affect the size of the box? <fantasai> AmeliaBR: if we're in a context where just the dimensions that we have on the container, combination of explicit sizes plus contain-itnrinsic-size are enough to create a scrollbar <fantasai> AmeliaBR: and usually scrollbar would be outside the content <fantasai> AmeliaBR: normally a scrollbar would go inside defined widht of container <fantasai> AmeliaBR: but not necessarily in something like a float, which doesn't have a defined width <cbiesinger> <div style="width: 100px; contain-intrinsic-size: 100px 100px; overflow: auto;"><div style="width: 120px;"></div></div> <fantasai> fantasai: ... <TabAtkins> fantasai: In that example, <fantasai> cbiesinger: You end up a horizontal and a vertical scrollbar <TabAtkins> fantasai: Your width is specified, so it won't grow. cis width is fine. There's no height specified, so it sizes to 100px tall. <iank_> https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=8034 <fantasai> cbiesinger: because horizontal scrollbar takes up space <iank_> (view in chrome canary) <fantasai> fantasai: yes. But size of box would be 100px, doesn't grow <TabAtkins> cbiesinger: Right, then the content is 120px tall, so you need a vertical scrollbar. And that covers up part of the 100px cis, so you get a horiz scrollbar too <TabAtkins> fantasai: yes <fantasai> dholbert: I think mental model of it that makes sense: <fantasai> dholbert: sounds like we size scrollable overflow area as if only one child size of c-i-s <fantasai> dholbert: other elements are sized similar to abspos, don't affect sizing <fantasai> dholbert: I think that approximately matches <fantasai> TabAtkins: Problem with children, grid + multicol act very differently if have one child <fantasai> TabAtkins: if ignore that, prtend block layout with one child, that works <fantasai> cbiesinger: so Ian's testcase, Chrome is wrong <fantasai> iank_: so width of this element should be 100px? <fantasai> fantasai: that's what I'm saying <cbiesinger> Ian's testcase would get two scrollbars, then <fantasai> fantasai: the point of the feature was that box doens't resize in response to contents <fantasai> fantasai: so should not change size <fantasai> fantasai: but also should not clip contents, or make them inaccessible underneath scrollbars <fantasai> TabAtkins: so use c-i-s to figure out if you need to add a scrollabr <fantasai> TabAtkins: but then when do layout, then ignore c-i-s for purpose of scrollbar <fantasai> TabAtkins: so adding vertical scrollbar for excess content won't change the size <fantasai> TabAtkins: but won't trigger extra scrollbars due to c-i-s <fantasai> TabAtkins: want content to be reflowable, and avoid unnecessary scrollbars <fantasai> TabAtkins: so c-i-s should factor into scrollable overflow area during intrinsic sizing <fantasai> TabAtkins: but not affect the scrollable overflow area when actually laying out the content <fantasai> cbiesinger: makes sense <fantasai> fantasai: +1 <fantasai> iank_: So during intrinsic sizes phase, if we have size containment, we ignore the scrollbar, but if not we include? <fantasai> cbiesinger: in intrinsic size phase, include scrollbar iff contain-intrinic-size triggers overflow <fantasai> cbiesinger: for actual layout, do what we do today <fantasai> TabAtkins: I think we fall back to model where post doing intrinsic size layout, lay out as if that was an explicit width + height <fantasai> TabAtkins: proposed resolution is, 'contain-intrinsic-size' is used to figure out whether or not scrollbars should show up during sizing of container. Scorllbars that would appear are factored in. <fantasai> TabAtkins: but when doing layout of interior contents, 'contain-intrinsic-size' has no effect -- cannot trigger additional scrollbars. Only the actual contents affects scrollbars <tantek> I agree with the resolution, and let's explicitly capture the principle that no additional scrollbars should appear <fantasai> RESOLVED: contain-intrinsic-size defines scrollable overflow area for purpose of intrinsic sizing (including adding scrollbars if so required); is ignored for the actual scrollable overflow area during layout <fantasai> cbiesinger: there can be actual scrollbars depending on the actual contents, just not based on contain-intrinsic-size <tantek> right what Tab said, not caused by the c-i-s value <fantasai> astearns: let's get testcases <fantasai> AmeliaBR: scrollbars should not be caused by interaction of actual content and c-i-s |
So in Then if there's 150px of content, a vertical scrollbar only will appear, taking up some of the 100px width. (Assuming there's no unbreakable inline in the content that wouldn't fit into 84px; if there is, it'll create a horizontal scrollbar too.) But in Then if 150px of content lays out into there, it continues to have only a vertical scrollbar, again unless the content has an unbreakable inline long enough to force a horizontal one. One final question now. In the second example, what if there is no content in the box? The element is still gonna be 116x50, but will there be a scrollbar letting us scroll to see the full 100px of empty space? I can handle it either way, I'll just need to be more subtle about "ignoring" if we want to keep that empty space scrollable. |
I don't think there should be a scrollbar in that case -- in my understanding of the discussion, actual presence of the scrollbars is only triggered by actual content. overflow from c-i-s is only used for sizing. |
An example I was working on based on Tab's example of floats… Three cases:
For each, three variations:
I'd expect both the calculated box size for the container and the presence of scrollbars on it to be the same for each of those variations. I think that's what we resolved. In contrast… currently in Chrome (v81), we're getting no scrollbars & no room for scrollbars in the calculated size for the childless element with contain size and contain-intrinsic-size. Then, when you add the content to the element that had contain-intrinsic-size exactly matching the child content size,
So these would be things we are hoping to prevent. |
Update: that was my fault. The extra scrollbar goes away if I use But the width of the float changing when the child element is added is still a problem. |
What should happen with scrollbars in
overflow:auto; intrinsic-width: 200px; width: 100px;
?If the element was filled with 200px worth of child content, it would definitely create scrollbars. I believe intrinsic-width should do the same.
As an added bonus, this helps with some infinite-scroller cases that currently use a tall dummy element to make the scrollbar look right.
The text was updated successfully, but these errors were encountered: