w3c / csswg-drafts

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

[css-overflow] scrollbar-gutter should not do anything for non-scrollable boxes #6028

Open emilio opened 3 years ago

emilio commented 3 years ago

https://drafts.csswg.org/css-overflow-4/#scrollbar-gutter-property:

When the force keyword is present stable and always take effect when overflow is visible, hidden or clip in addition auto or scroll. This does not cause a scrollbar to be displayed, only a scrollbar gutter.

Why? overflow: clip doesn't create an scrolling box, so it seems weird scrollbar-gutter somehow affects this.

tabatkins commented 3 years ago

Neither does overflow: visible, but we have it take effect there, too.

emilio commented 3 years ago

Is that useful? That seems weird that now stuff like scrollbar-width or the weird ::-webkit-scrollbar pseudos would have an effect on non-scrollable boxes.

felipeerias commented 3 years ago

It only has an effect when used with the force keyword, otherwise it is ignored.

The reason for this is to be able to align content outside of a scrolling box (header, toolbar...) with content inside of it.

emilio commented 3 years ago

I still think it's wrong. How does it affect inline elements? Svg?

felipeerias commented 3 years ago

According to the spec, it should apply to all elements. Perhaps that should be more specific.

In the Chromium implementation, it affects some inline elements (like images) pretty much like it does block elements: the width of the element remains the same, but there is an additional space reserved along one of or both of the inline edge (kind of like setting a padding on an element with box-sizing: border-box).

MatsPalmgren commented 3 years ago

What's the use case for applying this property on non-scrollable boxes?

emilio commented 3 years ago

Right, I meant non-replaced inline boxes. I think instead of playing whackamole with all different layout types there are this property should not only apply to scrollable boxes. If authors want to do something based on scrollbar sizes like moving content around or what not, we can add environment variables exposing the platform scrollbar size, which is both easier to specify and to implement, and more flexible.

tabatkins commented 3 years ago

What's the use case for applying this property on non-scrollable boxes?

As stated a few comments back:

The reason for this is to be able to align content outside of a scrolling box (header, toolbar...) with content inside of it.

It also lets you keep a stable layout if your app can switch a box from being non-scrollable to scrollable for some reason. (For example, having an editable area initially be inert and overflow:hidden, then switch overflow:auto when activated. Possible use-case: GitHub diff displays when you have lots of files in the diff.)


I think instead of playing whackamole with all different layout types there are this property should not only apply to scrollable boxes.

We do need to exclude non-replaced inlines, but that's all the whackamole that we could possibly have. Scrollbars aren't something special-cased across display modes. I think the property should just be clarified to "all elements capable of displaying scrollbars", perhaps with this detailed in prose to mean anything that will display a scrollbar if set to overflow:scroll.

emilio commented 3 years ago

I disagree. In Gecko at least, the way we implement scrollers is a different box altogether (wrapping the scrolled content).

In Blink / WebKit, the scrollable area seems like a property of the layer / layout object, and looking at Blink's implementation of scrollbar-gutter: force, at the very least this seems to affect various CSSOM methods like scrollWidth etc. It also forces layerization, though I don't know what side effects does that have in practice, seems it might affect paint order (as it behaves as if the element was relatively-positioned / created its own stacking context). So I still think it applying to non-scrollable boxes is a bad idea.

felipeerias commented 3 years ago

@emilio:

If I remember correctly, force elements get their own layer in Chromium simply because a PaintLayerScrollableArea is used to calculate the thickness of the element's hypothetical scrollbars. This is only strictly necessary to support custom scrollbars, otherwise it would be enough to query the current scrollbar theme.

(One advantage of supporting custom scrollbars is that they make it possible to write accurate and portable web tests for scrollbar-gutter, because their thickness can be specified explicitly)

A better implementation would reduce the number of layers to those strictly needed, thanks for pointing it out.

emilio commented 3 years ago

@felipeerias I find it a bit hard to believe that doesn't affect painting order in other unexpected ways, but I don't have the time to check right now.

felipeerias commented 3 years ago

@emilio My point was just that it is an implementation side effect of how Chromium calculates custom scrollbars, not something mandated by the spec.

felipeerias commented 3 years ago

FYI, the issue where force was creating unneeded layers in Chromium has already been fixed:

https://chromium.googlesource.com/chromium/src/+/2402abcb4c84404546998aa55a85cb711ae50eec

chrishtr commented 3 years ago

@felipeerias I find it a bit hard to believe that doesn't affect painting order in other unexpected ways, but I don't have the time to check right now.

