CSS & layout

The default axis-lock finally has an off switch

The default axis-lock finally has an off switch

You built a map. Or a canvas, or a wide diagram — anything scrollable on both axes. The user drags at a rough 45 degrees and the view slides sideways. Or straight down. Never diagonally. Somewhere between the touchpad and the viewport, the browser decided you meant one axis and latched onto it.

That behaviour has a name: scroll axis locking, sometimes just "railing". Until now you had no CSS handle on it. Bramus Van Damme covers a new property that gives you one: scroll-axis-lock, from the CSS Overflow 5 specification.

What the property does

scroll-axis-lock takes two values.

auto is the default. The browser is free to lock scrolling to whichever axis wins in the input gesture, which is what shipped engines already do.

none turns the lock off. A 2D scroller then follows the input vector directly, so a diagonal drag scrolls diagonally.

That is the whole property. One declaration on the scroll container:

.map {
  overflow: auto;
  scroll-axis-lock: none;
}

No JavaScript hook, no wheel-event trickery, no per-frame vector math. You are telling the engine to skip a heuristic it was applying on your behalf.

Why railing exists at all

Axis-locking is not an oversight. On a touchpad or a mouse wheel, small unintended deviations off the main direction are the rule, not the exception. Snapping the scroll to the dominant axis is what makes a long article feel like it scrolls down instead of drifting a couple of pixels sideways on every flick.

The trade-off shows up the moment the surface stops being an article. On a map, a game board, a whiteboard, or a wide flowchart, "drift" is the input. The user meant that 30-degree pan. Railing to the vertical then feels like the app is fighting them.

The current behaviour is not uniform. Bramus notes that touch-only platforms like iPhone typically do not scroll-lock, Safari on macOS is strict about it, and Chrome on macOS applies some locking. The same page can feel different in three environments, and none of them are wrong. They are each picking a default for a class of gesture.

scroll-axis-lock: none is how you say: for this scroller, on any platform, do not pick.

Where support stands

Bramus reports Chromium started supporting the property in Chromium 153. Firefox does not have it. Safari does not have it. So on the day it lands, you are enabling a smoother diagonal drag for one engine and leaving the other two on their current behaviour.

Two things follow from that.

First, treat the declaration as a progressive enhancement. On engines that ignore it, users get the platform default they already had, which, on iPhone, is often already unlocked anyway. Nothing regresses.

Second, if you need to branch other CSS on the same capability, feature-detect it the ordinary way:

@supports (scroll-axis-lock: none) {
  /* refinements that only make sense when the lock is really off */
}

Or the JS mirror, CSS.supports('scroll-axis-lock: none'), when the branch lives in script.

Try it on your next 2D scroller

Anywhere you currently tell users to "hold Shift to scroll horizontally", or you have wired a wheel listener to blend deltaX and deltaY yourself, scroll-axis-lock: none is the cleaner primitive. The blend happens at the compositor, not inside your event handler. The gesture no longer needs a keyboard modifier to escape one axis.

Two things worth watching next. Firefox and WebKit picking the property up, so "does this feel right" stops being an engine question. And whether the value list grows — right now it is a binary switch, and 2D scrollers are the shape of the problem where a middle ground would matter most.

Source: bram.us (bram.us)

Related
CSS & layout

Styling the dialog element: open is not the same as modal

A CSS-Tricks walkthrough by Geoff Graham lays out the styling model for HTML's dialog element — the modal-versus-non-modal split, three overlapping pseudo-classes, and where the animations plug in.

August 8, 2026
CSS & layout

::highlight() with a text-shadow safety net

The CSS Custom Highlight API lets you paint arbitrary text ranges from JavaScript, no wrapper spans required. A text-shadow fallback keeps the effect intact when the API is not there.

August 6, 2026
CSS & layout

Gap decorations: column-rule finally leaves multi-column

Chrome and Edge 149 ship CSS gap decorations, extending column-rule to grid and flexbox and adding row-rule for the other axis. The syntax was reworked before landing, so here is what actually changed and what to reach for first.

August 4, 2026