Skip to content

chearon/scrollbugs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 

Repository files navigation

Scrollbugs

Web browsers exhibit some inconsistencies when it comes to handling scrolled content. This is an attempt to categorize and explain them, and provide work-arounds and layout tests.

  1. Scrolling block (flow) elements and grid elements
  2. Scrolling flexboxes
  3. Scrolling in a shrinkwrapped (minmax(0, 1fr) with max-height) grid
  4. Shifting down visible content in a scroll area
  5. Scrolling grid flex item

Layout bugs

The following situation is where the layout differences below happen:

  • Scrollbars have size (Windows-style or when traditional scrollbars are enabled on macOS)
  • overflow: auto
  • Vertical overflow that creates a vertical scrollbar
  • No constraint (max-width etc) in the horizontal direction

Note that browsers are consistent in the following:

  • overflow: scroll always adds scrollbars to the size of the element
  • Horizontal scrollbars are always added to the size of the element

Firefox, Edge, and Safari (for the most part) shrink the element's inner width to fit the scrollbar and avoid forcing a relayout on the parent element. Chrome adds the scrollbar to the element's total width and does not shrink content, unless its outer size constraints are reached.

Layout bug #1

Chrome adds the vertical scrollbar to the total size of the block element, other browsers don't.

Examples

Work-arounds

  • Set a fixed width on the scrolling element or some parent element to make everything layout with definite size
  • Detect the shrink-width behavior and if it exists, add the scrollbar size

Layout bug #2

Safari and Chrome add the scrollbar to a flexbox's size. Safari initially subtracts the scrollbar until its inner content is laid out again (for example, by toggling flex).

Example

Work-arounds

The best way is to just avoid this layout - if you need to scroll a flexbox, try wrapping it with something else that scrolls, like another flexbox and scroll the flex item.

Behavior bugs

These bugs happen while the user is scrolling.

Behavior bug #1

In a "shrinkwrap" grid layout, Safari and Chrome discard the scroll position if content triggers a relayout while the user is dragging the scrollbar (bug)

Using minmax(0, 1fr) along with max-height and max-width gives you a magical layout. You can make a container that grows as its content does and gets no larger, and also shrinks/scrolls when it hits a specified limit. Safari and Chrome have just one issue with this layout when using the mouse to drag the scrollbar.

Examples

Work-arounds

Detect if the width/height of the content has hit the constraint and if so, change max-width/max-height to width/height

Behavior bug #2

Chrome attempts to keep visible content in a scrolling viewport if it would be shifted down by relative positioning changes (div added before content, or height of a div before the content is changed)

Chrome probably added this feature to help with badly coded webpages that have ads which change size or load while the user is reading. Unfortunately this behavior can be a nightmare if you're implementing virtual scrolling or something similar.

Example

Work-arounds

  • Use overflow-anchor: none. This is the best/fastest solution.
  • Replace the visible elements in the viewport with new ones when you update the content (e.g. use :key in Vue)

Behavior bug #3

A grid as a flex item that is also a scroll root can sometimes change size in Chrome

If appended with JS, the layout will be wrong on the first pass, but when the user interacts in a way that causes layout inside the flex item (like appending a grid item) it will self-correct.

Chrome bug: 1042399

Example

About

List of known browser bugs/inconsistencies involving CSS layouts with scrollbars

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published