[css-overflow] overflow: Consider reserving space for scrollbars with some property #92
|
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. |
|
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. |
|
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? |
|
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:
* { overflow-style: overlay;}
#foo { overflow: auto; }
#bar, #baz {oveflow: scroll} |
|
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. |
|
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. |
|
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. |
|
@smfr Does iOS currently use overlay scrollbars by default? Or layout-affecting ones? |
|
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? |
|
Is any UA willing to allow authors to change the types of scrollbars in different scrollable areas on a page? |
|
We do that today, with |
|
In Sydney we discussed that it's probably not really the overlay property devs want but these two sub-properties:
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? |
|
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? |
|
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? |
|
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? |
|
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. |
|
@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. |
|
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. |
|
No, what Rick suggested just above is that we start by just saying that 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
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. And if we do that, we can be more aggressive about designing features that treat |
|
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. |
|
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. |
|
Right, but I don't think the correct thing is new values to the overflow property, but rather values to an overflow-style property.
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. |
|
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 |
|
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. |
These scenarios are explicitly about avoiding script-scrolling (that's got a number of drawbacks, although it's commonly used for these scenarios).
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? |
If it's vertical, yeah. You explicitly mentioned a horizontally scrollable strip, tho. ^_^
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. |
Or this could be Media query based. |
|
Sure. I'm just saying that showing scroll-bars when you have a mouse and have them invisible (not autohide) when you're on a panning device may not be a sufficiently common desire that we need to have a built in value to handle it, and if authors can use MQs to figure out they're on a device with panning, they can do it themselves. |
|
Just realized / remembered another aspect of pre {
max-height: 100px;
overflow-y: auto;
width: max-content; /* or width: min-content,
or float:left
or position:absolute
or <td><pre>...</pre></td> */
}This gives you a horizontal scrollbar in addition to the vertical one when there's vertical overflow, which is not what the author wants (typically). This wouldn't: pre {
max-height: 100px;
overflow-y: auto;
overflow-style: overlay;
width: max-content; /* or width: min-content,
or float:left
or position:absolute
or <td><pre>...</pre></td> */
} |
|
Proposal:
|
|
The goals with the suggestion above is double:
|
|
I think |
|
If the width of the scollbar is known to CSS an author could write, The main difficulties I see is are
|
|
Results of the telcon, in my words:
Thus, I propose two values (names pending): value1: Acts like "auto" (doesn't show a scrollbar when the content doesn't overflow), but when using intrusive scrollbars, reserves the space the scrollbar would take up if it was there. (Overlay scrollbars continue to take up zero space regardless of content size.) value2: Acts like value1, but reserves the intrusive-scrollbar size at all times, even when scrollbars are overlay. We should then permanently shelve the idea of standardizing the "overlay" value, and commit to "overlay vs intrusive" being a user/platform choice uncontrollable by CSS. Parallel to this, we should restart the discussion of a "scrollbar width" unit or keyword, so people can reserve space on both sides of an element. Parallel to this, we should discuss if Houdini Layout'd elements always require a "stable" overflow value, such that "overflow: auto" is treated as one of the above two values (probably value1) on Houdini'd elements. That would let us chop out a big chunk of complexity from the layout API that authors will probably usually get wrong anyway. (I'll internally start a discussion about whether Chrome might want to switch |
Oooh, or, since at least Chrome/WebKit already have the |
|
Now that this property is just about reserving space, I don't think " overflow-style" is a good property name. It's more like "scrollbar-gutter: auto/when-scrollable/always;" |
|
Dang yeah, that's pretty good. Tho |
|
This all sounds great, but I'd like to also reopen @rbyers's earlier request to including a way to hide overlay scrollbars entirely and reserve no space. This is useful for image carousels, chat boxes, and for replacement by JS bespoke scrollbars for contact lists and photo albums. Without vendor prefixes, it can only be achieved with complex, bug-prone box tricks or touch-handler fake scrollers. @tabatkins's objection was that we don't want to make it too easy to make sites unusable for users who prefer to click on the scrollbar, and he suggested:
I think tying this to input capabilities is too weird. Some somewhat saner variants would be to tie it to overlay-or-not, or possibly scrollbar-absorbs-clicks-or-not. But, personally my preference would be to just have a |
I agree.
Then again, overflow-gutter (or overflow-style for that matter) incorrectly suggests that this may be a longhand of overflow. So maybe we're better off without an overflow prefix.
Agreed. I had been looking for names for your value1 and value2, and also landed on stable for value1. And if the property is called
I have no strong opinion for or against this part, but if we want it, it feels like it would influence the property and the other values' names. hidden or invisible sounds like an OK name for this value3, but not under a property called ...-gutter. And since that part of the name was what made it possible to call value2 always, if we do want this value3 we have a bit more bikeshedding to deal with.
Also, I am not sure what that implies in terms of bikeshedding, but other than auto, all these values make |
|
Since it sounds like we're converging on some gutter-defining API, I split the "mechanism for disabling scrollbars" debate off into #419. |
|
Bikeshedding a bit more, I think I like:
(and All of these values only have effect when
If people don't have objections to these, I'll write them up proper in a spec. |
|
It's actually a substantially different concept--more like the gutters used for bookbinding, not really a gap between things. So gutter seems better imho... |
|
Whether we call the the property -gutter or -gap, the three value version (auto | stable | always) seems good to me. Adding |
|
@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. |
|
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. |
|
Bikeshedding aside, following the last conf call, we now have 3 proposals:
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). |
|
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. |
|
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: 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 |
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.