Skip to content
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

[css-overflow] overflow: Consider reserving space for scrollbars with some property #92

Closed
RByers opened this issue Jan 22, 2016 · 61 comments
Assignees

Comments

@RByers
Copy link
Contributor

RByers commented Jan 22, 2016

WebKit/blink have "overflow: overlay" to enable scrollbars that don't take up layout space. Back in 2013 Tab said he supported standardization of this.

IE/Edge has '-ms-overflow-style: -ms-autohiding-scrollbar' which does the same but also indicates that scrollbars should automatically hide when not in use. Note that many sites try to implement this themselves today based on mouseenter/mouseleave events, which breaks touchscreen scrolling.

I don't know all the history here, but does CSSWG want to consider standardizing something here?

This bug tracks potential removal in blink.

@RByers
Copy link
Contributor Author

RByers commented Jan 29, 2016

We've heard a bunch of feedback from web developers that they want this feature (eg. it makes it easier to reason about layout when content grows/shrinks in an overflow:auto container). So we do not plan to deprecate this API from blink.

@atanassov
Copy link
Contributor

A great addition to the overflow spec. Implementing the -ms- feature we were concerned that the overlay scrollbars on top of the content degrades reading experience quite a bit, thus the autohiding behavior.
What are you proposing that we standardize?

@RByers
Copy link
Contributor Author

RByers commented Jan 29, 2016

The cases we've seen developers choose to use overflow:overlay, they're careful to have sufficient padding-right such that the scrollbars don't actually overlap the content (though I guess this depends on the implementation detail of the default scrollbar width - maybe the spec should define a maximum). So I think that would be OK. Since there's already non-trivial use of this syntax on the web, if we agree the semantics are reasonable, the simplest thing would be to standardize it.

That said, there's additional reason to like the authiding-scrollbar behavior. I don't know offhand if the developers who wanted overflow:overlay would be content with autohiding behavior as the only option. I'd personally be happy standardizing both.

@esprehn, @tabatkins thoughts?

@frivoal
Copy link
Collaborator

frivoal commented Jan 29, 2016

First, one process oriented comment. The CSSWG uses the www-style mailing list for technical discussions, not github. That may change one day, but so far it hasn't, so we should bring this back to the ML.

Now, on the proposal itself.

Regardless of whether we use autohiding or not or both, I think using the overflow-style property makes more sense:

  • Better graceful degradation. In a UA that doesn't support it you still get the correct value for the overflow property, which wouldn't be the case if we used overflow:overlay which would fallback on the default value, most likely visible.
  • If you want to apply the same overflow style to many scrollers, it's much easier to get this to cascade separately:
* { overflow-style: overlay;}
#foo { overflow: auto; }
#bar, #baz {oveflow: scroll}

@astearns
Copy link
Member

We have conversations in other venues about technical topics all the time, so I think it's fine to continue to discuss this here. The only requirement I'd like to have is that a summary be posted to www-style with a link back here. I'll bring this process detail up in the meetings next week.

@frivoal
Copy link
Collaborator

frivoal commented Jan 30, 2016

Sure. I just mean that while IRC discussions and the like are understood by all as being informal, some groups actually do use github for decision making but not this one, so there is potential for confusion. As you say, as long as it comes back to www-style at some point, it's all good.

@smfr
Copy link
Contributor

smfr commented Jan 31, 2016

For WebKit I don't think we want authors to be able to force scrollbars to diverge from the system-wide behavior. overflow: overlay is a historical artifact added for a Safari feature many years ago (before the system had overlay scrollbars), and I don't really want to see standardized.

@tabatkins
Copy link
Member

@smfr Does iOS currently use overlay scrollbars by default? Or layout-affecting ones?

@smfr
Copy link
Contributor

smfr commented Feb 19, 2016

iOS uses overlay scrollbars exclusively.

@tabatkins
Copy link
Member

So if we specced this as hinting that the author wants overlay scrollbars (without implying that the default has to be non-overlay), I assume you'd be cool with it?

@smfr
Copy link
Contributor

smfr commented Feb 19, 2016

Is any UA willing to allow authors to change the types of scrollbars in different scrollable areas on a page?

@tabatkins
Copy link
Member

We do that today, with overflow: overlay, thus this thread asking for it to be specced. ^_^ IE has something similar. Check the first post.

@RByers
Copy link
Contributor Author

RByers commented Feb 20, 2016

In Sydney we discussed that it's probably not really the overlay property devs want but these two sub-properties:

  1. No layout changes on size changes (like overflow:scroll)
  2. No (ugly) visuals when scrolling isn't needed (like overflow:auto)

