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
- Live Demo - See Peek in action
- Documentation - Full documentation
- GitHub Repository - Source code
- 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
Download peek.js and include it in your project.
<script src="path/to/peek.js"></script><header class="header-main">
Your header content
</header>.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);
}// 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'
}
});| 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 |
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
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)
Remove event listeners and clean up all classes.
const peek = Peek('.header-main');
// Later, when you want to remove Peek
peek.destroy();// Using default settings
const peek = Peek('.header-main');// More sensitive to scroll changes
const peek = Peek('.header-main', {
offset: 150,
tolerance: 10
});// Use your own class naming convention
const peek = Peek('.site-header', {
classes: {
pinned: 'header-visible',
unpinned: 'header-hidden',
top: 'at-top',
notTop: 'scrolled'
}
});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);// Apply to multiple headers with different settings
const mainPeek = Peek('.header-main', { offset: 100 });
const subPeek = Peek('.header-sub', { offset: 200, tolerance: 10 });Peek works in all modern browsers that support:
requestAnimationFrameclassListAPI- Passive event listeners
Supported browsers:
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- Opera (latest)
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)
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
This project is licensed under the MIT License - see the LICENSE file for details.
Inspired by the Headroom.js library, Peek provides a lightweight alternative with modern JavaScript practices.
If you have any questions or run into issues, please open an issue on GitHub.
Made with ❤️ by A Design Link, LLC