react-sticky-kit
v0.2.1
Published
A lightweight, flexible React sticky container and item component library supporting multiple sticky modes, advanced layouts, and edge cases.
Maintainers
Readme
React Sticky Kit
A lightweight, flexible React sticky container and item component library. Easily create sticky headers, sections, and advanced sticky layouts with support for multiple modes and edge cases.
Features
- 📦 Simple API:
<StickyContainer>and<StickyItem> - 🧩 Supports
replace,stack, andnonesticky modes - 🏷️ Customizable offset, z-index (baseZIndex), and sticky logic
- 🖥️ Flexible reference containers (window, DOM elements, refs)
- 🔄 Supports SSR/SSG (Next.js, Gatsby, Astro, etc.)
- 🧪 Handles edge cases: empty sections, dynamic heights, zero-height headers, long headers, etc.
- ⚡️ Written in TypeScript, fully typed
- 🧪 Includes demo pages for real-world scenarios
Installation
npm install react-sticky-kit
# or
yarn add react-sticky-kit
# or
pnpm add react-sticky-kitDemo
Usage
import { StickyContainer, StickyItem } from 'react-sticky-kit';
// !! Import styles for sticky components
import 'react-sticky-kit/dist/style.css';
// or `import 'react-sticky-kit/style';` for more clean style path(require modern bundler tools)
export default function Example() {
return (
<StickyContainer offsetTop={48} defaultMode="stack" baseZIndex={300}>
<StickyItem>
<div>Sticky Header</div>
</StickyItem>
<div>Content...</div>
<StickyItem mode="replace">
<div>Another Sticky Header (replace mode)</div>
</StickyItem>
<div>More Content...</div>
</StickyContainer>
);
}Props
<StickyContainer />
| Prop | Type | Default | Description |
|-----------------------------|------------------------------------------------------|-------------|---------------------------------------------------------------------------------------------|
| offsetTop | number | 0 | Offset from the top of the viewport |
| defaultMode | 'replace' \| 'stack' \| 'none' | 'replace' | Default sticky mode for all items |
| baseZIndex | number | 200 | Base z-index for sticky items. Should be greater than the number of sticky items. |
| | | | In replace mode, z-index = baseZIndex - index; in stack mode, z-index = baseZIndex + index. |
| onStickyItemsHeightChange | (height: number) => void | | Callback when total sticky height changes |
| constraint | 'none' | | Define the constraint for sticky behavior. 'none' = no constraints (CSS-like behavior) |
<StickyItem />
| Prop | Type | Default | Description |
|---------|--------------------------------------|---------|---------------------------------------------|
| mode | 'replace' \| 'stack' \| 'none' | | Sticky mode for this item (overrides StickyContainer) |
Sticky Modes
- replace: Only one sticky item is visible at a time, replacing the previous.
- stack: Sticky items stack on top of each other.
- none: Sticky is disabled for this item.
Constraint Behavior
The constraint prop allows you to control when sticky items should stop being sticky:
import React from 'react';
import { StickyContainer, StickyItem } from 'react-sticky-kit';
function Example() {
return (
<div>
{/* 1. Default: Container-based constraint */}
<StickyContainer>
<StickyItem><div>Sticky stops when container leaves viewport</div></StickyItem>
<div>Content...</div>
</StickyContainer>
{/* 2. No constraints (like CSS position:sticky) */}
<StickyContainer constraint="none">
<StickyItem><div>Always sticky like CSS position:sticky</div></StickyItem>
<div>Content...</div>
</StickyContainer>
</div>
);
}
<div>Content...</div>
</StickyContainer>
</div>
);
}Special behavior of constraint="none"
When you set constraint="none", the sticky items will always stick when they reach the top of the viewport, regardless of their parent container's visibility. This exactly matches the behavior of native CSS position: sticky.
In contrast, the default behavior (without specifying a constraint) only makes items sticky when their parent container is visible in the viewport.
Demo
Run the demo locally:
pnpm install
pnpm devOpen http://localhost:5173 and switch between demo pages to explore all features and edge cases:
- iOS Contact a dead simple iOS contact clone
- Mixed mode mix replace/stack/none mode
- Nested nest sticky containers
- Dynamic sticky items dynamic sticky items(add/remove)
- Dynamic offsetTop dynamic offsetTop that adapts to header height changes
- Constraint Demo demo showing different constraint options
SSR/SSG Support
React Sticky Kit supports Server-Side Rendering (SSR) and Static Site Generation (SSG), working seamlessly with frameworks like Next.js, Gatsby, Astro, and more.
Next.js Example
// pages/index.tsx
import { StickyContainer, StickyItem } from 'react-sticky-kit'
import 'react-sticky-kit/dist/style.css'
export default function Home() {
return (
<StickyContainer>
<StickyItem>
<header>Sticky Header</header>
</StickyItem>
<main>Content...</main>
</StickyContainer>
)
}Astro Example
---
// src/pages/index.astro
import { StickyContainer, StickyItem } from 'react-sticky-kit'
import 'react-sticky-kit/dist/style.css'
---
<html>
<head>...</head>
<body>
<StickyContainer client:load>
<StickyItem>
<header>Sticky Header</header>
</StickyItem>
<div>Content...</div>
</StickyContainer>
</body>
</html>Publish steps
pnpm pub
License
MIT