Could these properties be achieved without dictating anything that contradicts system appearance, and without introducing the "may cover content" (or "hard to grab with mouse") concern?

Eg. Maybe something like overflow:auto but that adds scrollbar-sized padding when no scrollbars are shown?

@tabatkins
Copy link
Member

This sounds legit to me. Identical to overflow:scroll, but without actually drawing any scrollbar. +1

Wanna take this to the list for wider comment?

@RByers
Copy link
Contributor Author

RByers commented Feb 23, 2016

I'm happy to do that, but just before we do: if that's really what we want so we need a new API for it at all? I.e. is it possible it's web compatible to either stop drawing the disabled scrollbars for overflow:scroll? In what situation would a developer want to be able to request overflow:scroll instead of this new behavior?

@tabatkins
Copy link
Member

There's absolutely zero page-observable difference between "draws the disabled scrollbars" and "reserves space but doesn't draw anything". So yeah, it's completely web-compatible. You wanna do that in Chrome, then we can add some text to the Overflow spec recommending that?

@smfr
Copy link
Contributor

smfr commented Feb 24, 2016

What if the page puts something there (e.g. abspos) with a click event handler? Seems observable.

@fantasai
Copy link
Collaborator

Seems unlikely to be a problem, though. Also, you can make that area behave exactly the same as a transparent scrollbar, in which case it would be completely unobservable.

@tabatkins
Copy link
Member

@smfr I assume you mean, like, underneath it, so the click event hits the element when it would otherwise have been intercepted by the disabled scrollbar?

If so, I agree with fantasai on both counts.

@smfr
Copy link
Contributor

smfr commented Feb 24, 2016

If I understand correctly, the current proposal is to have overflow: overlay reserve space for a scrollbar, only draw that scrollbar if it's "active", and intercept hit testing in the scrollbar region as if it were visible.

I think this defeats the purpose of overlay scrollbars. The whole point is to not take up any space, leaving more space for content. And for many types of content, it's just fine to paint in the area under the scrollbar (which is invisible most of the time).

The main problem comes with putting interactive content in that scrollbar area, like small buttons, where attempts to interact with the button end up bringing up the scrollbar. On Mac, at least, this is ameliorated by only showing the scrollbars when two fingers are on the trackpad, or you actually start to scroll.

@tabatkins
Copy link
Member

No, what Rick suggested just above is that we start by just saying that overflow:scroll is allowed to just... not paint the scrollbars if they're disabled. Keep the space, but don't draw anything. This should be a no-op for pages, but make overflow:scroll less ugly, and satisfy at least one major use-case for "overlay scrollbars".

Whether or not that space intercepts hit-testing is an open question that I think is relatively unimportant. We should decide one way or the other when speccing it (or make it explicitly undefined and encourage browsers to experiment and report back), but it's not a vital question to answer while evaluating this option.

For content that's okay with the scrollbars overlapping, we can then talk about actually speccing overflow:overlay. But this minor edit to scroll is actually safer and arguably more commonly useful, and gets us what we want without having to worry about "platform conventions" getting in the way.

I think this defeats the purpose of overlay scrollbars. The whole point is to not take up any space, leaving more space for content.

I strongly disagree. That's one point, yes, and if that's the goal you need true "overlay" scrollbars. The other reasons for this kinda thing, though, are to prevent your layout from shifting based on whether or not a scrollbar shows. For this it doesn't matter whether there's some lost space on the side or not; you can adapt either way, you just want it to be stable. overflow:scroll does that today, but at the cost of having an ugly disabled scrollbar when the element isn't scrollable, which is enough of a downside that people actively avoid that value and instead hack around overflow:auto. So we can just fix that downside.

And if we do that, we can be more aggressive about designing features that treat overflow:auto as always not having scrollbars, like vw and friends do, because people can then just use overflow:scroll if they want that space reserved. (Or overflow:overlay if/when we spec that.) Simpler layout code, yay!

@RByers
Copy link
Contributor Author

RByers commented Mar 7, 2016

We discussed this a bit for blink and people pointed out that it's very common to have full-width content that would look weird if it didn't go to the edge of the container (see screenshots here). Since we can't automatically determine if the content is "background" (safe to overlap with a scrollbar when present) or essential UI, we can't just automatically do the right thing.

@tabatkins
Copy link
Member

Yeah, I suppose I agree, unfortunately. :/

So we're back to needing new values to opt into good behavior, and never ridding ourselves of the terrible "overflow: auto" effect on layout calculations unless/until everyone agrees to switch to overlay scrollbars.

