![Bramus](https://web.dev/images/authors/bramus.jpg) Bramus [X](https://twitter.com/bramus) [GitHub](https://github.com/bramus) [Mastodon](https://front-end.social/@bramus) [Bluesky](https://bsky.app/profile/bram.us) [Homepage](https://www.bram.us/) ![Free Debreuil](https://web.dev/images/authors/freedebreuil.jpg) Free Debreuil [LinkedIn](https://www.linkedin.com/in/freedebreuil)


Published: Sep 4, 2026

<br />

The "single-axis scroll containers" feature extends the CSS `overflow` property to support scrollable values (`auto`, `scroll`, `hidden`) combined with `clip` (for example, `overflow: scroll clip`), resulting in scroll containers for only one axis.

While this change unlocks highly requested features such as per-axis sticky positioning, it also introduces extra side-effects across other scroll-dependent features. Because of these potential compatibility risks, we are asking developers to test their websites and provide feedback before this feature rolls out to stable channels.

The feature is available for developer testing in Chrome 154 on the Beta, Dev, and Canary [release channels](https://developer.chrome.com/docs/web-platform/chrome-release-channels). You don't need to turn on a flag.

## The quirk with setting overflow on one axis

Without this feature it was impossible to create a truly single-axis scroll container with CSS. If you configure one axis to scroll while attempting to keep the other axis visible (for example, setting `overflow-x: scroll` and leaving `overflow-y: visible`), the browser's style engine automatically forces the visible axis to compute to `auto` (or `scroll`). This creates a two-dimensional scroller even though you didn't intend to do so.

This quirk becomes very visible when trying to create a table with a sticky top row and sticky first column. In the following example the aim is for the first column to stick to the `.table-wrapper` that scrolls horizontally, and the top row to stick against the document's scroller.

    <div class="table-wrapper" style="overflow-x: auto;">
      <table>
        ...
      </table>
    </div>

    /* Scroll horizontally */
    .table-wrapper {
      overflow-x: auto;
    }

    /* Sticky top row */
    .table-wrapper thead {
      position: sticky;
      top: 0;
    }

    /* Sticky first column */
    .table-wrapper td:first-child {
      position: sticky;
      left: 0;
    }

If you [try it out](https://codepen.io/web-dot-dev/pen/VYmjePe) you'll notice that it doesn't work. This is because of the overflow quirk described earlier: the `.table-wrapper` effectively becomes a two-dimensional scroller. So when `position: sticky` looks up the nearest ancestor scroller for each axis, the result is the `.table-wrapper` element in both cases.

### Live Demo

<iframe height="655" style="width: 100%;" scrolling="no" title="CSS `position: sticky` for Single Axis Scroll Containers" src="https://codepen.io/web-dot-dev/embed/VYmjePe?default-tab=result" frameborder="no" loading="lazy" allowtransparency="true"></iframe>

### Demo Recording

## Single-axis scroll containers fix the quirk

With single-axis scroll containers, you can explicitly prevent that secondary axis from becoming a scroller by using `clip`. That way, `position: sticky` can track two different scroll containers independently.

To fix the table example, pair the horizontal scroll with `overflow-y: clip`.

    .table-wrapper {
      overflow-x: auto;
      overflow-y: clip;
    }

Or, using the `overflow` shorthand:

    .table-wrapper {
      overflow: auto clip;
    }

By doing this, the `.table-wrapper` only acts as a scroll container for the x-axis. The sticky top row will now bypass it and correctly stick to the document's scroller on the y-axis, while the first column continues to stick to the `.table-wrapper` horizontally.

If you are checking this post out in a browser with support, you can see it in action in [the following demo](https://codepen.io/web-dot-dev/pen/ZYeQryE):

### Live Demo

<iframe height="655" style="width: 100%;" scrolling="no" title="CSS `position: sticky` for Single Axis Scroll Containers" src="https://codepen.io/web-dot-dev/embed/ZYeQryE?default-tab=result" frameborder="no" loading="lazy" allowtransparency="true"></iframe>

### Demo Recording

## Affected behaviors

Because single-axis scroll containers change how scrolling contexts are evaluated and created, you may notice changes across other features that rely on scroll containers, such as:

- **`position: sticky`** : As shown, elements will now correctly stick within single-axis scroll containers, improving behaviors for elements constrained by `overflow: clip` on one axis.
- **`overscroll-behavior`** : Since an element can now be a scroll container on just one axis, `overscroll-behavior` might no longer trigger on the clipped axis, potentially affecting custom pull-to-refresh or bounce effects. This change in behavior matches Firefox and Safari.
- **Programmatic scrolling** : Calling scroll APIs (like `Element.scrollTo()`) on a single-axis scroll container now enforces programmatic scroll constraints. The element will refuse to scroll programmatically along the axis defined as clip.
- **Grid and Flex minimum cell sizing** : For scroll containers in grid and flex layout, the default minimum size (`min-width: auto`) normally gets ignored to allow the cells to adjust themselves to the available space. When `overflow: clip` is set on the same axis, the default minimum size will start having an effect, potentially causing the flex or grid container to grow larger.

## Feature detection

To detect support for single-axis scroll containers, query [the `@supports named-feature()` rule](https://www.bram.us/2026/08/27/feature-detecting-undetectable-css-features-with-supports-named-feature/) using the `single-axis-scroll-container` keyword.

    @supports named-feature(single-axis-scroll-container) {
      /* Feature is supported */
    }

As discussed in [CSSWG issue #13677](https://github.com/w3c/csswg-drafts/issues/13677), using `named-feature(single-axis-scroll-container)` is the recommended standard way to detect this capability, as checking using `@supports (overflow: scroll clip)` alone is parse check only, which does not detect whether the browser handles the revised single-axis scrolling behaviors correctly or not.

In JavaScript, use `CSS.supports("named-feature(single-axis-scroll-container)")` to perform this check.

## Feedback wanted

To assess the potential compatibility risks, testing has been conducted [across 190 websites](https://docs.google.com/document/d/1_4zPKOQ8S-Ttn-4BTFaIR7YWkkQYNiF_QlTsOK-k7uE/edit?tab=t.0). Based on this analysis, the changes do not appear to introduce any significant breakages.

However, because single-axis scroll containers fundamentally alter how scrolling contexts are evaluated, a wider net is being cast. You are asked to test websites and web applications on the non-stable [Chrome channels](https://developer.chrome.com/docs/web-platform/chrome-release-channels) to help identify any edge cases before this feature rolls out to stable.

If things start breaking for you, or if you encounter unexpected scrolling behavior, please [file a Chromium bug](https://crbug.com/new).

## Links and Resources

- [Single axis scroll containers explainer](https://github.com/explainers-by-googlers/single-axis-scroll-containers/blob/main/README.md)
- [CSS `position: sticky` now sticks to the nearest scroller on a per axis basis!](https://www.bram.us/2026/03/30/css-sticky-per-axis/)
- [Feature Detecting "Undetectable" CSS Features with `@supports named-feature()`](https://www.bram.us/2026/08/27/feature-detecting-undetectable-css-features-with-supports-named-feature/)