Edit Page

#Scroll

Create scrollable areas for desktop or mobile, with mouse and touch-based input support.

The Scroll Component is based on a Frame, which means that it supports all Frame properties. It allows you to create scrollable areas. Add Frames that exceed either the height or width of the component to create horizontally or vertically scrollable areas.

  • Create horizontally or vertically scrollable areas
  • Create nestable scrolling areas
  • Use touch wheels for desktop scrolling
  • Advanced control with momentum and overdrag

The Scroll Component is not just a div with overflow: scroll, but uses custom real physics (friction and spring) to mimic iOS-like scrolling. It works on all platforms and you have full control over the inputs and all events. This allows you to explore new and custom scroll based interactions.

import * as React from "react"
import { Frame, Scroll } from "framer"

export function MyComponent() {
  return (
    <Scroll height={200} width={200}>
      <Frame size={300}>Hello World!</Frame>
    </Scroll>
  )
}

#Sizing

Internally, the Scroll Component wraps all your children in a Frame and offsets the position based on your scrolling. For that to work, it needs to be able to calculate the total size of your scroll contents.

It attempts to do so automatically by measuring your added children in the DOM using a ResizeObserver. If that is unavailable, it will use a polyfill. If you use contentWidth and contentHeight it will opt out of this behaviour. You can use this if you need to performantly animate your scroll content size.


#Content

#dragEnabled: boolean

Enable or disable dragging to scroll. Defaults to true.

<Scroll dragEnabled={false} />

#wheelEnabled: boolean

Enable or disable wheel scroll. Defaults to true.

<Scroll wheelEnabled={false} />

#direction: "horizontal" | "vertical" | "both"

Controls the axis of drag-scrolling. Defaults to "vertical" for vertical scrolling.

Set "horizontal" or "vertical" to only drag in a specific direction. Set "both" to drag both directions.

// Horizontal
<Scroll direction="horizontal" />

// Vertical
<Scroll direction="vertical" />

// Locked
<Scroll direction="locked" />

// Both directions
<Scroll direction="both" />

#contentOffsetX: MotionValue<number> | number

Horizontal offset of the scrollable content. Set to 0 by default

<Scroll contentOffsetX={20} />

#contentOffsetY: MotionValue<number> | number

Vertical offset of the scrollable content. Set to 0 by default.

<Scroll contentOffsetY={20} />

#scrollAnimate: FrameProps["animate"]

Add a custom control for the scroll animation.

const controls = useAnimation()
controls.start({ y: -50 })
<Scroll scrollAnimate={controls} />

#Events

#onScroll(info): void

Called periodically during scrolling.

function onScroll(info) {
  console.log(info.offset, info.velocity)
}

<Scroll onScroll={onScroll} />
info: PanInfo

An PanInfo object containing x and y values for:

  • point: Relative to the device or page.
  • delta: Distance moved since the last event.
  • offset: Offset from the original pan event.
  • velocity: Current velocity of the pointer.

#onScrollStart(info): void

Called when scrolling starts.

function onScrollStart(info) {
  console.log(info.offset, info.velocity)
}

<Scroll onScrollStart={onScrollStart} />
info: PanInfo

An PanInfo object containing x and y values for:

  • point: Relative to the device or page.
  • delta: Distance moved since the last event.
  • offset: Offset from the original pan event.
  • velocity: Current velocity of the pointer.

#onScrollEnd(info): void

Called when scrolling ends.

function onScrollEnd(info) {
  console.log(info.offset, info.velocity)
}

<Scroll onScrollEnd={onScrollEnd} />
info: PanInfo

An PanInfo object containing x and y values for:

  • point: Relative to the device or page.
  • delta: Distance moved since the last event.
  • offset: Offset from the original pan event.
  • velocity: Current velocity of the pointer.