Open mirisuzanne opened 1 year ago
- When we have a non-default root overflow specified, it should absolutely propagate to the viewport. This is certainly a browser bug (in all browsers).
I'm pretty sure the Chrome implementation propagates the overflow value to the viewport, but that what you see is instead an effect of how overflow is treated for contain:layout.
<!DOCTYPE html>
<style>
html {
contain: layout; /* No scrollbars, change to size and you will have scrollbars. */
overflow: auto;
height: 0px;
}
#filler { height: 10000px; }
</style>
<div id="filler"></div>
@lilles I see. So overflow
does propagate to viewport, but containment remains on the root which captures any nested overflow?
In that case, I think @fantasai's proposal that 'containment should also propagate to the viewport' would be the best solution – since containment and overflow would be defined on the same 'element'?
Would the effects of containment be well defined on the viewport? Another possibility seems to not propagate overflow
from the root if it has containment. We are already preventing propagation from the body anyway.
The CSS Working Group just discussed [css-contain][css-overflow] Setting containment on root should not make scrolling impossible
.
This issue is primarily about establishing a root container for the sake of container queries. One possible approach is to change the way container
properties are applied to root, rather than changing how the contain
property applies. The container property often applies containment, but not directly - it represents the authors desire for a queryable container.
For style queries, there is no need to establish a container, but it is possible to name containers. Authors establishing a container name on root will expect that their style queries are resolved on the root element. It would not make sense to ignore styles set on the root element, and it's not even clear to me what it would mean to query styles on viewport. So the issue here is also specific to size queries, and any solution we come to should keep other query types (and container names) intact.
With size queries, there are several things that could differentiate a root element container from a viewport container:
Point 3 is the primary advantage that authors might get from using size container queries on root, instead of using a media query. The other main advantage of establishing a root size container is simply to have a fallback for container queries that don't find any intervening containers.
In my experience, it is very common for authors to set a viewport-based height
on the root element (eg 100vh
or 100%
), and very uncommon for authors to set a margin
on root. Because of that, the root container is generally either content-sized (which would not be possible when it's a container) or it is viewport-sized. When establishing a root container, authors are even more likely to set the size of the element based on the size of the viewport. Losing the ability to measure the root element is not a big loss in most cases.
Is there any possible solution here that allows scrolling on the viewport, while continuing to support value resolution (and container names) on the root element? Even if it means we always return the viewport size on root containers?
Any news here? As an author i find it very strange that making the root element into a container prevents scrolling. I have also noticed that the behavior isn't coherent across the different browsers (for instance Chrome v129 and Firefox v131).
Maybe we shouldn't be turning the root into a container, but in some cases it may actually be useful...
If there are differences, we should address those. Do you have examples of the differences?
Beyond that, my sense is there might not currently be a path forward on this. As a workaround, I generally apply containment to the main layout blocks directly inside the body
– something like this:
body > :is(header, nav, main, aside, footer) { container: layout / inline-size; }
I've written a more in-depth article about this if you're interested.
@mirisuzanne I am not really sure what causes the differences, so i can't explain them very well. I can only describe what i saw... On Chrome v129 everything seemed to work fine, but on Chrome v128 we couldn't scroll. Also on Firefox or Safari we couldn't scroll!
Yes, i have seen you article. It was actually what lead me to this gh issue. Thank you, i found your article really helpful! 🤗
I have also tested the solution you have at the end of your article. But i ended update having some problems with fixed elements overlapping the scrollbar, something like this:
In the end i did actually use something very similar to what you suggest here on your comment. i turned the main, footer, ... into containers.
But, tbh, i think the best would be to just turn the elements themselves into container. The problem with that is that each element needs an extra "container wrapper", so the element can be the container, and the wrapper can listen to the parent @container
On Chrome v129 everything seemed to work fine, but on Chrome v128 we couldn't scroll. Also on Firefox or Safari we couldn't scroll!
@bfgeek Would the move away from full layout containment be responsible for this difference? If so, would that now allow using the root as a container once all browsers update their implementation?
i think the best would be to just turn the elements themselves into container.
Yeah, that would be great – but raises even more issues, since then we would be styling the same thing we're measuring. See #10509 for more recent discussion on that.
Container size queries provide a number of advantages over media (viewport) size queries, besides the ability to query nested elements. In order to access those benefits, and also provide a 'default' outer container, authors will commonly want to add containment to the root element . In addition, authors rarely rely on intrinsic sizing of the root - setting
html { height: 100%; }
is a well established pattern in reset styles, to size with the viewport – making the root a good candidate for 2-axissize
containment.The resulting expectation is that this should work:
However, this doesn't currently work as expected in any browser. See this simplified demo on codepen. The primary issue seems to be a combination of factors:
size
containment (and the explicitheight
orblock-size
properties) keeps the root element from resizing to it's contentsoverflow
value is used instead of the root elementoverflow
layout
containment stops propagation of theoverflow
property from the body to the viewportThis is not supported by CSS Overflow and CSS Containment specs:
visible
visible
(which is the initial value of the property), then it should be treated asauto
In my mind that means:
auto
on the viewport by default, even if we try and fail to propagate from body. This might be a browser bug.In another conversation, @fantasai has also suggested that we might want to explicitly propagate root containment to the viewport.
Note that this also causes issues if we change the containment to
inline-size
, because it generates a new positioning context on root. Since overflow still propagates, and root isn't able to be a scroller itself,position: fixed
elements no longer remain in view when scrolling. I have another slightly more complicated pen that helps explore all the various interactions. In order to achieve roughly the desired outcome with either 1d or 2d containment, authors would currently have to set:This allows the body to act as the outer scroller, with fixed elements still positioned by the root.
Ideally, our solution here should allow both
size
andinline-size
root containers, without breaking viewport overflow or fixed positioning.