Skip to content

Scroll Area

A custom scrollable container with overlay scrollbars that can be styled to match your design.

Introduction

ScrollArea replaces the browser's native scrollbar with a custom one while preserving native scrolling behavior. It supports both vertical and horizontal scrolling, thumb dragging, track click-to-jump, and RTL layouts.

Anatomy

Import the components and assemble them:

vue
<script setup>
import {
  ScrollAreaContent,
  ScrollAreaCorner,
  ScrollAreaRoot,
  ScrollAreaScrollbar,
  ScrollAreaThumb,
  ScrollAreaViewport,
} from 'base-ui-vue'
</script>

<template>
  <ScrollAreaRoot>
    <ScrollAreaViewport>
      <ScrollAreaContent>
        <!-- scrollable content -->
      </ScrollAreaContent>
    </ScrollAreaViewport>
    <ScrollAreaScrollbar>
      <ScrollAreaThumb />
    </ScrollAreaScrollbar>
    <ScrollAreaScrollbar orientation="horizontal">
      <ScrollAreaThumb />
    </ScrollAreaScrollbar>
    <ScrollAreaCorner />
  </ScrollAreaRoot>
</template>

Both axes

Use two ScrollAreaScrollbar components (one vertical, one horizontal) with a ScrollAreaCorner for content that overflows in both directions:

Scroll fade

Use the --scroll-area-overflow-y-start and --scroll-area-overflow-y-end CSS variables on the Viewport to create a fade-out effect at the edges:

Keep scrollbar mounted

By default, scrollbars are unmounted when there is no overflow. Use keep-mounted to keep them in the DOM:

vue
<ScrollAreaScrollbar keep-mounted>
  <ScrollAreaThumb />
</ScrollAreaScrollbar>

CSS variables

The component exposes CSS custom properties for advanced styling:

VariableApplied toDescription
--scroll-area-corner-widthRootWidth of the corner element in pixels.
--scroll-area-corner-heightRootHeight of the corner element in pixels.
--scroll-area-thumb-widthScrollbar (horizontal)Width of the thumb in pixels.
--scroll-area-thumb-heightScrollbar (vertical)Height of the thumb in pixels.
--scroll-area-overflow-x-startViewportDistance from the horizontal start edge in pixels.
--scroll-area-overflow-x-endViewportDistance from the horizontal end edge in pixels.
--scroll-area-overflow-y-startViewportDistance from the vertical start edge in pixels.
--scroll-area-overflow-y-endViewportDistance from the vertical end edge in pixels.

API reference

Root

Groups all parts of the scroll area. Renders a <div> element.

PropTypeDefaultDescription
asstring | Component'div'The element or component to render.
overflowEdgeThresholdnumber | { xStart, xEnd, yStart, yEnd }0Pixel threshold before overflow edge data attributes are applied.
classstring | ((state: State) => string)--CSS class applied to the element.
styleStyleValue | ((state: State) => StyleValue)--Style applied to the element.
Data attributeDescription
data-scrollingPresent when the user is scrolling.
data-has-overflow-xPresent when horizontal overflow exists.
data-has-overflow-yPresent when vertical overflow exists.
data-overflow-x-startPresent when there is overflow at the horizontal start.
data-overflow-x-endPresent when there is overflow at the horizontal end.
data-overflow-y-startPresent when there is overflow at the vertical start.
data-overflow-y-endPresent when there is overflow at the vertical end.

Viewport

The scrollable container. Renders a <div> element.

PropTypeDefaultDescription
asstring | Component'div'The element or component to render.

Content

An optional wrapper for the scrollable content. Renders a <div> element. Uses a ResizeObserver to recalculate the thumb position when content size changes.

PropTypeDefaultDescription
asstring | Component'div'The element or component to render.

Scrollbar

A vertical or horizontal scrollbar track. Renders a <div> element.

PropTypeDefaultDescription
asstring | Component'div'The element or component to render.
orientation'vertical' | 'horizontal''vertical'Which axis the scrollbar controls.
keepMountedbooleanfalseWhether to keep the scrollbar in the DOM when there is no overflow.
Data attributeDescription
data-orientation'vertical' | 'horizontal'The scrollbar orientation.
data-hoveringPresent when the pointer is over the scroll area.
data-scrollingPresent when the user is scrolling on this axis.
data-has-overflow-xPresent when horizontal overflow exists.
data-has-overflow-yPresent when vertical overflow exists.
data-overflow-x-startPresent when there is overflow at the horizontal start.
data-overflow-x-endPresent when there is overflow at the horizontal end.
data-overflow-y-startPresent when there is overflow at the vertical start.
data-overflow-y-endPresent when there is overflow at the vertical end.

Thumb

The draggable thumb inside a scrollbar. Renders a <div> element.

PropTypeDefaultDescription
asstring | Component'div'The element or component to render.
Data attributeDescription
data-orientation'vertical' | 'horizontal'The thumb orientation (inherited from parent scrollbar).

Corner

The area at the intersection of horizontal and vertical scrollbars. Renders a <div> element. Only visible when both scrollbars are present.

PropTypeDefaultDescription
asstring | Component'div'The element or component to render.