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-4] Effect of scrollbar-gutter on viewport #8099

Open
bramus opened this issue Nov 18, 2022 · 12 comments
Open

[css-overflow-4] Effect of scrollbar-gutter on viewport #8099

bramus opened this issue Nov 18, 2022 · 12 comments
Assignees
Labels
css-overflow-3 Current Work

Comments

@bramus
Copy link
Contributor

bramus commented Nov 18, 2022

Testing the behavior of various browsers wrt scrollbar-gutter tells me it’s not interoperable. The spec doesn’t really define what should happen, so this needs work.

The tests

All tests are being run using the dedicated test pages on https://interop-2022-viewport.netlify.app/. Using the options on each testpage, the vw bars have been hidden so that they don’t cause extra overflow.

scrollbar-gutter: stable (short content) scrollbar-gutter: stable (long content) scrollbar-gutter: stable both-edges; (short content) scrollbar-gutter: stable both-edges; (long content)
Firefox 107 on macOS image image image image
Chrome 110 on macOS image image image image
Safari TP 158 on macOS no support no support no support no support

(I’ve only had time to test desktop browsers with support on macOS with scrollbars set to always visible)

Findings

  • Firefox 107
    • Always resizes the ICB.
    • Always repositions the ICB.
    • Always resizes the LVP.
    • Never repositions the LVP which doesn’t play nice with stable both-edges and the fact that the LVP gets resized.
  • Chrome 110
    • Always resizes the ICB.
      • The reported value through document.documentElement.clientWidth is wrong, though.
    • Always repositions the ICB.
    • Only resizes the LVP if scrollbars are actually there.
    • Only repositions the LVP for stable both-edges when the scrollbars are actually there.
  • Safari TP 158
    • No support

Expected results

  • I would expect browsers to resize the ICB, so that things like viewport units remain stable. This is currently correct in all browsers.

  • I would expect browsers to only resize the layout viewport when the scrollbars are actually present. This way it’s possible for a fixedpos element to cover the entire viewport.

    el {
      position: fixed;
      inset: 0;
    }

    If the LVP were to be resized when no scrollbars are visible, an author would not be able to cover the entire viewport in case stable is used: there would be a small strip visible on the scrollbar area.

  • I would expect browsers to not reposition the layout viewport – not even when stable both-edges is used. This again for fixedpos element purposes. If the LVP were to be repositioned, an author would not be able to cover the entire viewport in case stable both-edges is used: there would always be a small strip visible on the opposing side of the scrollbar area.

@bramus
Copy link
Contributor Author

bramus commented Nov 21, 2022

RE Chrome vs “The reported value through document.documentElement.clientWidth is wrong, though.”

This is as per current spec:

If the element is the root element and the element’s node document is not in quirks mode […] return the viewport width/height excluding the size of a rendered scroll bar (if any).

I say this feels wrong here because the visualised ICB (red dashed outline) does not match the reported values. Therefore I would like to suggest to adjust this definition so that it also caters for reserved scroll bar space.

@bramus
Copy link
Contributor Author

bramus commented Nov 21, 2022

RE “I would expect browsers to only resize the layout viewport when the scrollbars are actually present” and “I would expect browsers to not reposition the layout viewport”

This is from a POV where authors should be able to entirely cover the viewport. However, as scrollbar-gutter came to existence for visual stability, this makes no sense for posfixed elements as they would shift positions when a scrollbar would be rendered.

An updated expectation in that case – putting visual stability first – would be the opposite as I have suggested:

  • I would expect browsers to resize the layout viewport. This way layout remains stable when no scrollbars are shown and when scrollbars are shown.
  • I would expect browsers to reposition the layout viewport. This way layout remains stable when no scrollbars are shown and when scrollbars are shown.

This way layout remains stable when the content grows/shrinks:

You can try this out in this demo: https://cdpn.io/pen/debug/PoaEgoW/629275fd041fcf38696ee70e6ee75974 (source)

scrollbar-gutter: stable (short content) scrollbar-gutter: stable (long content)
Firefox 107 on macOS image image
Chrome 110 on macOS image image

(Firefox works as expected here. Chrome affected by https://bugs.chromium.org/p/chromium/issues/detail?id=1251856)

BUT, I’m still wondering about how authors could then cover the viewport entirely, especially when using scrollbar-gutter: stable both-edges. On the screenshots above, with the expectations listed just above, there’s no direct way to cover the bright green trip on the right.

Using negative insets – set to env(scrollbar-inline-size)? – could fix the dimensions of the box, but this is only needed when there is no overflow. In case there is overflow, the viewport would be sized correctly.

Maybe it should simply be accepted that scrollbar-gutter does not play nice with position: fixed?

Or maybe the proposed match-parent on the fixedpos elements could be a solution here? This would however – and I know I’m going back full circle here – require the viewport not the get resized/repositioned.

@jonjohnjohnson
Copy link

jonjohnjohnson commented Mar 10, 2023

On the screenshots above, with the expectations listed just above, there’s no direct way to cover the bright green trip on the right.

I want to add that (in at least FF) when the scrolling element is not overflowing and set to overflow-y: auto that elements background (bright green) shows in the scrollbar gutter. If overflow-y is set to scroll then the elements scrollbar track shows in the scrollbar gutter. Is this what we want?

@simevidas
Copy link
Contributor

Chrome 110
Only resizes the LVP if scrollbars are actually there.

Is Chrome’s behavior buggy? I checked in Chrome stable (version 116), and the LVP did resize even though the scrollbar is not present.

<div class="fixed">987654321</div>
html {
  scrollbar-gutter: stable;
}

.fixed {
  position: fixed;
  inset: 0;
  background: gold;
  text-align: right;
}

Test page: https://output.jsbin.com/xeyubex/quiet

As you can see in the screenshot, the right-aligned text is fully visible. However, if I resize the browser window, the LVP grows, and the last two numbers “21” are hidden behind the gutter. This must be a bug.

Screenshot of test page in Chrome

@simevidas
Copy link
Contributor

simevidas commented Sep 5, 2023

Hm, I’m leaning towards not resizing the layout viewport.

I would expect browsers to resize the layout viewport. This way layout remains stable when no scrollbars are shown and when scrollbars are shown.

The “layout” is the layout of fixed-positioned elements. The page layout is already stable because the ICB is resized (by scrollbar-gutter: stable). I think keeping the non-fixed page layout stable is enough. Why would it be important for fixed-positioned elements to also have a stable layout? I think this needs to be shown via a use-case.

@simevidas
Copy link
Contributor

simevidas commented Sep 18, 2023

Another thing that should probably be tested and debated is the effect on the visual viewport. Currently, the following two statements are true:

  1. The visual viewport either has the same size (in CSS pixels) as the layout viewport, or it’s smaller than the layout viewport. In other words, the visual viewport is never larger than the layout viewport.
  2. The visual viewport matches exactly what the user sees at all times.

If the decision is made that scrollbar-gutter: stable reduces the width of the layout viewport, then the above two statements can no longer both be true.

  • If the width of the visual viewport is not reduced by scrollbar-gutter, then the visual viewport will be wider than the layout viewport, which contradicts the fist statement.
  • If the width of the visual viewport is reduced by scrollbar-gutter, then it will no longer include the bright green strip (in the demo above). This contradicts the second statement because the user can see the strip, but it’s outside of the visual viewport.

The most sensible option would probably be to reduce the width of the layout viewport, but not to reduce the width of the visual viewport. The main question is, would having the visual viewport be wider than the layout viewport cause breakage on websites.

@yisibl
Copy link
Contributor

yisibl commented Jun 12, 2024

I want to emphasize again that scrollbar-gutter is too complex(#4674). Maybe env(scrollbar-inline-size) #4691 is a better way out. cc @argyleink

Normally when opening a modal dialog we want the page behind it not to be scrollable, which requires adding html { overflow: hidden; }, but since the scrollbar is hidden it causes the content of the page to be offset to the right.

scrollbar-gutter: stable solves this problem, but after opening the dialog you will notice a red background on the right side, which is very strange.

This is a very important scenario that seriously affects the usability of the <dialog> element. Both Chrome and Firefox have this issue.

Demo: https://scrollbar-gutter-stable-bug.glitch.me/

image


stable both-edges will have more serious compatibility problems:

data:text/html;charset=UTF-8,<!doctype html> <style>html { scrollbar-gutter: stable both-edges; background: linear-gradient(to right, green, yellow) red; } * { margin: 0; padding: 0; }</style> <span class="foo">test

2024-08-30 update

The scrollbar-gutter has been implemented in Safari TP and doesn't seem to have this bug.

image

@bramus
Copy link
Contributor Author

bramus commented Jun 12, 2024

In #9904 (comment) we resolved that top layer / fullscreen elements paint over the gutters. I think that solves your problem, @yisibl.

@JeroenReumkens
Copy link

@bramus Could it be that this fix now causes position fixed top-layer elements to not respect the scrollbar-gutter anymore and thus shift to the right?

In the attached video the nav that appears is a popover element, it has position:fixed and inset: 0 (like as is default), plus full width and height. Then the hamburger icon lives in :root with position: fixed; right: 8px; top: 8px;. The close button lives inside the popover and has a similar fixed position. Due to the popover overlaying the scrollbar gutter, the "right 8, top 8" is in fact a different position, thus shifting the button.

I'm not 100% sure in which Chromium version the fix you mention was released though:
Chromium Engine Version 126.0.6478.57.

CleanShot.2024-06-20.at.10.04.00.mp4

@yisibl
Copy link
Contributor

yisibl commented Jun 20, 2024

In #9904 (comment) we resolved that top layer / fullscreen elements paint over the gutters. I think that solves your problem, @yisibl.

There should be three scenarios here, #9904 (comment) seems to solve only the first case.

  1. a top layer element with position: fixed
  2. a normal element with position: fixed
  3. a background color problem

@jonaskuske
Copy link

Why would it be important for fixed-positioned elements to also have a stable layout? I think this needs to be shown via a use-case.

The use case is a fixed header / navigation bar, which is very common for all kinds of applications. When the scrollbar disappears and scrollbar-gutter kicks in, page content stays stable but the header widens and all center and right-aligned content within shifts. This can be seen in the video by @JeroenReumkens above

@simevidas
Copy link
Contributor

simevidas commented Jun 28, 2024

@jonaskuske

Due to the popover overlaying the scrollbar gutter

I would love to see a demo of that. (Sorry, I haven’t started testing with popover yet, so I’m not familiar.) Fixed-positioned elements normally cannot overlay a page’s classic scrollbar nor scrollbar gutter, so if a popover can do it, that is a new behavior that changes things significantly.

@frivoal frivoal self-assigned this Jul 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-overflow-3 Current Work
Projects
None yet
Development

No branches or pull requests

7 participants