Build a Sticky Header with CSS and Vanilla JavaScript
- Neha Sehgal
- 38 minutes ago
- 3 min read

What is a Sticky Header?
A sticky header is a UI pattern where the header remains visible as users scroll. It's implemented using CSS (position: sticky) or JavaScript with scroll event listeners.
Why Use a Sticky Header?
Persistent Navigation: Menu options stay accessible without scrolling back up
Consistent Branding: Logo remains visible throughout the experience
Quick Access: Search, login, and cart buttons stay within reach
How to Create a Sticky Header
Approach 1: Pure CSS
CSS provides native support through the position property:
Approach 2: CSS + JavaScript
For dynamic styling changes (shrinking height, changing background), use JavaScript:
const header = document.getElementById('header');
window.addEventListener('scroll', () => {
if (window.scrollY > 50) {
header.classList.add('scrolled');
} else {
header.classList.remove('scrolled');
}
});Common Use Cases
E-Commerce: Keep cart, search, and logo accessible
News & Blogs: Keep category menus visible during long reads
Dashboards: Keep filters and tabs fixed for data-heavy pages
Documentation: Keep table of contents accessible
Portfolios: Ensure branding follows visitors throughout
Use Case: E-Commerce Store Header

Without a sticky header, users must scroll up to search, login, or view their cart. A sticky header keeps the logo, search bar, and cart button always visible.
HTML
<header id="store-header" role="banner" aria-label="Main navigation">
<div class="logo">ShopEase</div>
<input type="text" placeholder="Search products..." aria-label="Search products" />
<button class="cart" aria-label="Shopping cart with 0 items">🛒 Cart (0)</button>
</header>
<main>
<h2>Our Products</h2>
<p>... lots of product listings here ...</p>
</main>CSS
#store-header {
position: fixed;
top: 0;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
background: transparent;
padding: 15px 30px;
transition: background 0.3s, padding 0.3s;
z-index: 1000;
}
#store-header.scrolled {
background: #222;
padding: 10px 20px;
}JavaScript
const storeHeader = document.getElementById('store-header');
window.addEventListener('scroll', () => {
if (window.scrollY > 100) {
storeHeader.classList.add('scrolled');
} else {
storeHeader.classList.remove('scrolled');
}
});As users scroll beyond 100px, the header transitions to a darker background and reduces padding for a compact appearance while maintaining full functionality.
When to Use CSS vs JavaScript?
CSS sticky: Simple, static headers
JavaScript sticky: Scroll effects, shrinking headers, or dynamic styling
Accessibility Considerations
Critical: Sticky headers can cause keyboard navigation issues. Ensure proper ARIA attributes:
Add role="banner" to the header element
Include aria-label for navigation regions
Add descriptive aria-label attributes to interactive elements
Test keyboard focus order to ensure it doesn't get trapped behind the sticky header
Consider adding a "Skip to main content" link for keyboard users
Considerations Before Using Sticky Headers
While sticky headers offer many benefits, there are some scenarios where you might want to reconsider:
Content-Heavy Sites: Consider that they reduce available viewport space, especially on mobile devices
Short Pages: May not be necessary when users don't need to scroll much
Full-Screen Experiences: Could potentially distract from immersive content like videos or galleries
Cluttered Headers: Large or complex headers might overwhelm the layout
Conclusion
Sticky headers improve navigation and user experience when used appropriately. E-commerce sites particularly benefit by keeping essential shopping actions always available.
However, consider viewport constraints and accessibility requirements before implementation.
References
Accessibility Standards and Guidelines
WAI-ARIA Authoring Practices Guide - W3C Web Accessibility Initiative
ARIA - Accessible Rich Internet Applications - MDN Web Docs
ARIA: navigation role - MDN Web Docs
WebAIM: Keyboard Accessibility - WebAIM
WCAG 2.2 Technique C34: Using media queries to un-fix sticky headers/footers - W3C
CSS and JavaScript Documentation
position - CSS: Cascading Style Sheets - MDN Web Docs
Element: classList property - MDN Web Docs
Window: scroll event - MDN Web Docs
