Re: [csswg-drafts] [css-overflow-4] drawing over the space reserved by `scrollbar-gutter` (#5232)

Part 1: Why I think variable / unit based proposals wouldn't work
----

Having access to scrollbar / gutter width via `env()` or something like that is not that straightforward:
- it would probably needs to be a unit rather than an `env()` variable, otherwise differently sized gutters per element based on [`scrollbar-width: thin`](https://drafts.csswg.org/css-scrollbars/#scrollbar-width) would not be possible.
- Depending on bidi and UA decisions, the scrollbar might be on either side of the element. Since this cannot practically be determined by a stylesheet author, this further reinforces the idea that it needs to be a unit rather than an `env()` variable so that it can be per element, and you'd actually need two of them:: one per side.
- For the use case described here, you'd want a (left/right pair of) unit(s) that is:
    - 0 for overlay scrollbars paired with the `stable` value (since that doesn't create a gutter and you must not poke out of the element)
    - equal to the scrollbar with for overlay scrollbars paired with the `always` value
    - equal to the scrollbar with for classic scrollbars with overflow:auto and scrollbar-gutter:stable or scrollbar-gutter:always if there is no overflow (and thus no visible scrollbar in the gutter).
    - 0 for classic scrollbars with overflow:auto and scrollbar-gutter:auto (because you don't want to overflow under the scrollbar if it's there, nor out of the element if it's not)
    - 0 for classic scrollbars with overflow:scroll
- If we ever want to offer authors the choice between overlay and classic scrollbars through a property, or if we want to allow the UA to make that decision differently on different elements (maybe form some form controls could be different), the (pair of) units is needed to reflect that choice locally.

Variable / units have also been suggested (in https://github.com/w3c/csswg-drafts/issues/4674#issuecomment-577662037) as potential alternatives to the `always`, `force`, and/or `both` values, but that would be hard for the same reasons, and also because the cases where you want the unit to be 0 or to match the scrollbar width vary depending on whether you want to use it for the use case under discussion here, or as alternative to `always`, or to `force`, or to `both`. For instance, unlike the case discussed above, if you're trying to use Variable / units as a replacement for `force`, you'd need them to be always non zero in the case of classic scrollbars. But the cases where you're want it to be zero would be something else yet again if you're trying to use it as a replacement for `both`.

So if we end up needing a pile of units which are zero in various cases, doubled up to deal with left/right, this is starting to look like variables or units is either not going to work, or is going to be highly confusing.

Part 2: Alternative proposal.
----

However, based on an (offline) discussion with @felipeerias, we have found a potential solution.

`scrollbar-gutter` could have one more value: `match-parent`.
* On a scroll container, this has no effect
* on a (non scroll container) block level element, if it's parent has no scollbar-gutter, it has no effect
* on a (non scroll container) block level element, if its parent has a scrollbar gutter, then the element also has a gutter:
    - on the same side(s) as the gutter(s) its parent (plural is in the case the parent has `both`)
    - of the same width as that of its parent (taking into account, if necessary, [`scrollbar-width`](https://drafts.csswg.org/css-scrollbars/#scrollbar-width) on the parent)
    - that is made to overlap (i.e. collapse) with that of its parent

So, here's an example, where you have a scroller, with a gutter, and one of its children wants to extend its background into the parent's gutter, you set `scrollbar-gutter: match-parent` on that child, and you get this:

<img width="288" alt="Screenshot 2020-06-23 18 42 22" src="https://user-images.githubusercontent.com/113268/85388657-50d89000-b581-11ea-812c-ddbb63847678.png">

And this "just works", even if the parent and child have a different bidi direction, even if the parent has a gutter on both sides, regardless of whether the scrollbar is overlay or classic, etc…

More details:
- if the `match-parent` child has a non-zero border and / or margin on the side where the gutter is expected, then the size of the child's gutter is `parent.gutter - child.border - child.margin`, and the child's gutter+border+margin is what collapses with the parent's gutter.
- It could be based on the nearest ancestor with a gutter, rather than the parent, but:
    -  dealing with padding/border/margins of inbetween elements which don't have match-parent seems troublesome.
   - going for the parent avoids expensive lookups far up the tree, unless they're actually needed (in which case you set `match-parent` on the in-between nodes).
   - to avoid unintentional collapsing with the gutters of the root element.
- this works best if `scrollbar-gutter` is not inherited, as discussed in https://github.com/w3c/csswg-drafts/issues/5231

-- 
GitHub Notification of comment by frivoal
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/5232#issuecomment-648047604 using your GitHub account

Received on Tuesday, 23 June 2020 10:14:38 UTC