Unlock Immediate Diagonal Scrolling with CSS scroll-axis-lock: none

The new CSS scroll-axis-lock property allows you to disable the browser’s default scroll axis-locking behavior (aka “railing”), allowing users to immediately perform a diagonal scroll.

~

Scroll Axis Locking?

By default, a browser often “locks” a user’s scrolling gesture to a single axis when that gesture starts with significantly more movement in one axis than in the perpendicular axis.

For example, say a user drags their finger on the screen such that the element underneath the finger would be scrolled by 500px in the y-axis and 3px in the x-axis. Because the gesture is almost entirely vertical, the browser might interpret the user’s intent to be a perfectly vertical scroll. As such, the browser can ignore the 3px scroll delta and (possibly) all further x-axis deltas for the remainder of the gesture. In this case, the browser has “locked” the scroll to the y-axis — a technique also known as “railing”.

Recording of the demo showing a vertical scroll performed on a trackpad. Even though the user input (the dashed red line) was not perfectly straight, the browser performed a perfect vertical scroll (solid blue line)

In many cases, this scroll-locking behavior improves the user’s experience by avoiding accidental scrolls along the other axis when the user’s intent was to scroll only one axis.

However, in cases where you wish an element to always be diagonally scrollable, this locking behavior forces the user to start their gesture at an angle that doesn’t trigger the locking, often not in alignment with the author’s intended user experience.

Thankfully, a recent change to CSS now offers control over this, namely the scroll-axis-lock property described in the CSS Overflow 5 specification.

💁‍♂️ Note that this axis-locking behavior totally depends on the browser and platform. Touch-only platforms (such as an iPhone) typically don’t scroll lock at all. Safari on macOS for example is very strict at it, while Chrome on macOS tries to more closely reflect your scroll’s intent (but still applies some locking)

Compare these two screenshots of Safari and Chrome: Safari’s scroll axis-locking results in a more etch-a-sketch-like scroll when scrolling in the shape of a circle (or attempt thereof 😅).

A circle-shaped scroll performed in Safari on macOS. The actual scroll (solid blue line) is much more angled the actual scroll input (dashed red line)
A circle-shaped scroll performed in Chrome on macOS. The scroll (solid blue line) resembles the scroll input (dashed red line), but is not 100% following the input.

~

Control scroll axis-locking with scroll-axis-lock

The scroll-axis-lock property gives you control scroll axis-locking. The property accepts the following values:

  • auto (default): The browser locks the scroll to a single axis if it determines the gesture is predominantly 1-dimensional. The browser may allow you to break out of scroll axis lock as part of your current gesture, but the thresholds to do that are different per browser and platform.
  • none: Disables the locking mechanism entirely. The scroll container will faithfully follow the user’s exact input, allowing for unrestricted diagonal panning.
.scroller {
  scroll-axis-lock: auto; /* Default */
  /* or */
  scroll-axis-lock: none;
}

In the following screenshots, you can compare how both values behave. The screenshots both show Chrome 153 on macOS, but with a different scroll-axis-lock value. The scroll is performed using a trackpad.

A scroll performed in Chrome on macOS with scroll-axis-lock: auto. The scroll (solid blue line) resembles the scroll input (dashed red line), but is not 100% following the input.
A scroll performed in Chrome on macOS with scroll-axis-lock: none. Because scroll axis-locking is disabled, the scroll (solid blue line) is identical to the scroll input (dashed red line).

~

Try it yourself

To feel the difference yourself (and to create the screenshots and videos above), I built a demo that samples your pointer’s X/Y input deltas and compares them against the actual scrollLeft and scrollTop output of the container.

See the Pen Scroll Axis Lock by Bramus (@bramus) on CodePen.

If you try scrolling diagonally with scroll-axis-lock: auto, you’ll notice the status indicator flag an “Axis Locked” warning. The browser detects a slight dominant axis, locks it, and ignores your perpendicular input. As mentioned before this depends on the browser and platform, so your mileage may vary

If you set the toggle to scroll-axis-lock: none, and try again. The grid now immediately pans in both directions simultaneously, exactly following your fingers.

~

# Browser Support

💡 Although this post was originally published in August 2026, the list below is constantly being updated. Last update: Aug 9, 2026.

Support for scroll-axis-lock looks like this:

Chromium (Blink)

✅ Supported in Chromium 153

Firefox (Gecko)

❌ No Support

Safari (WebKit)

❌ No Support

~

Feature Detection

There is no real need to feature detect this, as you can safely use scroll-axis-lock today as a progressive enhancement. Since it doesn’t break anything when ignored, you can just declare it directly 🙂

If you really do need to feature detect it — perhaps to load some alternative code? — you can use an @supports rule in CSS or CSS.supports() in JS to check.

@supports (scroll-axis-lock: none) {
  /* Control over scroll-axis locking supported */
}
if (CSS.supports('scroll-axis-lock: none')) {
  /* Control over scroll-axis locking supported */
}

You can see it in action in the following demo:

See the Pen
CSS scroll-axis-lock Support test
by Bramus (@bramus)
on CodePen.

~

🔥 Like what you see? Want to stay in the loop? Here's how:

I can also be found on 𝕏 Twitter and 🐘 Mastodon but only post there sporadically.

Published by Bramus!

Bramus is a frontend web developer from Belgium, working as a Chrome Developer Relations Engineer at Google. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

The thoughts and ideas expressed in this post are my own and not that of my employer. Unless noted otherwise, the contents of this post are licensed under the Creative Commons Attribution 4.0 License and code samples are licensed under the MIT License

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.