Skip to main content brightness_auto motion_photos_off palette download more_vert
toc

Pull to refresh

A pull to refresh container lets people pull its content down to reload it, with a loading indicator that shows progress.

HTMLJS
<md-gb-pull-to-refresh id="news" indicator-label="Refreshing news" style="block-size: 200px">
  <ul>
    <li>Markets rally on new data</li>
    <li>City opens a new bike lane</li>
    <li>Local team wins the final</li>
    <li>Weather turns cooler this week</li>
    <li>New library hours start Monday</li>
    <li>Festival lineup announced</li>
  </ul>
</md-gb-pull-to-refresh>

Install with shadcn/ui: npx shadcn@latest add https://material-web.dev/3.0/r/md-pull-to-refresh.json (setup)

Pull to refresh is the pull-to-refresh behavior of the loading indicator, which it shows while the content reloads.

  • Refresh content people expect to change. Use it on feeds and lists that update, such as news or messages.
  • Always offer another way. Pulling isn't available to everyone, so provide a refresh button that people can use with a single pointer or the keyboard.
  • Show it is working. The container keeps the indicator in view until you set refreshing back to false.

This component is new in M3 Expressive.

A pull to refresh container holds the scrolling content (default slot). An indicator appears above it while people pull and while it refreshes.

  • Water the plants
  • Pay the rent
  • Call the dentist
<md-gb-pull-to-refresh indicator-label="Refreshing tasks" style="block-size: 120px">
  <ul>
    <li>Water the plants</li>
    <li>Pay the rent</li>
    <li>Call the dentist</li>
  </ul>
</md-gb-pull-to-refresh>

Call refresh() from a button to start the same refresh without a gesture. It fires refresh and sets refreshing.

HTMLJS
<md-gb-icon-button id="reload" aria-label="Refresh">
  <md-gb-icon>refresh</md-gb-icon>
</md-gb-icon-button>
<md-gb-pull-to-refresh id="feed" indicator-label="Refreshing the feed" style="block-size: 160px">
  <ul>
    <li>New recipe: lemon pasta</li>
    <li>Ten tips for sourdough</li>
    <li>What to cook this weekend</li>
    <li>Pantry staples to stock</li>
  </ul>
</md-gb-pull-to-refresh>

Set indicator="circular" to use a circular arrow and progress indicator instead of the default contained loading indicator.

  • Ali: Brunch this weekend?
  • Sandra: Summer BBQ
  • Trevor: Oui oui
  • Britta: Recipe to try
<md-gb-pull-to-refresh indicator="circular" indicator-label="Refreshing messages" style="block-size: 160px">
  <ul>
    <li>Ali: Brunch this weekend?</li>
    <li>Sandra: Summer BBQ</li>
    <li>Trevor: Oui oui</li>
    <li>Britta: Recipe to try</li>
  </ul>
</md-gb-pull-to-refresh>

Set threshold to the distance in pixels people must pull before releasing starts a refresh (the default is 80). Add disabled to turn pulling off.

  • Order 1042: shipped
  • Order 1041: delivered
  • Order 1040: delivered
  • Order 1039: returned
<md-gb-pull-to-refresh threshold="120" indicator-label="Refreshing orders" style="block-size: 160px">
  <ul>
    <li>Order 1042: shipped</li>
    <li>Order 1041: delivered</li>
    <li>Order 1040: delivered</li>
    <li>Order 1039: returned</li>
  </ul>
</md-gb-pull-to-refresh>
  • Pulling needs a drag, so also provide a button or another control that calls refresh(), usable with a single pointer or the keyboard.
  • While refreshing, the indicator is a progressbar named by indicator-label (the default is "Refreshing"), and the label is announced politely. Write a label that says what is refreshing, such as "Refreshing news".
Material Design 3No spec page

Material Design has no page for this component; it follows the general guidance (color, shape, motion, states).

BaselineWidely availableChrome 124Edge 124Firefox 125Safari 17.4

The component’s own CSS and JavaScript rely only on web platform features that are Baseline widely available: it works in Chrome 124, Edge 124, Firefox 125, Safari 17.4 and later.

Newer features it uses where the browser has them (progressive enhancements):

WAI-ARIAaxe and ARIA 1.3 pass

Roles the component renders: progressbar (opens in a new tab).

1 rendered state run through axe-core and the WAI-ARIA 1.3 role and attribute rules in a real browser, with no known gaps.

Lighthouse99 · 100 · 100 · 100
  • Performance
  • Accessibility
  • Best practices
  • SEO

Audits under 90:

  • Eliminate render-blocking resources
  • Minify JavaScript
  • Enable text compression
  • Network dependency tree
  • Render blocking requests

Lighthouse 12.8.2 (desktop, 2026-11-08) on the component alone: its first example on a page of its own, without this site's shell. The modules are the development build (not bundled or minified), so the performance score is indicative.

A Material Design component.

Property Attribute Type Default
disabled
Whether pulling is turned off (Compose enabled = false).
disabled boolean false
indicator
The indicator: loading (M3 Expressive contained loading indicator) or circular (circular arrow and progress indicator).
indicator PullToRefreshIndicator 'loading'
indicatorLabel
Accessible label of the indicator, e.g. "Refreshing news".
indicator-label string DEFAULT_LABEL
refreshing
Whether content is refreshing. Set by a pull past the threshold (or refresh()); set it back to false once the content has refreshed.
refreshing boolean false
threshold
How far (px) the indicator must be pulled before releasing it refreshes (Compose PullToRefreshDefaults.PositionalThreshold, 80dp).
threshold number PULL_TO_REFRESH_THRESHOLD_PX
Slot Description
default The scrolling content.
Event Description
refresh
Event
Fired when a pull (or refresh()) starts a refresh. Cancel it to keep refreshing false.
Method Description
refresh
() => boolean
Starts a refresh without a gesture, e.g. from a refresh button: fires refresh and, unless it is cancelled, sets refreshing.
Part Description
::part(indicator) The indicator container.
::part(scroller) The element that scrolls the content.
Property Description
--indicator-color
--indicator-container-color
--indicator-container-height
--indicator-container-shape
--indicator-container-width
--indicator-elevation
--indicator-max-distance How far the indicator moves below the top edge at the threshold.
--motion-effects-duration
--motion-effects-easing
--motion-settle-duration
--motion-settle-easing
Install Material Web 3.0

Your browser did not offer to install the docs as an app. Install them from the browser instead:

Close
Send feedback
Bug Documentation Idea

Opens a new GitHub issue for material-components/material-web in a new tab, with this filled in.

Cancel Open issue