w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.48k stars 662 forks source link

[css-overflow] How does overflow-clip-margin: border-box behave on a scroll container? #7246

Open emilio opened 2 years ago

emilio commented 2 years ago

Usually the border of the scrollable area is outside. What should happen on a scrollable box when you set overflow-clip-margin: border-box?

Are you supposed to make the contents overlap the border area? If so, what happens with classic (Windows-like) scrollbars, which are inside the border area? I'm not sure how that would work.

cc @chrishtr @khushalsagar

emilio commented 2 years ago

Ah, I guess per spec overflow-clip-margin doesn't apply at all to scrollable boxes...

That seems a bit unfortunate, since at least content-box and padding-box seem useful on those (we probably can't expand the clip though, as per the above...).

flackr commented 2 years ago

Supporting visible scrollable overflow outside of the border-box could also be useful for certain niche use cases, such as tech demos e.g. https://twitter.com/justinfagnani/status/1569725232017199104 or effects like using a backdrop-filter: blur to create a glassy view of content which hasn't scrolled into view yet.

fantasai commented 1 year ago

@emilio What does it mean when you clip to the content-box on a scroll container? Where does the scrollbar go? If you scroll to the top/bottom of the scrollable range, is the content that would have been in the padding area clipped or is the viewport into the scrollable overflow area reduced? If it's reduced, what's the initial scroll position, can you see all the top of the content or is it invisible in the padding area?

How does this make any sense?

emilio commented 1 year ago

@fantasai I guess the use case where we use the equivalent of content-box for compatibility (<input> elements) can't have scrollbars, so they don't have to answer those questions.

khushalsagar commented 1 year ago

@emilio does overflow: clip work for your use-case then?

We can look into supporting this property if overflow is hidden, that would avoid complications with scrollbars @fantasai pointed out. Reasoning about this with scrollbars isn't worth it unless there is a strong use-case.

matthewferry commented 1 year ago

Personally, I have definitely wanted to have overflow: scroll where the clip is outside the <visual-box>, but where the scrollbars stay inside the <visual-box>. This is especially useful where you want the content to flow behind or on top of an adjacent element but want the scrollbar to stay within the visual-box and not end up moving behind/on top of the adjacent element.

Desired behavior

Admittedly, I'm not sure I fully understand the limitations/complications with scrollbars as mentioned above, so maybe this just isn't possible to support overflow-clip-margin with overflow: scroll, but here's a quick visual describing what would be desired:

overflow-clip-margin

Edit: removed unnecessary context on workarounds

Westbrook commented 1 year ago

Another place that a feature like this would be useful is in conjunction with visible states (e.g. :focus or :focus-visible) wherein content is added outside of the border-box of content within a scroll area. This can come to bear as in this image:

image

(source: adobe/spectrum-css#1336 )

There are reciprocal techniques (e.g. using extra padding internal to the parent, etc.) that you could do today that allow for managing this correctly. However, the idea that content can exist outside of the border-box feels like something that would be better to manage outside of the parent as well. Seeing scroll clipping work as outlined in @matthewferry's screenshots would be a great way to open up this reality.

css-meeting-bot commented 1 year ago

The CSS Working Group just discussed [css-overflow] How does overflow-clip-margin: border-box behave on a scroll container?.

The full IRC log of that discussion <TabAtkins> miriam: emilio raised this, fantasai agenda+'d it
<iank_> +1
<TabAtkins> emilio: I'm fine with "it doesn't apply to scrollable boxes"
<TabAtkins> emilio: So when I filed this, I was wondering...
<TabAtkins> emilio: There are some elements that need to clip, even tho they're scrollable they clip to anothe rbox that isn't the padding box
<TabAtkins> fantasai: Issue is about whther overflow-clip-margin should apply to scroll containers
<TabAtkins> fantasai: Applying it brings up a lot of interesting questions
<TabAtkins> fantasai: Where does the scrollbar go. If you croll to the top/bottom is the content in the padding area clipped, or is the scroll area reduced so it's viewable. Etc.
<TabAtkins> fantasai: There's a comment from Matthew Perry where he outlines the desire for this feature, and outlines a set of behaviors that seem to amke sense to them.
<TabAtkins> fantasai: Scrollable area and viewport are both... Never mind, follow the examples.
<TabAtkins> fantasai: He wants things scrollable to be viewable until it's outside the scrollable margin.
<TabAtkins> fantasai: I thin kif it's within the box it has a layout impact...? It's not clear to me exactly.
<TabAtkins> flackr: I don't think it has to.
<TabAtkins> fantasai: If it doesn't have a layout impact, you can't see all the content unless you know to put enough padding in the content.
<TabAtkins> flackr: Right.
<TabAtkins> fantasai: So I think it probably makes more sense to effectively increase the size of the box to the content area.
<TabAtkins> fantasai: So I think the q is - do we want to figure out how to make this work? Or just define it to not work?
<TabAtkins> flackr: I think there are a lot of UIs that would benefit from this, and we should try to make it work.
<TabAtkins> iank_: Can you give an example?
<TabAtkins> flackr: This is a good way to handle cases where you want some visuals that show up above your scrolled content, but your scrollbar doesn't, so the image in Mathhew's comment shows an example there with a chat widget where the text scrolls under the header (and is blurred by a backdrop filter) but the scrollbar doesn't.
<TabAtkins> iank_: That could also be solved with a z-index fix to the scrollbar, maybe? Is this th eprimary driver?
<TabAtkins> flackr: Not the zindex, it's the physical size of the scrollbar should be smaller than the visible sie of the scrolled content
<TabAtkins> flackr: In the chat support widget exapmle, the scrollbar starts below the header. The header is outside the scroller.
<bramus> +1 to this example/use-case. I needed something like this just recently.
<TabAtkins> flackr: I see a lot of sites that have this issue where scrollbars don't line up with their visual affordances, and I think this API provides a path to fix that.
<emilio> q
<emilio> q+
<TabAtkins> iank_: My problem is overflow-clip-margin can go negative, and that brings up andditional qs
<TabAtkins> flackr: there may be other ways to do this
<TabAtkins> iank_: This doesn't feel like o-c-m to me but i could be wrong
<TabAtkins> flackr: The chat widget would have an ocm of -(header size).
<TabAtkins> flackr: Or, postive. whatever makes stuff outside the scroller visible
<miriam> ack emilio
<TabAtkins> emilio: We do have a property already to specify the scroll distance to bring elements into view
<bramus> q+
<TabAtkins> emilio: The use-case for th eheader seems like we should use that?
<TabAtkins> emilio: scroll-padding
<TabAtkins> emilio: So it seems there's a use-case to maybe put the scrollbar only in the scroll-padding area
<TabAtkins> emilio: May be another way of solving this
<flackr> q+
<TabAtkins> emilio: Haven't made up my mind about making the scroller smaller and content overflowing it, which is kinda weird, or tweak the positioning of the scrollbar via scroll-padding
<iank_> a control to shift the scrollbar seems slightly better
<miriam> ack bramus
<TabAtkins> bramus: Maybe another approach is instead of specifying distances is to specify "overflow on x-axis" is simple visible and a wrapper around it would clip it?
<flackr> +1 I was thinking a common pattern would be an ancestor applies a clip so that it doesn't infinitely overflow
<TabAtkins> bramus: In the chat support widget, there's a wrapper around the whole thing that's preventing the chat content from being visible
<flackr> q-
<TabAtkins> bramus: That avoids the concern about numbers.
<miriam> ack fantasai
<Zakim> fantasai, you wanted to say we should re-use extended <position> and to
<TabAtkins> fantasai: Using specific overflow-clip-margin is problematic, you shouldn't be trying to predict fixed pixel values
<TabAtkins> fantasai: Makes it incompatible with allowing wrapping, etc.
<TabAtkins> fantasai: So I don't know this is a good fit for th euse-case, but I don't know what the right solution is either.
<TabAtkins> miriam: I also don't necessarily think scroll-padding is right here, it defaults where to scroll to. Here you still want to scroll to the top, just want things to be able to scroll past that position.
<flackr> q+
<TabAtkins> fantasai: maybe now we need scroll-scope that hoists the layout scope of a descendant scroll container?
<miriam> ack flackr
<TabAtkins> flackr: My expectation is the way devs will use this is they have an ancestor that still clips the content, and having pixel values is not desirable
<TabAtkins> flackr: Maybe you make scrollable overflow visible and it's clipped by an ancestor instead.
<bramus> `overflow: scroll-visible` 🤨
<TabAtkins> miriam: So it sounds we're moving in the direction of a new property, rather than re-using o-c-m?
<TabAtkins> miriam: Do we want to resolve on the o-c-m behavior, and open a new issue for the remaining cases we still want to handle?
<TabAtkins> emilio: I think o-c-m isn't necessarily the right proeprty for this use-case, so acknowledging we want to solve them and open a separate issue probably makes more sense.
<miriam> ack fantasai
<Zakim> fantasai, you wanted to note the two suggestions
<TabAtkins> fantasai: Two side suggestions
<TabAtkins> fantasai: from bramus, `overflow: scroll-visible;`
<TabAtkins> fantasai: from someone else, a keyword to o-c-m (`infinite`?)
<flackr> overflow-clip-margin: infinite was me :-)
<PaulG> q+
<miriam> ack PaulG
<TabAtkins> PaulG: If something is beneath the margin, and o-c-m is set, and there's something interactive in that text (a link), is is possible for that to come into focus when tabbed? Or will it only scroll to its normal limit and not come further in due to the clip?
<argyle> q+
<TabAtkins> flackr: Not 100% sure I followed, but assuming it's just a visual clip change, then you wouldn't be able to scroll to the new area.
<TabAtkins> PaulG: Sounds unhelpful, yeah.
<TabAtkins> flackr: Right, the other solutions expand the clip instead.
<TabAtkins> argyle: Another use-case. I have shadows on boxes inside of scrollers, I'd like them to leak out. Right now they're clipped.
<TabAtkins> argyle: So similar case, I want the scrollport to contain and create a scrollable area, but not clip paint.
<TabAtkins> miriam: And w'er eat time, we'll take back to the issue
bramus commented 1 year ago

In https://scroll-driven-animations.style/tools/view-timeline/ranges/ I needed exactly this ability as described above. In my case, the scroller (blue bordered box) should scroll its content (the aliceblue rectangle), yet all that overflows should be kept visible for demonstration purposes.

To make it work, I turned to faking it entirely by creating a faux scroll interface (mimicking the MacOS scroll UI), layering some things, and manually translating the scroller’s content via JS as one scrubs the faux scrollbar.

If there was some simple way say “do scroll the y axis but keep the overflow visible”, this workaround would not have been needed, and the UI would look good on all platforms.

Same thing goes for the chat example above, having it applied to the <chat-messages> list. It’s wrapping <chat-widget> could still have overflow set to hidden so things don’t bleed out of the widget itself.

Personally, I am leaning to something like a keyword (or maybe a new value?) for overflow, e.g. overflow-y: scroll visible;. Advantage to having a keyword is that you don’t need to know the specific height of any sibling element (e.g. the <chat-header> and <chat-form> in case of the chat UI).

fantasai commented 1 year ago

@bramus I think there are two use cases outlined here. One of them is the chat messages example from @matthewferry, where the clip rect for the scrollable overflow is defined by layout (of an ancestor).

But another is the example given by @Westbrook and @argyleink, where there's some kind of ink overflow and they want to let it overflow the scroller. For those, applying overflow-clip-margin would make more sense. These can often be worked around by increasing the padding within the scroller, though (which would also be useful if, for example, the author later decided to add a background color or border to the scroller), so I'm not sure how necessary it is to add... though if we're already having infinitely overflowing scrollable overflow, making a fixed overflow-clip-margin also work is probably not that hard.

matthewferry commented 1 year ago

Personally, I am leaning to something like a keyword (or maybe a new value?) for overflow, e.g. overflow-y: scroll visible;

That would work, too!