Getting started with react-headroom: build an auto-hiding, sticky navigation
React-Headroom is a compact React component that hides your header on scroll down and reveals it on scroll up, while keeping it effectively „sticky” at the top of the viewport. This article covers installation, setup, customization (animations, styles), scroll detection strategies, and practical tips to get a performant navigation that works across devices.
The guidance below prioritizes real-world usage: minimal code, accessibility considerations, and options for customizing behavior and appearance. You’ll also find concise examples and recommended links to the official package and repo for deeper reference.
If you want a quick jump: install via npm, wrap your header in Headroom, then tune props and CSS for animation and responsiveness. Read on for a step-by-step that includes scroll throttling, onPin/onUnpin handlers, and troubleshooting.
Why choose react-headroom for auto-hiding and sticky headers
react-headroom provides a small, battle-tested abstraction over the common pattern of hiding navigation while scrolling down and revealing it while scrolling up. The component handles delta detection, initial pin/unpin behavior, and adds optional classes so you can animate transitions in CSS. This saves time over writing bespoke scroll handlers.
Using react-headroom retains the native document flow: the header remains outside of content reflows when hidden (it’s transformed via translateY or position changes), which minimizes layout thrashing. That behavior helps maintain performance on mobile devices where frequent reflows can cause jank.
Finally, react-headroom exposes lifecycle callbacks (onPin, onUnpin, onUnfix) and props for tolerance and pinStart behavior. Those hooks make it practical to integrate analytics, update state for responsive UI, or synchronize other components (e.g., sidebars) with header visibility changes.
Installation and quick setup
Installation is trivial and fits any React stack. If you use npm or yarn, add the package and then import the Headroom component. Below are the canonical steps and a minimal example to get you rendering a hide-on-scroll header quickly.
- Install: npm i react-headroom or yarn add react-headroom
- Import: import Headroom from 'react-headroom’
- Wrap your header markup in <Headroom> … </Headroom>
Minimal example (JSX):
import React from 'react';
import Headroom from 'react-headroom';
function AppHeader() {
return (
<Headroom>
<header style={{background:'#fff', padding:'12px 20px', boxShadow:'0 1px 4px rgba(0,0,0,0.06)'}}>
<nav>My App Navigation</nav>
</header>
</Headroom>
);
}
This renders a header that pins at the top and hides during downward scrolls. The default styles are minimal—use CSS to replace transitions and add branding. More advanced props are covered below.
react-headroom installation (npm),
react-headroom example (GitHub),
getting started with react-headroom (tutorial).
Key props and behavior control
react-headroom exposes a concise set of props to tune behavior: tolerance, upTolerance, downTolerance, pinStart, disableInlineStyles, and callbacks like onPin/onUnpin. Understanding these controls lets you balance sensitivity and stability across touch and mouse events.
Use tolerance to avoid noisy toggles on micro-scrolls. For example, setting tolerance to 5 or 10 means the component will wait until the pointer moves that many pixels before reacting. upTolerance and downTolerance let you set asymmetric thresholds for pinning vs unpinning.
If you prefer to manage styles entirely through CSS, pass disableInlineStyles and add your own transitions via classes like .headroom–pinned and .headroom–unpinned. Callbacks are useful for toggling ARIA attributes or exposing header state to other parts of your app.
Customizing animations and styles
By default, react-headroom injects inline styles and class names you can target. For richer animations, disable the inline styles and define transitions in CSS using the classes .headroom, .headroom–unfixed, .headroom–unpinned, and .headroom–pinned.
Example CSS to animate vertical movement smoothly:
.headroom { transition: transform 0.25s ease-in-out; will-change: transform; }
.headroom--unpinned { transform: translateY(-100%); }
.headroom--pinned { transform: translateY(0); }
For subtle effects, combine opacity and shadow changes. If you need hardware acceleration, prefer transform properties (translateY) over top/height because transforms are GPU-accelerated and less likely to trigger layout calculations.
Scroll detection, throttling, and performance
On mobile, scroll events fire rapidly and can spike CPU usage if handlers run heavy logic on each event. react-headroom manages basic detection internally, but if you add custom onScroll handlers (for analytics or live UI updates), debounce or throttle them.
Use requestAnimationFrame for animation-bound state updates. Alternatively, use a small throttle implementation (e.g., lodash.throttle) to limit handler invocations to ~100–200ms. This approach yields a responsive UI without jank during fast scrolls.
Example with throttle:
import throttle from 'lodash.throttle';
function handleScrollThrottled(e) {
// do light-weight work, e.g., update last scroll position
}
const throttled = throttle(handleScrollThrottled, 150);
// attach / detach throttled in effects
Accessibility and responsive considerations
Hiding navigation on scroll can be disorienting if not announced to assistive technologies. Ensure that interactive controls inside the header remain reachable. If the header contains focusable elements, handle focus transitions—when the header hides, move focus logically to the next interactive element in the document flow.
Add ARIA attributes where appropriate. For example, toggle aria-hidden on header contents if you programmatically hide them. Use skip links (a visually-hidden „Skip to content” link) so keyboard users can bypass navigation when needed. Also test with screen readers to confirm the experience is predictable.
Responsive layout: on small screens, consider a larger tolerance so accidental scrolls don’t constantly hide the header while users interact. Another pattern is to disable the auto-hide behavior below a certain viewport width by conditionally rendering Headroom based on window.innerWidth.
Advanced tips, patterns, and common pitfalls
If you want a header that is both sticky and auto-hiding, keep Header positioned as fixed or allow Headroom to manage the pinned position. Be careful with stacking contexts: set a clear z-index to ensure the header overlays page content as expected.
To avoid layout shifts, do not change the header height dynamically during transitions. If you need to compress the header on pin, animate an inner element’s transform or scale rather than changing the header’s height. Also consider mixing a compact class for pinned state so the content below isn’t repainted unnecessarily.
Common pitfalls include having other scroll listeners that fight Headroom’s logic and using CSS that overrides transform behavior. If you see jitter, check for multiple scroll handlers, conflicting CSS (like translate hacks on ancestors), or slow paint due to shadows and expensive filters.
Troubleshooting and FAQs — quick fixes
Header not hiding: verify that Headroom receives pointer/scroll events (e.g., if you use a scrolling container, pass the container to Headroom or set up a custom scroll listener). react-headroom assumes document scrolling by default.
Animations jumping: ensure disableInlineStyles is set if you plan to supply fully custom CSS. Also check if your CSS specificity is strong enough to override inline fallback styles when needed.
Mobile flicker: this often happens when transitions run on height or top instead of transforms. Move to transform-based effects (translateY) and reduce shadow/painter-heavy styles during scroll.
Conclusion — pragmatic recipe
To implement a robust auto-hiding sticky header with react-headroom: install the package, wrap your header, disable inline styles if you want full control, and add transform-based CSS transitions. Tune tolerance and pinStart to match your UX needs, and throttle any extra scroll handlers to avoid performance regressions.
Test on real devices and emulate slow CPU conditions in dev tools. Add accessibility checks and skip links to ensure keyboard and screen reader users are not disadvantaged. With these adjustments, react-headroom provides a small, effective foundation for modern navigation patterns.
If you want sample projects and community examples, check the GitHub repo and the npm package for latest changes and usage notes. For a walkthrough-style tutorial, see this getting started with react-headroom article.
FAQ
How do I install react-headroom?
Install via npm or yarn: run npm install react-headroom or yarn add react-headroom. Then import and wrap your header: import Headroom from 'react-headroom' and use <Headroom>YourHeader</Headroom>. See the npm package page for version info.
How can I customize animations and disable inline styles?
Pass disableInlineStyles to Headroom and add your own CSS targeting the classes .headroom--unpinned and .headroom--pinned. Use transform: translateY() and transition for smooth, GPU-accelerated animations. Example CSS is included above in this article.
How do I detect scroll direction or respond when the header hides/shows?
Use the callbacks provided by react-headroom: onPin, onUnpin, and onUnfix. These hooks fire when the header pins, unpins, or becomes unfixed; attach handlers to update application state, analytics, or to synchronize other UI elements.
Primary: react-headroom, React auto-hiding header, React sticky navigation, React hide on scroll
Secondary: react-headroom installation, react-headroom tutorial, react-headroom setup, react-headroom example, react-headroom getting started
Clarifying / LSI: React scroll header, react-headroom customization, React scroll detection, react-headroom animations, React header library, React navigation header, auto-hide nav, hide header on scroll, sticky header React
Related intents: how to install react-headroom, headroom onPin onUnpin, disableInlineStyles headroom, headroom CSS animation, throttle scroll React