Scrollable elements in non-default writing modes

FAQ

What is the ChromeStatus entry for this change?

It's called Interoperable Element's scrollLeft and scrollTop in non-default writing modes.

What should I know about scroll positions and writing modes?

One can use the scrollLeft and scrollTop properties to get and set scroll positions of an element with scrollable overflow. The scroll position can be set to specific coordinates using scrollTo() and scroll(). Another way to perform scrolling is to reveal a descendant via scrollIntoView() or to scroll by a certain amount via scrollBy(), scrollLeft += 5 etc.

By default, the lines of the web page are horizontal and flow vertically from top to bottom (CSS writing-mode property set to horizontal-tb) and each one is read from left to right (CSS direction property set to ltr). However, other modes exist such as direction: rtl (e.g. Arabic or Hebrew), writing-mode: vertical-rl (e.g. in Japanese or Korean) or writing-mode: vertical-lr (e.g. Mongolian).

What will change in Chromium?

Chromium will follow the standard behavior:

Is there a feature detection available for this behavior change?

One can use one of the functions below from this script to detect the behavior of scroll coordinates in a browser. It is recommended to cache the result to avoid appending and removing the test <div> each time the function is called, as it is done in this jquery script.

What is the result of the feature detection in my browser?

The result of scroll_coordinates_behavior_with_scrollIntoView() for your browser is the following:

The result of scroll_coordinates_behavior_by_setting_nonpositive_scrollLeft() for your browser is the following:

Browsers following standard behavior will return true for both properties. For the first point, all but old versions of Internet Explorer and Edge will return true. For the second point, Chromium will return false with the legacy behavior and true with the newer behavior.

What are browser scroll conventions?

Latest releases of WebKit (e.g. Safari) or Gecko (e.g. Firefox) use the standard behavior and so will future versions of Blink (e.g. Google Chrome, Edge, Opera). Old versions of browsers can use a different convention that you can check via feature detection.

Am I affected by this change?

You are not affected by this change if:

  1. You only use scrollable elements that overflow in the rightward and downward directions (e.g. default or Mongolian modes).
  2. The first point does not hold, but you only rely on relative scroll positions (e.g. operations like scrollBy() or delta = oldScrollTop - element.scrollTop).
  3. The two first points don't hold, but you perform feature detection to deal with inconsistent conventions of each browser.

Conversely, you may be affected by this change if all of these conditions hold:

How can my content be broken after this change?

Typically, your scrollable elements will scroll to a wrong position or won't scroll at all.

How are you shipping the new behavior?

To detect potential affected URLs, we rely on a use counter which basically measures when a scroll coordinate is incorrectly set to a positive value. Unfortunately, this counter is not very reliable and so we invite users of the top website and libraries triggering this counter to check and update their pages to avoid false positives. This feature detection does not trigger the use counter.

In any case, because of the unreliability of user counter, we are instead progressively shipping the new behavior to a larger and larger amount of users. This might lead to regression and bug reports that we are analyzing carefully.

Anything I should be aware if I rely on library XXX.js?

Some polyfills for ResizeObserver such as ResizeSensor or javascript-detect-element-resize rely on "size change detectors" implemented as scrollable elements. When pages in non-default writing modes use any of these libraries, they will trigger the user counter and so lead to false positives. You are invited to address this by forcing these detectors to be in the default writing mode (writing-mode: horizontal-tb; direction: ltr;). In any case, it is strongly recommended that you update your website to rely on native ResizeObserver implementations when available.

Some libraries such as OverlayScrollbars.js or jquery.rtl-scroll-type used to perform feature detections in a way that triggers the counter and so led to false positives. You are invited to follow the approach from feature detection instead or to upgrade to the latest versions of these libraries.

Where can I report feedback regarding the content of this page?

Please use this GitHub repository. Pull requests are welcome!

Demos and analysis

Default writing mode

In that writing mode, there are more or less natural conventions for scrollable elements that have always been followed by browsers:

  1. Initially render the top left corner of the content by making it match the top left corner of the scrollable element.
  2. Put the horizontal scroll bar on the bottom and the vertical scroll bar on the right.
  3. Define scrollLeft and scrollTop to be equal to zero for this initial position.
0
1
2
3
4
5
6
7
8

Writing mode vertical-lr

If the lines of text are vertical and flowing from left to right (CSS writing-mode property set to vertical-lr) then the start of the content is again the top left corner.

Browsers follow the same convention as above and behave consistently:

0
1
2
3
4
5
6
7
8

Writing mode rtl

If each line flows horizontally from right to left (CSS direction property set to ltr) then browsers follow the following conventions, obtained by inverting the right/left sides:

  1. Initially render the top right corner of the content by making it match the top right corner of the scrollable element.
  2. Put the vertical scroll bar on the left.
0
1
2
3
4
5
6
7
8

Safari and Firefox also follow the third one:

  1. Define scrollLeft to be equal to zero for this initial position.

However, Chrome instead defines scrollLeft to be zero when the element is scrolled to its leftmost position. This means that scrollLeft is nonzero at the initial position.

Writing mode vertical-rl

If the lines of text are vertical and flowing from right to left (CSS writing-mode property set to vertical-rl) then the start of the content is now the top right corner. Continuing with the previous reasoning, the expected behavior should be:

0
1
2
3
4
5
6
7
8

One more time, Firefox and Safari follow these conventions but Chrome defines scrollLeft to be zero when the element its scrolled to its leftmost position.

Additionally, another interoperability issue can be noticed: Chrome and Safari puts the vertical scroll bar on the right side but Firefox puts it on the left side.

Other writing modes

The cases discussed above are the most common writing modes used in practice. However, one can actually combine any value of direction and writing-mode. The latter has sideways-rl and sideways-lr values which are not implemented yet in all browsers.

vertical-lr, rtl

0
1
2
3
4
5
6
7
8

vertical-rl, rtl

0
1
2
3
4
5
6
7
8

sideways-rl

0
1
2
3
4
5
6
7
8

sideways-lr

0
1
2
3
4
5
6
7
8

sideways-lr, rtl

0
1
2
3
4
5
6
7
8

sideways-rl, rtl

0
1
2
3
4
5
6
7
8

Conclusion

  1. Scrollable elements are always initially scrolled so the start of their content is visible and placed at one corner. Behavior is well-defined and implemented consistently.
  2. Relative values of scrollLeft (respectively scrollTop) are also consistent in all browsers: The difference between a start and end scroll position is positive if the content is scrolled rightward (respectively downward).
  3. Absolute values of scrollLeft and scrollTop are compatible in Firefox and Safari: They are alway zero at the initial scroll position. However, Chromium sometimes behaves differently.
  4. Scrollbar positions are compatible in Chromium and Safari. However, Firefox sometimes behaves differently.

Point 2 (relative positions) is explicit in the CSSOM View specification and the description of how to scroll an element assumes a behavior compatible with Firefox and WebKit's for point 3 (absolute positions):

At the time of writing, point 4 (scroll bars position) does not seem to be defined by any specification.