Debug Responsive Layouts With A Visual Tracker – breakpoint-overlay

Category: Javascript , Layout , Recommended | January 14, 2026
Authorolawalethefirst
Last UpdateJanuary 14, 2026
LicenseMIT
Tags
Views26 views
Debug Responsive Layouts With A Visual Tracker – breakpoint-overlay

breakpoint-overlay is a TypeScript library that displays a persistent on-screen badge showing your current viewport dimensions, active responsive breakpoint, and device pixel ratio.

It is ideal for developers who need to validate responsive behavior instantly on any device or screen size.

Features:

  • Real-Time Viewport Tracking: Monitors window resize events with configurable debouncing.
  • Flexible Breakpoint Strategies: Supports min-width, max-width, and range-based breakpoint matching.
  • Keyboard Shortcuts: Default Alt+Shift+O toggle with full modifier key support.
  • Expandable Details Panel: Click the badge to reveal all configured breakpoints with their active states and pixel ranges.
  • Framework Agnostic: Pure JavaScript implementation that works with React, Vue, Svelte, or vanilla HTML.
  • Shadow DOM Encapsulation: Renders inside Shadow DOM to prevent style conflicts with your application CSS.

See It In Action:

Use Cases:

  • Multi-Device Responsive Testing: Verify that breakpoint transitions occur at the correct viewport widths across desktop, tablet, and mobile ranges.
  • Design System Implementation: Confirm that component variants match their designated breakpoints.
  • Client Demonstrations: Show stakeholders how responsive behavior changes at specific viewport widths during presentations or video calls.
  • Debugging Layout Shifts: Track down unexpected responsive behavior by monitoring which breakpoint is active when content reflows.

How to Use It:

1. Install the package using your preferred package manager.

# npm
npm install --save-dev breakpoint-overlay
# pnpm
pnpm add -D breakpoint-overlay
# yarn
yarn add -D breakpoint-overlay

2. Import the library and call initOverlay with your breakpoint configuration. This creates the overlay runtime and registers keyboard shortcuts.

import { initOverlay } from 'breakpoint-overlay';
// Initialize with your responsive breakpoints
const overlay = initOverlay({
  breakpoints: [
    { id: 'mobile', label: 'Mobile', maxWidth: 767 },
    { id: 'tablet', label: 'Tablet', minWidth: 768, maxWidth: 1199 },
    { id: 'desktop', label: 'Desktop', minWidth: 1200 }
  ]
});
// Start the overlay to display the badge
overlay.start();

3. The badge appears in the top-right corner showing current viewport dimensions. Press Alt+Shift+O to toggle visibility. Click the badge to expand the breakpoint panel.

4. Define breakpoints using minWidth, maxWidth, or both for range-based matching. The library automatically infers matching strategy per breakpoint. Breakpoints with only minWidth use min-width matching. Breakpoints with only maxWidth use max-width matching. Breakpoints with both use range matching.

const overlay = initOverlay({
  breakpoints: [
    // Max-width only (matches 0 to 767px)
    { id: 'sm', label: 'Small', maxWidth: 767 },
    
    // Min-width only (matches 768px and above)
    { id: 'md', label: 'Medium', minWidth: 768 },
    
    // Range with both (matches 768px to 1199px)
    { id: 'tablet', minWidth: 768, maxWidth: 1199 },
    
    // Min-width for largest breakpoint
    { id: 'xl', label: 'Extra Large', minWidth: 1200 }
  ]
});

5. Force all breakpoints to use the same matching strategy with the matchStrategy option.

const overlay = initOverlay({
  matchStrategy: 'min-width',
  breakpoints: [
    { id: 'sm', minWidth: 0 },
    { id: 'md', minWidth: 768 },
    { id: 'lg', minWidth: 1024 }
  ]
});

6. All configuration options.

  • breakpoints (Array): Breakpoint definitions with id, optional label, and width constraints. Each breakpoint requires either minWidth, maxWidth, or both. The id must be unique. The label defaults to id if omitted.
  • matchStrategy (string): Forces a specific matching strategy across all breakpoints. Valid values are 'min-width', 'max-width', or 'range'. When omitted, each breakpoint infers its strategy from its width properties.
  • hotkey (string): Keyboard shortcut in modifier+...+key format. Supported modifiers are alt, ctrl, shift, and meta. The final token must be a single character. Examples: 'ctrl+shift+k', 'alt+o'. Set to empty string "" to disable keyboard shortcuts entirely. Default is 'alt+shift+o'.
  • debounceMs (number): Milliseconds to wait between viewport resize samples. Higher values reduce update frequency. Lower values increase responsiveness. Default is 150.
// Subscribe to state changes to trigger side effects or synchronize with application state.
const overlay = initOverlay({
  breakpoints: [
    { id: 'mobile', maxWidth: 767 },
    { id: 'desktop', minWidth: 768 }
  ]
});
// Listen for breakpoint changes
const unsubscribe = overlay.subscribe((state) => {
  if (state.breakpoint?.id === 'mobile') {
    console.log('Mobile breakpoint active');
    // Update application layout
  }
});
overlay.start();
// Clean up subscription before destroying overlay
unsubscribe();
overlay.destroy();
// Configure custom keyboard shortcuts that match your development workflow.
// Single modifier plus key
const overlay1 = initOverlay({
  hotkey: 'alt+b',
  breakpoints: []
});
// Multiple modifiers
const overlay2 = initOverlay({
  hotkey: 'ctrl+shift+d',
  breakpoints: []
});
// Meta key (Command on Mac, Windows key on PC)
const overlay3 = initOverlay({
  hotkey: 'meta+shift+o',
  breakpoints: []
});
// Disable keyboard shortcut
const overlay4 = initOverlay({
  hotkey: '',
  breakpoints: []
});

7. API methods.

// Activate the overlay and start viewport tracking
overlay.start();
// Deactivate the overlay and reset badge expansion
overlay.stop();
// Toggle between started and stopped states
overlay.toggle();
// Completely tear down the overlay and remove all listeners
overlay.destroy();
// Update configuration and recompute internal state
overlay.updateConfig({
  breakpoints: [{ id: 'new', minWidth: 800 }],
  hotkey: 'ctrl+b'
});
// Get current runtime state object
const state = overlay.getState();
console.log(state.active, state.viewport, state.breakpoint);
// Register a state change listener
const unsubscribe = overlay.subscribe((state) => {
  console.log('Breakpoint changed:', state.breakpoint?.id);
});
// Remove the listener when done
unsubscribe();

FAQs:

Q: How do I prevent the overlay from appearing in production builds?
A: Install the package as a development dependency using --save-dev or -D flags. Configure your bundler to tree-shake the import in production builds. For webpack, use environment-based conditional imports. For Vite, wrap the import in a if (import.meta.env.DEV) check.

Q: Can I customize the badge position or styling?
A: The badge uses Shadow DOM. You cannot modify the internal styles directly. The badge positions itself with position: fixed at top: 16px; right: 16px with z-index: 2147483647.

Q: Why does the active breakpoint show null even though I configured breakpoints?
A: This occurs when the current viewport width does not match any configured breakpoint ranges. Check that your breakpoint definitions cover the full viewport spectrum.

Q: How do I integrate this with React or Vue component lifecycle?
A: Call initOverlay once during application initialization outside component render cycles. Store the returned handle in a module-level variable or singleton service. Call start() when your root component mounts. Call stop() or destroy() when your root component unmounts. Avoid calling initOverlay inside component render functions as this creates new instances on every render.

Changelog:

01/14/2026

  • fix next vulnerability

You Might Be Interested In:


Leave a Reply