@frivoal
Copy link
Collaborator

frivoal commented Mar 8, 2016

Right, but I don't think the correct thing is new values to the overflow property, but rather values to an overflow-style property.

  • The fallback behavior in UAs that don't support this is better
  • These things cascade separately
  • Whether something has scrollbars or not (overflow: auto / scroll vs visible / hidden) is an independent question of how the scrollbars should look like.

I can also see Apple's point that authors should not have control over this at all. But if they should, I'm pretty sure it shouldn't be in the overflow property.

@RByers
Copy link
Contributor Author

RByers commented Mar 8, 2016

A related argument for overflow-style: I think there are legitimate use cases for disabling scrollbars entirely. Eg. a horizontally scrollable tab strip - @esprehn tells me polymer and facebook apparently rely on a hack for this where they place the strip inside a overflow:hidden container that is 20px shorter in order to clip the scrollbar. Some sites also rely on -webkit scrollbar theming for this. Edge has -ms-overflow-style: none for this, we should standardize that too.

@tabatkins
Copy link
Member

I'm confused - what part of this isn't already done by overflow:hidden? If you're just script-scrolling, overflow:hidden works just fine.

If you're wanting it to be pannable but not scrollable, that's a bit user-hostile - it'll only be scrollable on touch devices. Having something that turns off scrollbars when the user is capable of panning sounds okay, tho.

@RByers
Copy link
Contributor Author

RByers commented Mar 8, 2016

I'm confused - what part of this isn't already done by overflow:hidden? If you're just script-scrolling, overflow:hidden works just fine.

These scenarios are explicitly about avoiding script-scrolling (that's got a number of drawbacks, although it's commonly used for these scenarios).

If you're wanting it to be pannable but not scrollable, that's a bit user-hostile - it'll only be scrollable on touch devices. Having something that turns off scrollbars when the user is capable of panning sounds okay, tho.

Good point, though it's not just "touch" devices - you can still scroll with a mousewheel etc. Perhaps we need more concrete use cases here - presumably people are either breaking scenarios where scrollbars are the only way to scroll, or using this only as a convenience UI when there is some other navigation mechanism. eg. for a tab strip, you can click on the left or rightmost tab and it'll recenter to show more further left/right. The Android homescreen is an interesting use-case too - it doesn't have a scrollbar, but a custom "dot" indicator showing the active screen (and in mouse cases you could presumably click on the dot you want). Scenarios like this will probably be more common when developers switch to using css snap points (instead of custom JS scrolling) - those often have alternate navigation UI (at least next / previous buttons). Of all the image carousels I've seen on the web, I don't think I've ever seen one with a scrollbar. We want to support those scenarios as native scrollers right?

@tabatkins
Copy link
Member

Good point, though it's not just "touch" devices - you can still scroll with a mousewheel etc.

If it's vertical, yeah. You explicitly mentioned a horizontally scrollable strip, tho. ^_^

We want to support those scenarios as native scrollers right?

Definitely. The hard part is designing things that degrade well, and making the badly-behaved things possible but not the easiest thing to reach for. ^_^

For example, a "panning" overflow-style could hide the scrollbars when the device is capable of panning, and default to showing scrollbars otherwise. We could then have a property controlling that default, and allow people to say they'll handle those cases manually, with a property/value name that makes it less attractive, defaulting to the safe scrollbar-showing behavior.

@frivoal
Copy link
Collaborator

frivoal commented Mar 9, 2016

For example, a "panning" overflow-style could hide the scrollbars when the device is capable of panning, and default to showing scrollbars otherwise.

Or this could be Media query based.

@tabatkins
Copy link
Member

MQs let authors vary styles. I'm not sure how they help us define default behavior of a value.

@tabatkins
Copy link
Member

@fantasai Even if the concept is a bit different (I agree, it is), it's close enough that converging on names is worthwhile. The semantic difference between "gap" and "gutter" is razor-thin - this is indeed a gap between the outer edge of the padding box and the inner edge of the border box. I don't like forcing people to remember precisely which way we were leaning in the wind at a given time, even if one can argue that something is slightly more appropriate; better to be consistent and slightly wrong, than inconsistent but completely correct.

@frivoal Yeah, I'm not in any way attached to expressing the "no scrollbar" functionality thru this, I was just pointing out that we have a reasonable name available if we do indeed go that way. It's not part of the current proposal.

@fantasai
Copy link
Collaborator

I don't actually conceive of this as a “gap” at all: it is filled by the scrollbar. So to me it doesn't even seem close to right.

@frivoal
Copy link
Collaborator

frivoal commented Oct 5, 2016

