Custom Scrollbars for React
react-scrollbars-custom is a React component that provides highly customizable scrollbars while preserving native browser scrolling behavior. Unlike many alternatives, it does not emulate scrolling but rather styles the native scrollbars, ensuring optimal performance (60 FPS using requestAnimationFrame) and a consistent experience across different browsers and platforms. Key features include cross-browser compatibility, full customizability for look and feel, scrollbar nesting, momentum scrolling for iOS, RTL support, and proper handling of page zoom. The current stable version is 4.1.1, released in August 2022, indicating a maintenance phase following active development. It differentiates itself by its performance-focused approach and extensive customization options, including allowing users to define their own renderer components.
Common errors
-
Scrollbar not appearing or not scrolling despite having content.
cause The `Scrollbar` component does not have explicit `width` and `height` dimensions, or its content is not overflowing its boundaries.fixEnsure the `<Scrollbar>` component has defined `width` and `height` styles (e.g., `style={{ width: 300, height: 200 }}`) or via CSS. Also, verify that the content inside the `Scrollbar` is larger than these dimensions to trigger scrolling. -
TypeError: Super expression must either be null or a function, not undefined.
cause This error typically indicates an issue with `React` peer dependency resolution or an incompatible `React` version, especially with older module bundlers or `react-scrollbars-custom` versions prior to `v4.1.0`.fixEnsure `react` is installed as a dependency and meets the `>=16.0.0` peer dependency requirement. Check your bundler configuration to ensure `react` is resolved correctly. For `react-scrollbars-custom v4.1.0` and above, the `prop-types` dependency was removed, which could also affect older setups. -
Syntax error or `global` is not defined in a browser environment.
cause Using an older version of `react-scrollbars-custom` that did not correctly handle browser environment detection, leading to issues with server-side rendering (SSR) or specific browser builds.fixUpgrade to `react-scrollbars-custom@4.1.1` or higher, which includes a fix to replace `global` with proper browser environment detection. -
Custom styles not applying or default styles persisting despite `noDefaultStyles`.
cause Either the custom styles are not specific enough to override the component's internal styles, or the `noDefaultStyles` prop is incorrectly applied or missing for the desired elements.fixVerify that `noDefaultStyles` is passed to the `<Scrollbar>` component. If providing custom renderers (e.g., for `renderThumbVertical`), ensure that essential styles are explicitly passed to your custom renderer components as described in the documentation, as some styles are crucial for functional correctness. Use higher CSS specificity for your custom styles if needed.
Warnings
- breaking In `v4.1.0`, the `prop-types` dependency was removed. If your project explicitly relied on `prop-types` for `react-scrollbars-custom`, you might need to adjust your dependency configuration or type checking setup. This version also updated the peer dependency for React to `>=16.0.0`.
- gotcha The `<Scrollbar />` component requires explicit `width` and `height` properties (either inline via `style` or through CSS classes) to function correctly and display scrollbars. Without defined dimensions, the component may not render scrollbars or behave as expected.
- gotcha For compatibility with Internet Explorer 10 and older browsers, polyfills (e.g., `@babel/polyfill`) are required. While the library is syntax-compatible with IE10+, it relies on modern browser APIs not natively available in these older environments.
- gotcha The library ships with `main` (CJS ES3), `module` (ESM ES3), and `esnext` (ESM ES6+) fields in `package.json`. Depending on your bundler configuration (e.g., Webpack, Babel), you might need specific settings to correctly resolve and transpile the desired version, especially if you intend to leverage the untranspiled `esnext` version.
- gotcha Applying custom styles or disabling default styles using `noDefaultStyles` prop is possible, but some critical inline styles necessary for the component's proper functionality will always remain.
Install
-
npm install react-scrollbars-custom -
yarn add react-scrollbars-custom -
pnpm add react-scrollbars-custom
Imports
- Scrollbar
const Scrollbar = require('react-scrollbars-custom');import { Scrollbar } from 'react-scrollbars-custom'; - ScrollbarProps
import { ScrollbarProps } from 'react-scrollbars-custom';import type { ScrollbarProps } from 'react-scrollbars-custom'; - CustomScrollbar
import { Scrollbar as CustomScrollbar } from 'react-scrollbars-custom';
Quickstart
import React from 'react';
import { Scrollbar } from 'react-scrollbars-custom';
function App() {
return (
<div style={{ width: '100%', height: 'calc(100vh - 20px)', padding: '10px' }}>
<h1>My Scrollable Content</h1>
<p>This component demonstrates a custom scrollbar that maintains native scrolling behavior but allows for extensive styling. It's often used when default browser scrollbars don't match the application's aesthetic.</p>
<Scrollbar style={{ width: '100%', height: 300, border: '1px solid #ccc', padding: '10px' }} noDefaultStyles>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
{Array.from({ length: 50 }).map((_, i) => (
<p key={i}>This is some scrollable content, line {i + 1}. Adding more lines to ensure the scrollbar appears and is functional.</p>
))}
<p>End of scrollable content. You can scroll this section independently.</p>
</Scrollbar>
<h2>Another section below the scrollable area.</h2>
<p>This content is outside the custom scrollbar component.</p>
</div>
);
}
export default App;