The useScrollLock hook currently has issues:
position: fixed elements need to have their width or right properties compensated by the removed scrollbar width, otherwise they shift over to the right once scroll locking is activated on the body. Regular content is unaffected. To complicate matters more, in some systems, the <body> scrollbar appears on the left of the screen; this means the left property, if specified, would need to be compensated under certain conditions.
- When
overflow-y: scroll is applied to the <body>, the removed scrollbar padding compensation itself causes layout shift and needs to be ignored. There may be other layout settings where this is the case as well.
radix-ui/primitives#1925
The scrollbar-gutter: stable CSS property, when applied to <html>:
- Is unsupported in Safari
- Fully solves this issue in Firefox
- Is bugged in Chrome, as initial shift still occurs, then works on subsequent locking until a resize occurs - making it unusable in practice.
Possible solutions
- @vladmoroz has a demo as an alternative that could "just work" and require no manual intervention: https://codesandbox.io/p/sandbox/remove-scroll-poc-forked-pqfyhf
- If the above doesn't work out - first, we need to remove the
padding compensation under certain layouts. However, position: fixed will still need their layout adjusted for the removed scrollbar width. We need to add a CSS variable to the root such as --base-ui-removed-scrollbar-width that users can use to apply to their position: fixed elements: width: calc(100% - var(--base-ui-removed-scrollbar-width, 0px)) or right: var(--base-ui-removed-scrollbar-width, 0).
Search keywords: scroll-lock
The
useScrollLockhook currently has issues:position: fixedelements need to have theirwidthorrightproperties compensated by the removed scrollbar width, otherwise they shift over to the right once scroll locking is activated on the body. Regular content is unaffected. To complicate matters more, in some systems, the<body>scrollbar appears on the left of the screen; this means theleftproperty, if specified, would need to be compensated under certain conditions.overflow-y: scrollis applied to the<body>, the removed scrollbarpaddingcompensation itself causes layout shift and needs to be ignored. There may be other layout settings where this is the case as well.radix-ui/primitives#1925
The
scrollbar-gutter: stableCSS property, when applied to<html>:Possible solutions
paddingcompensation under certain layouts. However,position: fixedwill still need their layout adjusted for the removed scrollbar width. We need to add a CSS variable to the root such as--base-ui-removed-scrollbar-widththat users can use to apply to theirposition: fixedelements:width: calc(100% - var(--base-ui-removed-scrollbar-width, 0px))orright: var(--base-ui-removed-scrollbar-width, 0).Search keywords: scroll-lock