In Blink/WebKit, it is true that allocating a PaintLayer (RenderLayer in WebKit) affects paint order. But that's just an implementation mistake (a big one, as it turns out! In Blink we've been working on fixing it for years now.) that should be fixed. In any case, the commit Felipe mentioned above avoids this problem in the case of scrollbar-gutter, and any other effect is also a bug. If an element has overflow:clip and scrollbar-gutter, then paint order should not be affected. Implementations can avoid creating any of these side-effect-causing data structures by just treating scrollbar-gutter as another form of margin.

Also, to re-iterate the use cases already mentioned above:

  1. Align content outside of a scrolling box (header, toolbar...) with content inside of it.
  2. Retain stable layout when switching from a non-scrollable to a scrollable style.

I don't know how common (2) is, but I think (1) is common.

css-meeting-bot commented 3 years ago

The CSS Working Group just discussed [css-overflow] scrollbar-gutter should not do anything for non-scrollable boxes.

The full IRC log of that discussion <dael> Topic: [css-overflow] scrollbar-gutter should not do anything for non-scrollable boxes
<dael> github: https://github.com/w3c/csswg-drafts/issues/6028
<dael> emilio: A bit confused
<dael> emilio: How scrollbar gutter applies to thing with overflow visible or clip
<dael> emilio: That's interaction with a lot of layout models and it's not defined. I think should be defined on scrollable boxes and that's it
<dael> florian: Not dismissing challenge. Good reasons why proposed to work this way
<dael> florian: Some examples might be in spec, some in issue. One example of why you want to apply to not scrollable item is like gmail UI
<smfr> q+
<dael> florian: You have icons in each email and icons in header above list and you want to visually align. Where the icons will be depends on if that part has a gutter. Depends on if scrollbars are overlay or classic. Element that is not scollable but next to and you want visual alignment you need to say give me a gutter that's the same size so I have the same space
<dael> emilio: Could that be env variable?
<dael> florian: Was suggested. Not easy. First, wouldn't be env variable but a unit b/c have scrollbar width that lets you change the size. With an env variable you don't have the size b/c context based it changes
<dael> florian: Also, a whole bunch of them. In the issue. You can't know if scrollbar will be on left or right. Might be decision based on bidi or OS design
<dael> florian: As author you would need a pile of env variables or more likely units to know side, size
<emilio> q+
<dael> florian: Another point is there's a couple of aspects of scrollbar gutter suggested to be variables or units but need different ones. Some use cases need size of classical scrollbar and some other usecases where you want 0 with classical and overlay with new.
<astearns> ack smfr
<tantek> while I agree with the theoretical use-cases of aligning stuff in/on a nonscrollable box with a subsequent (or previous) scrollable box with gutter, has anyone actually seen this in practice? didn't see any links to real world examples in the issue
<tantek> e.g. is this for table header on top of a scrollable table body?
<astearns> ack fantasai
<Zakim> fantasai, you wanted to propose we close this as 'scrollbar-gutter applies to all elements to which overflow applies'
<dael> smfr: I find it weird we would have a property like this that adds eq to padding or margin. It's almost like spacer.gif. Weird way to add layout space. Sympathize with need to match, but would think use of scrollbar gutter should be limited to where scrollbars appear
<dael> fantasai: Want to suggest we solve bymaking applies to be all elements to which overflow property applies. Avoids explicit list in this propdef table and tie them together. Doesn't mean you are assigning overflow scroll
<dael> emilio: I think more tricky to impl. Overflow applies to a lot of things in SVG and whatnot
<dael> TabAtkins: Applies only to flip between visible and hidden. Can be more precise
<dael> emilio: Maybe
<astearns> ack emilio
<fantasai> s/precise/precise, say only elements to which 'overflow: scroll' applies/
<dael> emilio: Reply to florian is you need context for which side scrollbar is on to solve adding spacing. Also true with scrollbar gutter. If element is RtL then either your element needs to be RtL or something needs to happen. That's not well defined in scrollable but not defined in non-scroll
<dael> emilio: You need all the context scrolling box has and need it to match. Having env variables; way FF UI does this you have MQ for overlying scrollbars and then scrollbar width- for overlay there's a MQ
<dael> emilio: I think it's only 2 widths and if they're overlay. That's the 3 bits of state. Sides is trickier but scrollbar gutter doesn't fix it
<dael> florian: Depends on varables. Case of matching nearby I agree doesn't change. Other things it would simplify with env variables and in those you need size. I feel this is a topic for a F2F with a whiteboard
<dael> emilio: Maybe. Generally feel scrollbar gutter applying to non-scrollable will lead to itnerop issues
<astearns> ack fantasai
<Zakim> fantasai, you wanted to comment on rtl
<dael> fantasai: Side comment that having the scrollbar switch side on rtl or ltr is probably not great user interface b/c want consistent side. There are impl that do this, though
<dael> dbaron[m]: FF for a time had a hidden preference to change that and some users cared very deeply about that preference
<dael> florian: I think overall point in the general sense it is not trivial to replace with 1 or more variables.
<fantasai> s/though/though. E.g. Firefox uses OS direction, whereas Chrome uses element direction/
<dael> florian: There are use cases underlying all use cases and the proposed value to add. May be true some are impractical to impl. That is new information to me and should investigate. Reject it's simplier to make it 2 variables and that there's not a use case
<dael> astearns: Have been hearing use case is not strong enough to justify complication of adding scrollbar gutters to things that cannot scroll
<tantek> regarding changing "Applies to:", another option to consider is what scrollbar-width says: https://drafts.csswg.org/css-scrollbars-1/#scrollbar-width "Applies to: boxes to which overflow applies"
<felipeerias> q+
<tantek> +1 astearns
<smfr> q+
<fantasai> WG discussion to add the 'force' value to scrollbar-gutter: https://lists.w3.org/Archives/Public/www-style/2017Feb/0059.html
<dael> emilio: No concerns about it as a property that applies to scrollable things. Proposed values seemed fine when I went through
<dael> astearns: tantek has suggestion in IRC that I believe is similar to fan
<astearns> ack felipeerias
<tantek> s/to fan/to what fantasai suggested
<dael> felipeerias: conceptually I agree force value is a bit weird. Want to align to container with scrollbar with you set scrollbar-width:thing to non-scrollable. Agree it's weird. Problem with scrollbars if they have logic that depends on OS. Either you have something like scrollbar-gutter where you give value or you make the complexity visible to the web author so you have MQ to know about overlay or classical, maybe a selector to know side
<dael> felipeerias: Trade off. I understand some of the concerns and they are reasonable
<astearns> ack smfr
<dael> smfr: Emphasize WK position; whole point of overlay scrollbars is to max space for content. Not a fan of encouraging authors to reserve space. Want to allow authors to move interactive elements from under scrollbar, but fine for text to go there
<tantek> How is text not an interactive element? E.g. text selection
<dael> smfr: General policy is not to encourage authors to avoid that edge. We'd prefer things like env variables that authors can apply to specific elements
<dael> florian: If we want env variables to replace force and allwidth we need different varables. They're opposites. I'm concerned about explosion of units
<dael> fantasai: Note we had discussion on these lines so might be worth looking at that
<florian> s/allwidth/always/
<tantek> clear: scroll-gutter :P
<dael> myles: Goal is not to have a formulation of units. Goal is move indiviual elements. If there's a design solution without a pile of variables would be great.
<chrishtr> q+
<dael> florian: If we decide some usecases have bad tradeoff between desireable and complex I think that's okay. might regret. The claim we can just replace with an env variable, though, we can't 'just' if we want to solve all the things that the solution does now.
<astearns> ack chrishtr
<dael> chrishtr: Looks like we've expanded to not just case from emilio but subsiquent issues about removing always. I think it would be okay to remove always and maybe also do what emilio suggests b/c solves some use cases that we have most consensus on and then we can consider solutions for other use cases in the future
<bmathwig> +q
<dael> astearns: That is one possibility
<dael> florian: I don't have an issue with UAs prioritizing a more easily doable subset of property. As long as we don't rule out some use cases worth exploring whole design. If we say we'll do this and solve the rest with varables and then discover we can't that would be unfortunate.
<dael> chrishtr: I don't htink it would conflict. Subset, emilio's point needs to be edited in. Only applying to scrollable elements
<dael> florian: Means removing force value. You can't support that value w/o applying to other elements
<astearns> ack bmathwig
<dael> bmathwig: From Edge standpoint and based on our use cases I would propose keeping always and auto and discard the rest. Overlay vs classical we don't have use cases for sable, both, or force
<dael> florian: Not stable? Surprised
<dael> bmathwig: If dev doesn't include gutter it's assumed auto so scrollbars overtake. And always they want space cross platofrm and browser to avoid special casing.
<dael> astearns: bmathwig I suggest you put those details into issue #4674. We should add details and we'll bring them back next meeting to see if we can get to resolution
chrishtr commented 3 years ago

Restricting to only scrollable boxes is ok by me, in order to unblock consensus on the most important use case for scrollbar-gutter. See my comment here.

astearns commented 3 years ago

Changing tags for this and #4674 in favor of a breakout session