React Sticky Box
Edit page
React Sticky BoxSee it in ActionWhat the Code looks likeHow to installHow it worksWhat kind of scroll containers can be usedTroubleshootingIs this production-ready?Api
Examples
Changelog

React Sticky Box

See it in Action

Sidebar

The sidebar to the left stays in a sticky position.

Go ahead and hit the expand button to see how it behaves once the sidebar becomes greater than the viewport.

What the Code looks like

import React from "react";
import StickyBox from "react-sticky-box";
const Page = () => (
<div className="row">
<StickyBox offsetTop={20} offsetBottom={20}>
<div>Sidebar</div>
</StickyBox>
<div>Content</div>
</div>
);

You may also import an es2017 build via

import StickyBox from "react-sticky-box/dist/esnext";

How to install

yarn add react-sticky-box
npm install react-sticky-box

How it works

React Sticky Box relies on position: sticky. It's widely supported these days.

For all browsers without sticky support, it falls back to a position: relative behaviour. This could be considered "good enough" in a lot of cases. Alternatively you have to provide a custom solution to get sticky behaviour here. Either via polyfills or even targeting IE10+ Browsers via @media queries like presented here by Olivr3.

position: sticky isn't without it's issues though. If the content is bigger than the viewport, it simply gets cut off and becomes inaccessible. This library solves this issue by allowing the content to scroll along with all the other content until the the corresponding end is visible and continues to be sticky.

You still might encounter browser bugs with position: sticky if your content lies within certain combinations of z-index, overflow and especially transform.

What kind of scroll containers can be used

Window

<body>
<div style={{display: "flex", alignItems: "flex-start"}}>
<StickyBox>Sidebar</StickyBox>
<div>Main Content</div>
</div>
</body>

Scroll Container as offset parent

<div style={{height: 200, position: "relative", overflow: "auto"}}>
<div style={{position: "absolute", top: 0, left: 0, minHeight: "100%"}}>
<StickyBox>Sidebar</StickyBox>
<div>Main Content</div>
</div>
</div>

Scroll Container as non-offset parent

<div style={{height: 200, overflow: "auto"}}>
<div style={{display: "flex", alignItems: "flex-start"}}>
<StickyBox>Sidebar</StickyBox>
<div>Main Content</div>
</div>
</div>

Troubleshooting

The StickyBox is not sticky!

Make sure that the <StickyBox> is only as high as its content, and not as high as the parent node. To quickly check this you can do:

<StickyBox style={{border: "3px solid green"}}>content</StickyBox>

Good

Sidebar
Main Content

Bad

This time without alignItems: "flex-start"

Sidebar
Main Content

Is this production-ready?

This library is heavily used within Codecks, so expect it to be fairly stable.