A lightweight JavaScript library for creating smart header behavior based on scroll intent. Peek automatically hides your site header when users scroll down and reveals it when they scroll up, creating a more immersive browsing experience.
Author: Chad Pierce
Version: 1.0.0
License: MIT
Copyright: A Design Link, LLC
🔗 Links
- Live Demo - See Peek in action
- Documentation - Full documentation
- GitHub Repository - Source code
Features
- Lightweight - Minimal footprint with no dependencies
- Smart scroll detection - Distinguishes between intentional scrolling and small movements
- Smooth animations - Uses requestAnimationFrame for optimal performance
- Easy integration - Works with any website or framework
- Customizable - Configure thresholds, delays, and CSS classes
- Passive event listeners - Improved scroll performance
Installation
Manual
Download peek.js and include it in your project.
<script src="path/to/peek.js"></script>
Quick Start
HTML
<header class="header-main"> Your header content </header>
CSS
.header-main { position: fixed; top: 0; left: 0; right: 0; transition: transform 0.3s ease; will-change: transform; } .main-header--unpinned { transform: translateY(-100%); } .main-header--pinned { transform: translateY(0); } .main-header--top { /* Styles when at top of page */ } .main-header--not-top { /* Styles when scrolled past offset */ box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
JavaScript
// Initialize with default options const peek = Peek('.header-main'); // Or customize the behavior const peek = Peek('.header-main', { offset: 150, tolerance: 10, classes: { pinned: 'main-header--pinned', unpinned: 'main-header--unpinned', top: 'main-header--top', notTop: 'main-header--not-top' } });
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
offset |
Number | 100 |
Scroll offset in pixels before triggering state changes |
tolerance |
Number | 5 |
Pixels scrolled before pin/unpin state change |
classes.pinned |
String | 'main-header--pinned' |
Class applied when header is visible/pinned |
classes.unpinned |
String | 'main-header--unpinned' |
Class applied when header is hidden/unpinned |
classes.top |
String | 'main-header--top' |
Class applied when at top of page (≤ offset) |
classes.notTop |
String | 'main-header--not-top' |
Class applied when scrolled past offset |
How It Works
Peek uses a smart scroll detection algorithm:
- Top Detection: When scroll position is at or below the
offset, the header stays pinned and gets thetopclass - Scroll Direction: Detects whether user is scrolling up or down
- Tolerance Check: Only triggers state changes after scrolling at least
tolerancepixels to avoid jitter - State Management: Applies appropriate classes based on scroll direction and position
State Classes
main-header--top: Applied whenscrollY ≤ offset(at top of page)main-header--not-top: Applied whenscrollY > offset(scrolled past threshold)main-header--pinned: Applied when header should be visible (scrolling up or at top)main-header--unpinned: Applied when header should be hidden (scrolling down)
API Methods
peek.destroy()
Remove event listeners and clean up all classes.
const peek = Peek('.header-main'); // Later, when you want to remove Peek peek.destroy();
Examples
Example 1: Basic Implementation
// Using default settings const peek = Peek('.header-main');
Example 2: Custom Offset and Tolerance
// More sensitive to scroll changes const peek = Peek('.header-main', { offset: 150, tolerance: 10 });
Example 3: Custom Classes
// Use your own class naming convention const peek = Peek('.site-header', { classes: { pinned: 'header-visible', unpinned: 'header-hidden', top: 'at-top', notTop: 'scrolled' } });
Example 4: Mobile-Only Implementation
let peek; function initPeekOnMobile() { if (window.innerWidth < 768 && !peek) { peek = Peek('.header-main'); } else if (window.innerWidth >= 768 && peek) { peek.destroy(); peek = null; } } // Initialize initPeekOnMobile(); // Handle window resize window.addEventListener('resize', initPeekOnMobile);
Example 5: Multiple Headers
// Apply to multiple headers with different settings const mainPeek = Peek('.header-main', { offset: 100 }); const subPeek = Peek('.header-sub', { offset: 200, tolerance: 10 });
Browser Support
Peek works in all modern browsers that support:
requestAnimationFrameclassListAPI- Passive event listeners
Supported browsers:
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- Opera (latest)
Performance
Peek is optimized for performance:
- Uses
requestAnimationFramefor smooth updates - Implements passive event listeners for better scroll performance
- Minimizes DOM operations with state tracking
- Only updates when necessary (tolerance check)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
Inspired by the Headroom.js library, Peek provides a lightweight alternative with modern JavaScript practices.
Support
If you have any questions or run into issues, please open an issue on GitHub.
Made with ❤️ by A Design Link, LLC