w3c / csswg-drafts

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

[css-overflow] Should a visibility:hidden overflow:scroll be scrollable? #4113

Closed smfr closed 3 years ago

smfr commented 5 years ago

visibility:visible on a child can make content visible inside a visibility:hidden ancestor. If the ancestor chain to which visibility:hidden applies contains overflow:scroll, and the scrollable content contains a visibility:visible element, should user interaction be able to trigger scrolling, and thus cause the visible element to get scrolled?

https://codepen.io/smfr/pen/orRLqN

smfr commented 5 years ago

Safari and Chrome don't allow scrolling. Firefox kinda does on the first scroll, but then it becomes non-scrollable.

AmeliaBR commented 5 years ago

In all major browsers (I'm pretty sure) visibility: hidden makes an element non-focusable. If it isn't focusable, it shouldn't be scrollable. (Or conversely, if it is scrollable, it should be focusable.)

emilio commented 5 years ago

It should still be scrollable via script though, right?

jonjohnjohnson commented 5 years ago

What thoughts do you folks have for how this relates to an overflowing scroll container with pointer-events: none while a descendant has pointer-events: auto set? Treated the same as the visibility example linked above?

Case for pointer-events version of scenario, currently unique behavior in each blink/webkit/gecko https://output.jsbin.com/talomas/quiet

See also https://bugs.webkit.org/show_bug.cgi?id=183870 (guessing @smfr filed this as a response)

Or conversely, if it is scrollable, it should be focusable.

@AmeliaBR can you elaborate on what you mean here? Kinda confused in a chicken/egg way, but maybe I’ll understand better from how you define “scrollable”?

AmeliaBR commented 5 years ago

can you elaborate on what you mean here?

I mean, if mouse-wheel users can scroll it, then keyboard users should be able to scroll it. Which means there must be a keyboard-only way to get focus on the scroll container or its contents. (Now, some browsers aren't very good about making scrollable containers focusable by default even if they are visible, but the standard solution is to give the container tabindex="0". In this case, you'd need to make the visible child focusable, but at the same time something non-interactive that will bubble keyboard events up to the container.)

Of course, even that wouldn't guarantee accessibility for all users: some users still rely on grabbing the visible scoller in order to scroll. (I do this all the time myself for small widgets on screen where I can't easily get keyboard focus to the correct place, since touch gesture scrolling on my trackpad is very unreliable.) To make scrolling work for this situation, the scrollbar itself would need to be rendered separate from the rest of the box.

In sum: If the hidden scroll container is "scrollable" it needs to be scrollable with every input method that normally works for visible scroll containers.

AmeliaBR commented 5 years ago

It should still be scrollable via script though, right?

Sure…? Do we have any other ways to create a scrollable container with user-scrolling disabled?

jonjohnjohnson commented 5 years ago

Safari and Chrome don't allow scrolling. Firefox kinda does on the first scroll, but then it becomes non-scrollable.

Also, @smfr, this is not entirely true. Webkit does allow scrolling, if it bubbles from nested scroll containers. And gecko behaves the same regarding nested scroll containers. It also always allows gestural scrolling from atop the scrollbar and from grabbing the scrollbar when manipulating pointer-events. And all browsers allow scrolling when focused and pressing the (shift+)spacebar.

jonjohnjohnson commented 5 years ago

Chrome don't allow scrolling.

@smfr from the demo that I originally filed, https://codepen.io/anon/pen/EBzmWv, I can scroll whether visibility or pointer-events manipulation on the scroll container. When my mouse is atop the visibility: visible white blocks, I can scroll them up into view. When my mouse is in the area atop the scroll container, but not atop the white blocks, I cannot scroll the visibility: hidden scroll container.

Does this case exhibit different behavior in Chrome 77.0.3847.0 (Official Build) canary (64-bit) on your computer?

smfr commented 5 years ago

Sure…? Do we have any other ways to create a scrollable container with user-scrolling disabled?

overflow:hidden is exactly that :)

I agree that programmatic/bubbled scrolling in such containers should continue to work.

from the demo that I originally filed, https://codepen.io/anon/pen/EBzmWv

That's an overly complicated testcase. Can you simplify it?

jonjohnjohnson commented 5 years ago

@smfr Simplified, but it’s still really the same and it still is scrollable in blink (as well as gecko 70.0a1)

https://codepen.io/anon/pen/NZZvgY

I think it has to do with the fact that there is a scroll container underneath the hidden container.

Can you chime in with your thoughts on pointer-events though? If you’d want it treated differently? And why or why not?

css-meeting-bot commented 5 years ago

The CSS Working Group just discussed Should a visibility:hidden overflow:scroll be scrollable?, and agreed to the following:

The full IRC log of that discussion <dael> Topic: Should a visibility:hidden overflow:scroll be scrollable?
<dael> github: https://github.com/w3c/csswg-drafts/issues/4113
<dael> smfr: You have overflow:scroll with visibity:hidden but a visble decendant. Should you be able to scroll if you interact? If programmatic movement should it move things around?
<dael> Rossen_: Current behavior?
<dael> smfr: Cannot interactively scroll, but can through programmatic and things happening on descendants. I think that's reasonable
<Rossen_> https://codepen.io/anon/pen/NZZvgY
<dael> Rossen_: Is ^ the example?
<dael> smfr: Yes, I think so
<dael> emilio: FF behavior is same but we allow scrolling interactively the first time which is weird. Would think of it as a bug.
<smfr> https://codepen.io/smfr/pen/orRLqN
<dael> smfr: Simpler example ^
<dael> [everyone looks at the examples in silence]
<dael> Rossen_: Your definition, if I'm getting it correctly, for purposes of computing scroll bounds for scroller with visibility:hidden descendants are not counted as part of scroll boands for this scroller?
<dael> smfr: Not about scroll bounds. element.scrollheight is same weither or not overflow:Scroll is hidden. It's about if UA allows interaciton
<dael> TabAtkins: final codepen has a scrollbar, but you can't scroll it directly
<dael> TabAtkins: If you were to make it scroll bounds it means can't be scrolled by anything. Programmatic and bubbling still works
<dael> smfr: Behaves similar to if it's overflow:hidden. Maybe can write in same way as overflow:hidden which allows programmatic scrolling
<dael> Rossen_: Reasonable. Aligning with overflow:hidden would be similar behavior to something people know how to use. People know you can select and drag to scroll overflow:hidden scrollers.
<dael> Rossen_: Other opinions?
<dael> Rossen_: Prop: Align behavior of visibility:hidden with visible descendants for overflow:scroll to behave the same as overflow:hidden
<dael> smfr: Also question on if pointer-events:none.
<dael> Rossen_: Sep issue?
<dael> smfr: No. Don't know if need separate or lump in.
<dbaron> seems like pointer-events:none shouldn't effect keyboard-based scrolling?
<dael> Rossen_: Since we're a minute past let's resolve on this. If want to try and lump in lets do that later.
<dael> Rossen_: Obj to Align behavior of visibility:hidden with visible descendants for overflow:scroll to behave the same as overflow:hidden
<dael> RESOLVED: Align behavior of visibility:hidden with visible descendants for overflow:scroll to behave the same as overflow:hidden
<dbaron> I assume this means for scrolling behavior and not for layout (e.g., size of scrollbars)
<dael> Rossen_: We're are hour. If you want to discuss pointer-events let's do that next week or in github
tabatkins commented 5 years ago

Convo was a bit rushed, so I'd like to confirm our resolution.

We want a visibility:hidden element to act like overflow:hidden wrt scrolling, regardless of its overflow value, right? So:

  1. Never a scrollbar.
  2. No scroll bubbling - if you mousewheel on a visible descendant, it doesn't scroll the hidden container.
  3. Script-based scrolling still works.

Is this regardless of overflow value, or does it just apply to all the "scrollable" overflow values? (Hidden, auto, scroll) I assume an "overflow:visible" element remains unscrollable, as would the clip values?

emilio commented 5 years ago

Never a scrollbar.

I think there should be a scrollbar, just not visible (this is observable since having a scrollbar on non-Mac platforms changes the available space).

smfr commented 5 years ago

We want a visibility:hidden element to act like overflow:hidden wrt scrolling, regardless of its overflow value, right? So:

  1. Never a scrollbar.

No visible scrollbar, but layout happens as it would without visibility:hidden (i.e. a present non-overflow scrollbar will take space).

  1. No scroll bubbling - if you mousewheel on a visible descendant, it doesn't scroll the hidden container.

Agreed.

  1. Script-based scrolling still works.

Agreed.

Is this regardless of overflow value, or does it just apply to all the "scrollable" overflow values? (Hidden, auto, scroll) I assume an "overflow:visible" element remains unscrollable, as would the clip values?

overflow:visible and clip would remain unscrollable, yes. I don't think there's any behavior change for overflow:hidden. Auto/scroll would behave as above.

frivoal commented 3 years ago

Alright. So this is done now, but there's a follow up in #6355.