Skip to content

Conversation

@atomiks
Copy link
Contributor

@atomiks atomiks commented Aug 9, 2025

Closes #1100
Closes #2706

data-* attributes are applied to Root, Viewport, and Scrollbar

/** Whether horizontal overflow is present. */
hasOverflowX: boolean;
/** Whether vertical overflow is present. */
hasOverflowY: boolean;
/** Whether there is overflow on the inline start side. */
overflowXStart: boolean;
/** Whether there is overflow on the inline end side. */
overflowXEnd: boolean;
/** Whether there is overflow on the block start side. */
overflowYStart: boolean;
/** Whether there is overflow on the block end side. */
overflowYEnd: boolean;
/** Whether the scrollbar corner is hidden. */ 
cornerHidden: boolean; 

// cornerHidden is not exposed as a data attribute
// [data-has-overflow-x][data-has-overflow-y] means the corner is visible
// it's slightly strange to see `data-corner-hidden` as a default for common scroll areas

CSS variables are added to Root:

/**
 * The distance from the horizontal inline start edge in pixels.
 * @type {number}
 */
scrollAreaOverflowXStart = '--scroll-area-overflow-x-start',
/**
 * The distance from the horizontal inline end edge in pixels.
 * @type {number}
 */
scrollAreaOverflowXEnd = '--scroll-area-overflow-x-end',
/**
 * The distance from the vertical block start edge in pixels.
 * @type {number}
 */
scrollAreaOverflowYStart = '--scroll-area-overflow-y-start',
/**
 * The distance from the vertical block end edge in pixels.
 * @type {number}
 */
scrollAreaOverflowYEnd = '--scroll-area-overflow-y-end',

In addition, there's a configuration prop to determine when the attrs should be added:

    /**
     * The threshold in pixels that must be passed before the overflow edge attributes are applied.
     * Accepts a single number for all edges or an object to configure them individually.
     * @default 0
     */
    overflowEdgeThreshold?:
      | number
      | Partial<{
          xStart: number;
          xEnd: number;
          yStart: number;
          yEnd: number;
        }>;

@atomiks atomiks added type: new feature Expand the scope of the product to solve a new problem. component: scroll area Changes related to the scroll area component. labels Aug 9, 2025
@pkg-pr-new
Copy link

pkg-pr-new bot commented Aug 9, 2025

Open in StackBlitz

pnpm add https://pkg.pr.new/mui/base-ui/@base-ui-components/react@2478
pnpm add https://pkg.pr.new/mui/base-ui/@base-ui-components/utils@2478

commit: 35109fa

@netlify
Copy link

netlify bot commented Aug 9, 2025

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 35109fa
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/68cbc169fdd1eb000815fe96
😎 Deploy Preview https://deploy-preview-2478--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@mui-bot
Copy link

mui-bot commented Aug 9, 2025

Bundle size report

Bundle Parsed Size Gzip Size
@base-ui-components/react 🔺+1.88KB(+0.61%) 🔺+542B(+0.55%)

Details of bundle changes

Generated by 🚫 dangerJS against 51392ce

@atomiks atomiks force-pushed the feat/scroll-area-overflow-presence branch from d267b68 to 0ab54c9 Compare August 9, 2025 08:42
Comment on lines 15 to 20
"data-has-overflow-x": {
"description": "Present when the scroll area has horizontal overflow."
},
"data-has-overflow-y": {
"description": "Present when the scroll area has vertical overflow."
},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Present when scrollWidth/Height > clientWidth/Height

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Present when the Scroll Area's content is taller than the viewport" ?

Comment on lines 21 to 33
"data-overflow-x-end": {
"description": "Present when there is overflow on the inline end side for the horizontal axis."
},
"data-overflow-x-start": {
"description": "Present when there is overflow on the inline start side for the horizontal axis."
},
"data-overflow-y-end": {
"description": "Present when there is overflow on the block end (bottom) side."
},
"data-overflow-y-start": {
"description": "Present when there is overflow on the block start (top) side."
}
},
Copy link
Contributor Author

@atomiks atomiks Aug 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Present when .scrollTop/Left > 0 for start

I'm curious if there should also be CSS variables for the scroll amount if you want to transition the strength of e.g. an overflow gradient by the amount. Maybe CSS scroll-driven animations already solve this, though

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious if there should also be CSS variables for the scroll amount if you want to transition the strength of e.g. an overflow gradient by the amount. Maybe CSS scroll-driven animations already solve this, though

I haven't needed such variable for my use case so far, but I agree that it would be interesting.

Here we could also decide to expose it only if/when needed?

@atomiks atomiks force-pushed the feat/scroll-area-overflow-presence branch 5 times, most recently from 532ec7c to c2aa002 Compare August 9, 2025 09:31
@atomiks atomiks force-pushed the feat/scroll-area-overflow-presence branch from c2aa002 to 51392ce Compare August 9, 2025 09:36
@ciampo
Copy link

ciampo commented Aug 19, 2025

@atomiks

Does the presence of data-overflow-{x,y}-start/data-overflow-{x,y}-end need to have a threshold? Right now if it's scrolled by 1px from the start, it gets added, and same if you're only 1px away from the end.

In my experience / for my use case, a threshold wouldn't be needed. I think we can be "lazy" and expose the option only if/when needed.

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Aug 22, 2025
@atomiks atomiks mentioned this pull request Sep 9, 2025
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged. label Sep 17, 2025
@atomiks atomiks force-pushed the feat/scroll-area-overflow-presence branch from e4630b7 to 3940537 Compare September 17, 2025 04:05
@mui-bot
Copy link

mui-bot commented Sep 17, 2025

Bundle size report

Bundle Parsed size Gzip size
@base-ui-components/react 🔺+3.09KB(+0.88%) 🔺+960B(+0.86%)

Details of bundle changes

@atomiks atomiks force-pushed the feat/scroll-area-overflow-presence branch 2 times, most recently from 6b744a7 to 6decd43 Compare September 17, 2025 05:00
@atomiks atomiks force-pushed the feat/scroll-area-overflow-presence branch from 6decd43 to b1effeb Compare September 17, 2025 05:08
@atomiks atomiks force-pushed the feat/scroll-area-overflow-presence branch from 9734c83 to 6aeb302 Compare September 17, 2025 05:33
@atomiks atomiks marked this pull request as ready for review September 17, 2025 05:33
"data-has-overflow-y": {
"description": "Present when the scroll area content is taller than the viewport."
},
"data-overflow-x-end": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the advantage of having separate attributes for -start and -end?
We could use data-has-overflow-x="start end".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edge scroll gradients work better with boolean attrs.

Compare:

.fade-start[data-overflow-y-start],
.fade-end[data-overflow-y-end] {
  opacity: 1;
}

This breaks unless you use ~= token matchers which isn't intuitive:

.fade-start[data-has-overflow-y="start"],
.fade-end[data-has-overflow-y="end"] {
  opacity: 1;
}

@atomiks atomiks changed the title [scroll area] Overflow presence state attributes [scroll area] Add overflow presence state attributes and CSS variables Sep 18, 2025
@atomiks atomiks force-pushed the feat/scroll-area-overflow-presence branch from 4b49b9c to 35109fa Compare September 18, 2025 08:23
@atomiks atomiks merged commit 22acea0 into mui:master Sep 18, 2025
20 checks passed
@atomiks atomiks deleted the feat/scroll-area-overflow-presence branch September 18, 2025 08:53
atomiks added a commit to atomiks/base-ui that referenced this pull request Sep 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: scroll area Changes related to the scroll area component. type: new feature Expand the scope of the product to solve a new problem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[scroll area] state [scroll area] Need a styling attribute to check for overflow presence

4 participants