An open API service indexing awesome lists of open source software.

https://github.com/oe/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.
https://github.com/oe/react-sticky-kit

react react-sticky sticky sticky-header

Last synced: 3 months ago
JSON representation

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.

Awesome Lists containing this project

README

          

# React Sticky Kit



NPM Version


NPM Downloads


GitHub Stars


Build Status


License


TypeScript


SSR/SSG Compatible

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: `` and ``
- 🧩 Supports `replace`, `stack`, and `none` sticky 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

```bash
npm install react-sticky-kit
# or
yarn add react-sticky-kit
# or
pnpm add react-sticky-kit
```

## Demo
- [Apple iOS Contact App](https://codesandbox.io/p/sandbox/dreamy-hofstadter-v9dzfz)

## Usage

```tsx
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 (


Sticky Header


Content...


Another Sticky Header (replace mode)


More Content...


);
}
```

## Props

### ``
| 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) |

### ``
| 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:

```tsx
import React from 'react';
import { StickyContainer, StickyItem } from 'react-sticky-kit';

function Example() {
return (


{/* 1. Default: Container-based constraint */}

Sticky stops when container leaves viewport

Content...



{/* 2. No constraints (like CSS position:sticky) */}

Always sticky like CSS position:sticky

Content...



);
}
Content...



);
}
```

### 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:

```bash
pnpm install
pnpm dev
```

Open [http://localhost:5173](http://localhost:5173) and switch between demo pages to explore all features and edge cases:
* [iOS Contact](http://localhost:5173/#ios-contact) a dead simple iOS contact clone
* [Mixed mode](http://localhost:5173/#mixed-mode) mix replace/stack/none mode
* [Nested](http://localhost:5173/#nested) nest sticky containers
* [Dynamic sticky items](http://localhost:5173/#dynamic) dynamic sticky items(add/remove)
* [Dynamic offsetTop](http://localhost:5173/#dynamic-offset) dynamic offsetTop that adapts to header height changes
* [Constraint Demo](http://localhost:5173/#constraint) 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

```tsx
// pages/index.tsx
import { StickyContainer, StickyItem } from 'react-sticky-kit'
import 'react-sticky-kit/dist/style.css'

export default function Home() {
return (


Sticky Header

Content...

)
}
```

### Astro Example

```astro
---
// src/pages/index.astro
import { StickyContainer, StickyItem } from 'react-sticky-kit'
import 'react-sticky-kit/dist/style.css'
---

...



Sticky Header

Content...


```

## Publish steps

`pnpm pub`

## License

MIT