Bikeshedding aside, following the last conf call, we now have 3 proposals:

  1. Have the 3 values (auto/stable/always) attached to a separate property that is not a longhand of overflow. e.g: scrollbar-gutter: auto | stable | always
  2. Have the three values attached to an overflow-something property that is a longhand of overflow. e.g. overflow-gutter: auto | stable | always
  3. Have the two non default values (stable/always) be optional values directly on the overflow property. e.g. overflow: visible | hidden | scroll | auto [stable | spaced]?

In all cases, if we decide to accept #419 as well, we can add the additional value.

I prefer solution number 1, because it makes sense to me that this would cascade separately (which makes it better than 2 and 3), and also because this seems more robust with regards to dealing with fall back behavior in browsers that don't support this property (which makes it better than 3).

@tabatkins
Copy link
Member

I don't understand why this needs to cascade separately. This isn't an independent piece of behavior - it's modifying the behavior of one value in 'overflow'. Effectively these are just two new 'overflow' values; the argument against actually doing that is that 'overflow' is already overloaded in handling multiple overflow-related things, and adding more values here would just increase the confusion.

In other words, there's no reason for the user to set "overflow: auto" if they really want the stable/always behavior. It doesn't offer them anything additional; it doesn't make their life easier for some other reason. They should just be setting the "stable" or "always" value directly on those elements, and only use "auto" if they actually want "auto" behavior.

@frivoal
Copy link
Collaborator

frivoal commented Oct 11, 2016

Whether or not something needs a scrollbar to show up when there's overflow is something you need to decide on an element per element basis.

What that scrollbar should look like is something that you may sometimes want to decide on an element per element basis, but you may also want to make page-wide (or widget-wide, or component-wide... .i.e non local) decisions, and that's a lot easier to do if they cascade separately. And it gives better fallback behavior when some values are not supported: auto is a better fallback from stable than visible, which is what you'd get if you're not careful.

Based on that, I think that it makes sense for the values we are discussing now to be in a different property than the choice between visible vs auto. By that logic, it could make sense for the choice of scroll vs auto to be in that same other property as well, but too late for that.

@frivoal
Copy link
Collaborator

frivoal commented Dec 5, 2016

Time to revisit? Agenda+ing

@fantasai
Copy link
Collaborator

I agree with Florian here.

@atanassov atanassov changed the title [css-overflow] overflow: Consider support for overlay scrollbars [css-overflow] overflow: Consider reserving space for scrollbars with some property Dec 21, 2016
@frivoal
Copy link
Collaborator

frivoal commented Jan 13, 2017

We resolved on:

scrollbar-gutter: auto | [ [stable | always ] && force? && both? ]

The property is inherited, and the initial value is auto.

The behavior of auto, stable, and force is as defined in #92 (comment). They also apply when overflow is scroll.

Stable and always do not apply to overflow: visisble, overflow: hidden, and overflow: clip, unless the force keyword is present, in which case they do.

When the both keyword is present, the space is reserved on both edges of the box rather than just the side the scrollbar appears in.

The property only has effects on the scrollbars triggered by overflow in the block direction.

If we find that we want to get the same effect for inline overflow, we will later add a new scrollbar-gutter-inline longhand, and the shorthand optionally take the same values a second time, defaulting to auto when omitted.

The name of the values are expected to be bikesheeded in a future session.

@frivoal
Copy link
Collaborator

frivoal commented Jan 13, 2017

img_20170113_142100

@smfr
Copy link
Contributor

smfr commented Sep 21, 2018

I intend to make overflow:overlay be a synonym for overflow:auto in WebKit: webkit.org/b/189811 to reduce engine complexity.

frivoal pushed a commit to frivoal/csswg-drafts that referenced this issue Nov 15, 2018
@ByteEater-pl
Copy link

People, am I the only one having a déjà vu? Much of what's discussed above was once drafted in [css-box]: https://www.w3.org/TR/2007/WD-css3-box-20070809/#the-lsquo3.

@frivoal
Copy link
Collaborator

frivoal commented Feb 5, 2019

That's actually quite different. This overflow-style old spec defined a bunch of different UIs for scrollers, but in all cases it didn't say how they consumed space. This new property does not change the UI for scrollers but does define (and let authors influence) whether and how they control space.

@Timmmm
Copy link

Timmmm commented Apr 30, 2020

What is the status of overflow: overlay? I want to use it in an Electron app, and it works fine as far as I can tell. @smfr said he made it the same as overflow: autobut that doesn't seem to be the case in the version of Chrome in Electron I am using (says it is Chrome 80).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests