Closed jcrben closed 2 years ago
It was never clear in 2.1. Overflow 3 is clear about it - padding should be included - but it's not 100% clear that's web-compatible. In particular, Chrome only includes padding in the block axis, and as you found, Firefox/IE don't include it in either axis. We need to dig thru this as a group and figure out what we should be doing.
We discussed this on the call today. I've added an issue to the spec for it.
In WebKit, we actually have different policies for block children and inline children. If the scroll container has inline children, we will include padding-right (or the equivalent for different writing modes) when computing layout overflow. However, if the scroll container has block children, we just consider the border boxes of the children. This is why there was some disagreement in the call today about what the policy is for the inline-direction.
Since additional information is being added here, and we haven't solved the original issue, I'm reopening this despite also having an inline issue in the spec.
@litherum Very interesting. Do you know if the decision to behave differently in the inline direction was informed by compat issues? I would not be surprised that adding the padding in the inline direction if the scroll container has block children was causing scroll bars to appear in places where they're not wanted, and had to be avoided because of that.
@litherum I thought it might be something like that; I'm glad to hear it's that simple, and I'll edit the issue accordingly. I echo @frivoal's question about whether the "don't include if if there's only block children" was done for compat (y'all were seeing pages suddenly sprout lots more scrollbars than intended), or if it was just happenstance (y'all added a hack to make inline content look better, and just didn't apply it generally).
@litherum Ping on:
I echo @frivoal's question about whether the "don't include if if there's only block children" was done for compat (y'all were seeing pages suddenly sprout lots more scrollbars than intended), or if it was just happenstance (y'all added a hack to make inline content look better, and just didn't apply it generally).
This code is older than my time on the WebKit team. I'll ask tomorrow.
@tabatkins Do you know whether firefox will fix this bug https://bugzilla.mozilla.org/show_bug.cgi?id=748518 ?
@tabatkins Do you know whether firefox will fix this bug https://bugzilla.mozilla.org/show_bug.cgi?id=748518 ?
Sebastian
My two cents are that we will change behavior here no more than once. That means the WG needs to get its act together and figure out what it's doing before we make any changes.
From a web developers view the Chrome behavior makes much more sense. I do not like it to put semantic-less wrapper-divs to get my padding.
@litherum On June 22, 2016, you said:
This code is older than my time on the WebKit team. I'll ask tomorrow.
Unless you live in a very unusual time zone, I think we're past tomorrow :) Any update?
1) Hello, I'm a developer and I lost a precious time to understand why there is padding-top/left/right but no bottom on firefox/edge. 2) The spec should be clear about this, display all paddings or hide all paddings. The "show padding-bottom/right if...." leads to 1.
Gecko is close to the spec (and I like it, most of the time) but the Blink implementation makes more sense in this case.
@frlinw I think historically the issue is that browsers didn't want to trigger scrollbars for overflow: auto
unless visible content was overflowing the inner border edge, so they didn't count padding. Once scrollbars are in place, however, it makes sense that the padding is included in the scrollable area, otherwise (as we've all noticed) the content gets uncomfortably tight against the bottom right edge when we scroll to that corner.
Unfortunately, browsers only measure overflow in one way: either include a padding/margin or don't. And changing behavior to include padding/margin when it wasn't before can cause pages which previously didn't have scrollbars to suddenly have scrollbars, and this can make a problem for the page. So we're in an uncomfortable position of what to do here.
I think it would be best artistically if we can count padding/margin as much as possible, but compatibility with existing Web content limits what we can do about it...
can cause pages which previously didn't have scrollbars to suddenly have scrollbars
Yes, I understand the issue here but actually, it is expected. Padding can cause overflow. What is unexpected is browsers trying to workaround this expected behavior with an unexpected one. If you go this way, padding-top can cause overflow when it's unecessary why the spec didn't decide to ignore padding-top too ? Because it breaks something, and it will be very visible. It's the same thing with padding-bottom, if you ignore it, even if it's less visible, it breaks something.
Moreover, Blink has the highest market share, it does not implement the behavior introduced in CSS 2.1 and there is no screams about it (actually maybe there are screams, I really don't know, but blink team does not need 6 years to implement something the dev community wants).
The issue here is the developer is not in control. The spec introduced a behavior which can be unexpected but didn't give to the developer the opportunity to control it (with something like overflow-clip
?)
existing Web content limits what we can do
CSS 2.1 broke existing web content because of this change too. Web is a living thing.
The Working Group just discussed padding-bottom in overflow content
, and agreed to the following resolutions:
RESOLVED: Require that you leave space in scroll containers for block-end padding in the scrollable area
RESOLVED: Undo the previous resolution and continue to figure out a whole model.
To solve the Web-Compat problem one could invent a CSS property such:
overflow-padding-behavior-right: strict;
overflow-padding-behavior-bottom: strict;
And a shorthand (right bottom):
overflow-padding-behavior: strict strict;
values are:
strict
=> padding at the endinline-content
or inline-children ? => padding-only for inline-childrenignore
=> no padding at the endThe actual Chrome behavior would be:
overflow-padding-behavior: inline-content strict;
The actual Firefox behavoir would be:
overflow-padding-behavior: ignore ignore;
@nuxodin your proposition seems good. I'm in for a css property to give some control to web authors (if there is no consensus about a default behavior) but it is not really related to the webcompat issue Because your spec is supposed to give a default value for this property... So implement this spec will break (or repair, depends of the point of view) some current browsers behavior
So, due to some issues in the css-align-3 spec (see https://github.com/w3c/csswg-drafts/issues/1425), the align-content
and justify-content
properties will now have this side-effect: any non-normal
value will cause the padding to be honored as requested here. See https://www.w3.org/TR/css-align-3/#overflow-scroll-position I think that resolves the request for a switch. :) We should definitely note this in the Overflow spec as well, however; and this issue remains open to see what we can do to fix this in the default case (which is constrained by Web-compat). I suspect we might be able to make it work in the block axis, but not the inline one.
@jcrben - still no solution found for the above problem , but we can try a trick to work. create a empty div at the bottom of your scrolling div and give it some height.this will work very similar to padding bottom.
OK, so we're also going to try to fix this for Flexbox and Grid generally (even when alignment is normal). See https://github.com/w3c/csswg-drafts/issues/3665 Cross your fingers and hope it's Web-compatible. :)
For anyone who comes here looking for a workaround/solution, here is a very well documented workaround:
https://www.brunildo.org/test/overscrollback.html
Problem: https://jsbin.com/sawuwor/1/edit?html,css,output Workaround: https://jsbin.com/wikuyif/1/edit?html,css,output
Update: I switched to using a :before
pseudo element to avoid issues with line height and pseudo element causing vertical scroll.
Problem: https://jsbin.com/sokufup/3/edit?html,css,output Workaround: https://jsbin.com/fusuwod/2/edit?html,css,output
Another workaround that worked well in my case: adding bottom margin to the last child.
.overflowing-container > *:last-child{ margin-bottom: 20px; }
Something should be done here and I think it should be to change the spec to what Blink implements given that most developers would expect Blink/Webkit behaviour as the "correct" one.
https://bugzilla.mozilla.org/show_bug.cgi?id=748518 has accumulated 21 dupe bugs since it was opened 8 years ago, which shows developers have come to expect Blink/Webkit as the correct one and Firefox's as wrong.
It certainly seems intuitive to me that padding/margin should not dissappear just because a area is scrollable. I would visualize the scroll area as a "zoom-in" on a content area. A "zoom" should not be able to change content.
My workaround for fixing this bug in my project was (helpful when you want the children centered with margin: auto
in a flex container if there is no scroll.):
.overflowing-container > *:last-child:after {
display: block;
height: 1rem; /* Match bottom padding */
margin-bottom: -1rem; /* Move it outside */
content: "";
}
Ran into this issue today, thankfully I was able to see this discussion. Added a margin-bottom to the div inside the scroll div and fixed the issue.
After a few days of fighting this problem, today I filed a bug https://bugzilla.mozilla.org/show_bug.cgi?id=1621708 and realised it's an 8yo known issue. Used the margin workaround, but now I can't have a flex container. Shame.
After a few days of fighting this problem, today I filed a bug https://bugzilla.mozilla.org/show_bug.cgi?id=1621708 and realised it's an 8yo known issue. Used the margin workaround, but now I can't have a flex container. Shame.
Yep, I also filed yet another duplicate for it just a few days earlier.
Fortunately managed to find a solid x-browser workaround with making the scroll container a child of the original scroll container. With custom elements, <slot>
element was already sitting there, I was able to to utilize it directly to become the new scroll container, instead of creating another <div>
layer or similar. Implementation is live at https://cxl.com/blog/ right sidebar.
Workarounds with pseudo elements don't work when I need to set the padding to percentage. Please fix it or add an option to support end padding. Thanks.
I'm about to add use-counters into blink to determine how often we have overflow-x + inline-end padding. We should have data in 2-3 months.
Ian
Over the past few weeks I've done a fair bit of investigation on the model here. Broadly speaking there is the "ideal" model which is as follows.
When calculating the scrollable-overflow for a scroll-container there are two rectangles we need to keep track of:
To determine this correctly the engine needs to keep track of the bounds of all inflow children and their margins (pre relative-positioning and transform adjustments). Padding of the scroll container is then added to this rectangle and added to the scrollable-overflow.
Importantly this doesn't include any float, or out-of-flow positioned children.
This also only happens for a scroll container, this isn't part of the scrollable-overflow for non-scroll containers.
On top of this the "regular" scrollable overflow calculations apply, e.g. the scrollable-overflow for propagation rectangle which is post-transform, post-relative-positioning.
The result of the scrollable overflow rectangle is the union of [1], [2].
Broadly speaking everything is a relative mess :). However the compat concerns only surround [1].
I created this handle table! | Blink (inline) | Blink (block) | WebKit (inline) | WebKit (block) | Gecko (inline) | Gecko (block) | EdgeHTML (inline) | EdgeHTML (block) | |
---|---|---|---|---|---|---|---|---|---|
block-flow (inline-level) | padding | padding | padding | padding | none | none | none | none | |
block-flow (block-level) | none | child-margin + padding | none | child-margin + padding | none | child-margin | none | child-margin | |
flex | none | child-margin + padding | none | child-margin + padding | none | none | none | none |
(I didn't test grid). The "ideal" thing here (which developers are asking for) would be for each of the layout modes to include "child-margin + padding".
(For the "block-flow (inline-level)" case "child-margin + padding" == "padding").
We (Blink) are prepared to try and incrementally move to the "child-margin + padding" case for both axis, however stop when we find real world compat concerns. As an example this may end up as the following:
We've got some UseCounters in place, but we are in the process of adding more precise ones.
The CSS Working Group just discussed [css-overflow-3] Clarify padding-bottom in overflow content
.
@fantasai The primary difference from the spec and above, is that the padding-edges contributing to scrollable-overflow are determined "pre-transform, pre-relative-position". E.g. this means that you can animate an element "in" from the top for example, without affecting the scrollable-overflow. This is obviously still union'ed if a child is transformed "outside" this area.
This is what Blink/WebKit do today for block-end edges (and what grid somewhat requires, making the grid part of the scrollable-area).
Additionally OOF-positioned children aren't considered for the padding calculation.
@fantasai & I chatted quicky and are on the same page regarding my previous two comments.
Another workaround that worked well in my case: adding bottom margin to the last child.
.overflowing-container > *:last-child{ margin-bottom: 20px; }
This would have been a great workaround for me as well, until I had dynamically created cards in a grid. This left the last child having a nice look, but if there were several children next to each other, only having the last one have padding threw it all off.
I'm fixing this webcompat issue for gecko. I update @bfgeek's compat table in the previous comment based my test. Please let me know if there's any error. | Testcase | Blink (inline-end) | Blink (block-end) | WebKit (inline-end) | WebKit (block-end) | Gecko (inline-end) | Gecko (block-end) |
---|---|---|---|---|---|---|---|
block-flow (inline-level) | padding | padding | padding | padding | none [3] | padding | |
block-flow (block-level) | none | child-margin + padding | none | child-margin + padding | none [3] | child-margin + padding | |
flex | child-margin + padding | child-margin + padding | none | child-margin + padding | child-margin + padding | child-margin + padding | |
grid | none [1] | none [1] | none | child-margin + padding | none [2] | none [2] |
(For the "block-flow (inline-level)" case "child-margin + padding" == "padding").
[1] Blink is planning to change grid to "child-margin + padding" in both axes in GridNG (from my communication with @bfgeek) [2] Gecko is planning to change grid to "child-margin + padding" in both axes, too. Tracking in Bug 1527539. [3] Both Blink and WebKit are not consistent on whether the inline-end padding is added in block-flow (yes for inline-level, no for block-level), so Gecko is waiting until there's resolution for this issue. Tracking in Bug 1700858.
The primary difference from the spec and above, is that the padding-edges contributing to scrollable-overflow are determined "pre-transform, pre-relative-position".
@bfgeek If the spec isn't clear about that, then that's a problem with the spec that should be fixed. It's certainly intending to specify that. Padding gets applied essentially at the edge of what would have been the content edge of the box, if it were auto-sized to its contents. Are you saying the spec is unclear, or that implementations attach padding after transforms/relpos rather than before?
Additionally OOF-positioned children aren't considered for the padding calculation.
"Out of flow" includes floats. I think floats are intended to be included here, no?
I mean, it's good to see this being discussed frequently (with an estimate 2-year-interval at first glance), but in the meantime another question about this has been raised and suggested quirky workarounds on StackOverflow.
Considering this issue has been reported on bugzilla more than 9 (!!!!) years ago, to an outside person this does make the impression that whoever decides on such issues doesn't do their job in anywhere near acceptable timely manner.
Considering this issue has been reported on bugzilla more than 9 (!!!!) years ago, to an outside person this does make the impression that whoever decides on such issues doesn't do their job in anywhere near acceptable timely manner.
Must be said again. Frontenders are disheartened by browser bugs, quirks and undefined behaviour. From all-time favourites like scroll padding and missing subpixel scroll offset to relatively new unstable stuff like scroll snapping, web dev is a minefield.
As far as I can tell, other than possible editorial tweaks to make the prose cleaner, the only reminaing open quesiton is that of “[3]” in https://github.com/w3c/csswg-drafts/issues/129: do we add that padding in the inline-end of block-flow or not (limited to the case of justify-content: normal).
I think that:
That would mean that even though the current webkit/blink behavior is odd, it represents the most padding we'll ever get, so we might want to spec that.
However, the blink/webkit "odd" behavior is really odd: they add the scroll container’s padding to the inline-end of inline children of the container, but not to other descendents of the container, be they block containers or inline descendents other than children.
This is not just weird, it also violates the principle that inserting an unstyled div should make no difference to the layout.
We probably should for consistency, and never add that padding to the inline-end.
The CSS Working Group just discussed clarify padding-bottom in overflow
, and agreed to the following:
RESOLVED: Go with Firefox's behavior - no elements cause the scroll container's inline-end padding to be used
http://wpt.live/css/css-overflow/overflow-padding.html should be fixed to match the resolution.
@bfgeek Can you say a little bit about why you want this back on the agenda? Should I hold off doing the edits?
Yes - sorry I was OOO last week. I'm pretty sure that we can do something better for web developers here but we'd need to un-resolve that resolution. We aren't necessarily compat constrained here. (have data).
The CSS Working Group just discussed [css-overflow-3] Clarify padding-bottom in overflow content
, and agreed to the following:
RESOLVED: Undo previous resolution. Explicitly mark as undefined in the draft for now
umm, I'm sorry, but is this issue resolved? I use Chrome 92.0.4515.131 and it seems that the padding (right-padding) is already work as expected, or this thread is only for discussing the draft spec, but not the issue itself? (sorry if this is a dumb question..)
this thread is only for discussing the draft spec
Yes, this whole repository is for discussing specifications. Of course, specs and implementations are expected to match each-other, but if you're interested in the status of a particular bug in a particular browser, this is the wrong repo to be looking at.
If the scroll container has different types of children, how to determine the scrollable overflow rectangular area?
I discovered this today when my overflow content appeared cut-off in Firefox and IE. It appears this was reported to Mozilla and closed as invalid in Bug 748518 - padding-bottom/right(block-end/inline-end) is ignored with overflow:auto/scroll because it extends in from the border-box rather than out from the scrollable area and someone there suggested bringing it up with the CSS team. I did a search for padding-bottom overflow on the www-style list and didn't see anything.
Previous practical discussions on Stack Overflow include Bottom padding not working on overflow element in non-chrome browsers and padding-bottom is ignored in Firefox and IE on overflowing elements with no content.
Perhaps this is already clear and Chrome has it wrong? I'll admit I'm not enough of an expert on the spec to be sure, just hoping for consistency.