Scroll Area
A native scroll container with custom scrollbars.
View as MarkdownAnatomy
Import the component and assemble its parts:
import { ScrollArea } from '@base-ui/react/scroll-area';
<ScrollArea.Root>
<ScrollArea.Viewport>
<ScrollArea.Content />
</ScrollArea.Viewport>
<ScrollArea.Scrollbar>
<ScrollArea.Thumb />
</ScrollArea.Scrollbar>
<ScrollArea.Corner />
</ScrollArea.Root>Examples
Both scrollbars
Use <ScrollArea.Corner> to prevent the scrollbars from intersecting.
Gradient scroll fade
Use the viewport overflow CSS variables to fade the scroll edges, which gradually increases in strength as the user scrolls away from the edges.
The CSS variables do not inherit by default to improve rendering performance in complex scroll areas with deep subtrees. To use them in child elements (or pseudo-elements on <ScrollArea.Viewport>), you must manually set each variable to inherit.
.Viewport {
&::before,
&::after {
content: '';
display: block;
left: 0;
width: 100%;
position: absolute;
pointer-events: none;
border-radius: 0.375rem;
transition: height 0.1s ease-out;
}
&::before {
--scroll-area-overflow-y-start: inherit;
top: 0;
height: min(40px, var(--scroll-area-overflow-y-start));
background: linear-gradient(to bottom, var(--color-gray-50), transparent);
}
&::after {
--scroll-area-overflow-y-end: inherit;
bottom: 0;
height: min(40px, var(--scroll-area-overflow-y-end, 40px));
background: linear-gradient(to top, var(--color-gray-50), transparent);
}
}For SSR, a fallback can be used as part of the var() function to provide a default height.
.Viewport::after {
height: min(40px, var(--scroll-area-overflow-y-end, 40px));
}API reference
Root
Groups all parts of the scroll area.
Renders a <div> element.
overflowEdgeThresholdUnion0
- Description
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.
- Type
| number | Partial<{ xStart: number; xEnd: number; yStart: number; yEnd: number; }> | undefined- Default
0
classNamestring | function—
- Name
- Description
CSS class applied to the element, or a function that returns a class based on the component’s state.
- Type
| string | ((state: ScrollArea.Root.State) => string | undefined) | undefined
styleReact.CSSProperties | function—
- Name
- Type
| React.CSSProperties | (( state: ScrollArea.Root.State, ) => React.CSSProperties | undefined) | undefined
renderReactElement | function—
- Name
- Description
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.
Accepts a
ReactElementor a function that returns the element to render.- Type
| ReactElement | (( props: HTMLProps, state: ScrollArea.Root.State, ) => ReactElement) | undefined
data-has-overflow-x
Present when the scroll area content is wider than the viewport.
data-has-overflow-y
Present when the scroll area content is taller than the viewport.
data-overflow-x-end
Present when there is overflow on the horizontal end side.
data-overflow-x-start
Present when there is overflow on the horizontal start side.
data-overflow-y-end
Present when there is overflow on the vertical end side.
data-overflow-y-start
Present when there is overflow on the vertical start side.
data-scrolling
Present when the user scrolls inside the scroll area.
| Attribute | Description | |
|---|---|---|
data-has-overflow-x | Present when the scroll area content is wider than the viewport. | |
data-has-overflow-y | Present when the scroll area content is taller than the viewport. | |
data-overflow-x-end | Present when there is overflow on the horizontal end side. | |
data-overflow-x-start | Present when there is overflow on the horizontal start side. | |
data-overflow-y-end | Present when there is overflow on the vertical end side. | |
data-overflow-y-start | Present when there is overflow on the vertical start side. | |
data-scrolling | Present when the user scrolls inside the scroll area. | |
--scroll-area-corner-height
The scroll area’s corner height.
--scroll-area-corner-width
The scroll area’s corner width.
| CSS Variable | Description | |
|---|---|---|
--scroll-area-corner-height | The scroll area’s corner height. | |
--scroll-area-corner-width | The scroll area’s corner width. | |
ScrollArea.Root.StateHide
type ScrollAreaRootState = {
/** Whether the scroll area is being scrolled. */
scrolling: boolean;
/** Whether horizontal overflow is present. */
hasOverflowX: boolean;
/** Whether vertical overflow is present. */
hasOverflowY: boolean;
/** Whether there is overflow on the inline start side for the horizontal axis. */
overflowXStart: boolean;
/** Whether there is overflow on the inline end side for the horizontal axis. */
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;
}Viewport
The actual scrollable container of the scroll area.
Renders a <div> element.
classNamestring | function—
- Name
- Description
CSS class applied to the element, or a function that returns a class based on the component’s state.
- Type
| string | (( state: ScrollArea.Viewport.State, ) => string | undefined) | undefined
styleReact.CSSProperties | function—
- Name
- Type
| React.CSSProperties | (( state: ScrollArea.Viewport.State, ) => React.CSSProperties | undefined) | undefined
renderReactElement | function—
- Name
- Description
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.
Accepts a
ReactElementor a function that returns the element to render.- Type
| ReactElement | (( props: HTMLProps, state: ScrollArea.Viewport.State, ) => ReactElement) | undefined
data-has-overflow-x
Present when the scroll area content is wider than the viewport.
data-has-overflow-y
Present when the scroll area content is taller than the viewport.
data-overflow-x-end
Present when there is overflow on the horizontal end side.
data-overflow-x-start
Present when there is overflow on the horizontal start side.
data-overflow-y-end
Present when there is overflow on the vertical end side.
data-overflow-y-start
Present when there is overflow on the vertical start side.
data-scrolling
Present when the user scrolls inside the scroll area.
| Attribute | Description | |
|---|---|---|
data-has-overflow-x | Present when the scroll area content is wider than the viewport. | |
data-has-overflow-y | Present when the scroll area content is taller than the viewport. | |
data-overflow-x-end | Present when there is overflow on the horizontal end side. | |
data-overflow-x-start | Present when there is overflow on the horizontal start side. | |
data-overflow-y-end | Present when there is overflow on the vertical end side. | |
data-overflow-y-start | Present when there is overflow on the vertical start side. | |
data-scrolling | Present when the user scrolls inside the scroll area. | |
--scroll-area-overflow-x-end
The distance from the horizontal end edge in pixels.
--scroll-area-overflow-x-start
The distance from the horizontal start edge in pixels.
--scroll-area-overflow-y-end
The distance from the vertical end edge in pixels.
--scroll-area-overflow-y-start
The distance from the vertical start edge in pixels.
| CSS Variable | Description | |
|---|---|---|
--scroll-area-overflow-x-end | The distance from the horizontal end edge in pixels. | |
--scroll-area-overflow-x-start | The distance from the horizontal start edge in pixels. | |
--scroll-area-overflow-y-end | The distance from the vertical end edge in pixels. | |
--scroll-area-overflow-y-start | The distance from the vertical start edge in pixels. | |
ScrollArea.Viewport.StateHide
type ScrollAreaViewportState = {
/** Whether the scroll area is being scrolled. */
scrolling: boolean;
/** Whether horizontal overflow is present. */
hasOverflowX: boolean;
/** Whether vertical overflow is present. */
hasOverflowY: boolean;
/** Whether there is overflow on the inline start side for the horizontal axis. */
overflowXStart: boolean;
/** Whether there is overflow on the inline end side for the horizontal axis. */
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;
}Content
A container for the content of the scroll area.
Renders a <div> element.
classNamestring | function—
- Name
- Description
CSS class applied to the element, or a function that returns a class based on the component’s state.
- Type
| string | (( state: ScrollArea.Content.State, ) => string | undefined) | undefined
styleReact.CSSProperties | function—
- Name
- Type
| React.CSSProperties | (( state: ScrollArea.Content.State, ) => React.CSSProperties | undefined) | undefined
renderReactElement | function—
- Name
- Description
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.
Accepts a
ReactElementor a function that returns the element to render.- Type
| ReactElement | (( props: HTMLProps, state: ScrollArea.Content.State, ) => ReactElement) | undefined
ScrollArea.Content.StateHide
type ScrollAreaContentState = {
/** Whether the scroll area is being scrolled. */
scrolling: boolean;
/** Whether horizontal overflow is present. */
hasOverflowX: boolean;
/** Whether vertical overflow is present. */
hasOverflowY: boolean;
/** Whether there is overflow on the inline start side for the horizontal axis. */
overflowXStart: boolean;
/** Whether there is overflow on the inline end side for the horizontal axis. */
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;
}Scrollbar
A vertical or horizontal scrollbar for the scroll area.
Renders a <div> element.
orientation'vertical' | 'horizontal''vertical'
- Name
- Description
Whether the scrollbar controls vertical or horizontal scroll.
- Type
'vertical' | 'horizontal' | undefined- Default
'vertical'
classNamestring | function—
- Name
- Description
CSS class applied to the element, or a function that returns a class based on the component’s state.
- Type
| string | (( state: ScrollArea.Scrollbar.State, ) => string | undefined) | undefined
styleReact.CSSProperties | function—
- Name
- Type
| React.CSSProperties | (( state: ScrollArea.Scrollbar.State, ) => React.CSSProperties | undefined) | undefined
keepMountedbooleanfalse
- Name
- Description
Whether to keep the HTML element in the DOM when the viewport isn’t scrollable.
- Type
boolean | undefined- Default
false
renderReactElement | function—
- Name
- Description
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.
Accepts a
ReactElementor a function that returns the element to render.- Type
| ReactElement | (( props: HTMLProps, state: ScrollArea.Scrollbar.State, ) => ReactElement) | undefined
data-orientation
Indicates the orientation of the scrollbar.
data-has-overflow-x
Present when the scroll area content is wider than the viewport.
data-has-overflow-y
Present when the scroll area content is taller than the viewport.
data-hovering
Present when the pointer is over the scroll area.
data-overflow-x-end
Present when there is overflow on the horizontal end side.
data-overflow-x-start
Present when there is overflow on the horizontal start side.
data-overflow-y-end
Present when there is overflow on the vertical end side.
data-overflow-y-start
Present when there is overflow on the vertical start side.
data-scrolling
Present when the user scrolls inside the scroll area.
| Attribute | Description | |
|---|---|---|
data-orientation | Indicates the orientation of the scrollbar. | |
data-has-overflow-x | Present when the scroll area content is wider than the viewport. | |
data-has-overflow-y | Present when the scroll area content is taller than the viewport. | |
data-hovering | Present when the pointer is over the scroll area. | |
data-overflow-x-end | Present when there is overflow on the horizontal end side. | |
data-overflow-x-start | Present when there is overflow on the horizontal start side. | |
data-overflow-y-end | Present when there is overflow on the vertical end side. | |
data-overflow-y-start | Present when there is overflow on the vertical start side. | |
data-scrolling | Present when the user scrolls inside the scroll area. | |
--scroll-area-thumb-height
The scroll area thumb’s height.
--scroll-area-thumb-width
The scroll area thumb’s width.
| CSS Variable | Description | |
|---|---|---|
--scroll-area-thumb-height | The scroll area thumb’s height. | |
--scroll-area-thumb-width | The scroll area thumb’s width. | |
ScrollArea.Scrollbar.StateHide
type ScrollAreaScrollbarState = {
/** Whether the scroll area is being hovered. */
hovering: boolean;
/** Whether the scroll area is being scrolled. */
scrolling: boolean;
/** The orientation of the scrollbar. */
orientation: 'vertical' | 'horizontal';
/** Whether horizontal overflow is present. */
hasOverflowX: boolean;
/** Whether vertical overflow is present. */
hasOverflowY: boolean;
/** Whether there is overflow on the inline start side for the horizontal axis. */
overflowXStart: boolean;
/** Whether there is overflow on the inline end side for the horizontal axis. */
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;
}Thumb
The draggable part of the scrollbar that indicates the current scroll position.
Renders a <div> element.
classNamestring | function—
- Name
- Description
CSS class applied to the element, or a function that returns a class based on the component’s state.
- Type
| string | ((state: ScrollArea.Thumb.State) => string | undefined) | undefined
styleReact.CSSProperties | function—
- Name
- Type
| React.CSSProperties | (( state: ScrollArea.Thumb.State, ) => React.CSSProperties | undefined) | undefined
renderReactElement | function—
- Name
- Description
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.
Accepts a
ReactElementor a function that returns the element to render.- Type
| ReactElement | (( props: HTMLProps, state: ScrollArea.Thumb.State, ) => ReactElement) | undefined
data-orientation
Indicates the orientation of the scrollbar.
| Attribute | Description | |
|---|---|---|
data-orientation | Indicates the orientation of the scrollbar. | |
ScrollArea.Thumb.StateHide
type ScrollAreaThumbState = {
/** The component orientation. */
orientation?: 'horizontal' | 'vertical';
}Corner
A small rectangular area that appears at the intersection of horizontal and vertical scrollbars.
Renders a <div> element.
classNamestring | function—
- Name
- Description
CSS class applied to the element, or a function that returns a class based on the component’s state.
- Type
| string | ((state: ScrollArea.Corner.State) => string | undefined) | undefined
styleReact.CSSProperties | function—
- Name
- Type
| React.CSSProperties | (( state: ScrollArea.Corner.State, ) => React.CSSProperties | undefined) | undefined
renderReactElement | function—
- Name
- Description
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.
Accepts a
ReactElementor a function that returns the element to render.- Type
| ReactElement | (( props: HTMLProps, state: ScrollArea.Corner.State, ) => ReactElement) | undefined
ScrollArea.Corner.StateHide
type ScrollAreaCornerState = {}