Peek

v1.0.0 MIT License No Dependencies

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
Copyright: A Design Link, LLC

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 or peek.min.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:

  1. Top Detection: When scroll position is at or below the offset, the header stays pinned and gets the top class
  2. Scroll Direction: Detects whether user is scrolling up or down
  3. Tolerance Check: Only triggers state changes after scrolling at least tolerance pixels to avoid jitter
  4. State Management: Applies appropriate classes based on scroll direction and position

State Classes

  • main-header--top: Applied when scrollY ≤ offset (at top of page)
  • main-header--not-top: Applied when scrollY > 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:

  • requestAnimationFrame
  • classList API
  • Passive event listeners

Supported browsers:

  • Chrome/Edge (latest)
  • Firefox (latest)
  • Safari (latest)
  • Opera (latest)

Performance

Peek is optimized for performance:

  • Uses requestAnimationFrame for 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.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. 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