A responsive debugging overlay: breakpoints, overflow, grid ruler
DevTools device mode is great until it is in the way: it shrinks your viewport, it lags on resize, and it cannot tell you which element is causing that infuriating horizontal scrollbar. This article builds a lightweight responsive debugging overlay you inject straight onto the page — a live size badge, the active breakpoint name, an outline-everything toggle, an overflow finder and a column ruler. Pair it with the JustZix CSS pane and you can spot a bug and fix it in the same window.
Why an on-page overlay beats device mode
Device mode answers "how does this look at 375px?" — but most responsive bugs are not about a specific width, they are about the transitions: a margin that does not collapse, an image with a fixed width, a flex child that refuses to shrink. For those you want to drag your real browser window and watch numbers change live. An injected overlay gives you that, at native performance, with no chrome stealing pixels.
Everything below is one JS rule. Inject it once; the overlay updates itself as you resize.
The live viewport badge
Start with a fixed badge that shows the current viewport width and height and updates on every resize.
(() => {
document.getElementById('jz-resp')?.remove();
const bar = document.createElement('div');
bar.id = 'jz-resp';
Object.assign(bar.style, {
position: 'fixed', left: '10px', bottom: '10px',
font: '12px/1.5 ui-monospace, monospace',
background: '#111', color: '#fff',
padding: '6px 10px', borderRadius: '6px',
zIndex: 2147483600, pointerEvents: 'none',
whiteSpace: 'pre',
});
document.body.appendChild(bar);
function update() {
const w = window.innerWidth;
const h = window.innerHeight;
bar.textContent = w + ' × ' + h + 'px · ' + bpName(w);
}
window.addEventListener('resize', update);
update();
The badge sits bottom-left, ignores pointer events so it never blocks a click, and rides a z-index high enough to clear almost any site.
Naming the active breakpoint
A raw pixel count is useful, but "are we in the tablet range?" is the question you actually ask. Map widths to names — adjust the table to match the site's framework (these are the Tailwind defaults).
function bpName(w) {
if (w >= 1536) return '2xl';
if (w >= 1280) return 'xl';
if (w >= 1024) return 'lg';
if (w >= 768) return 'md';
if (w >= 640) return 'sm';
return 'xs';
}
Now the badge reads something like 1024 × 768px · lg — and the moment you drag across a breakpoint boundary, the name flips. That instant feedback is the whole point.
Outline every element
The classic "outline everything" trick exposes the box model of the whole page — you immediately see stray margins, misaligned columns and accidental nesting. Make it a toggle so it does not get in the way.
let outlined = false;
const styleEl = document.createElement('style');
document.head.appendChild(styleEl);
function toggleOutline() {
outlined = !outlined;
styleEl.textContent = outlined
? '* { outline: 1px solid rgba(255,0,0,.35) !important; }'
: '';
}
// Press 'o' to toggle outlines
window.addEventListener('keydown', e => {
if (e.key === 'o' && !e.metaKey && !e.ctrlKey) toggleOutline();
});
Using outline rather than border matters — outlines do not take up space, so toggling them does not reflow the layout you are trying to inspect.
The horizontal-overflow finder
This is the feature worth the whole article. A sideways scrollbar means some element is wider than the viewport — but which one? Walk every element and flag any whose right edge spills past document.documentElement.clientWidth.
function findOverflow() {
document.querySelectorAll('.jz-of').forEach(n => {
n.classList.remove('jz-of');
n.style.outline = '';
});
const limit = document.documentElement.clientWidth;
const culprits = [];
document.querySelectorAll('*').forEach(el => {
const r = el.getBoundingClientRect();
if (r.right > limit + 1 || r.left < -1) {
culprits.push(el);
el.classList.add('jz-of');
el.style.outline = '3px solid #f0f';
}
});
console.log('%c' + culprits.length + ' overflowing element(s)',
'color:#f0f');
console.log(culprits);
return culprits;
}
// Press 'f' to find overflow
window.addEventListener('keydown', e => {
if (e.key === 'f' && !e.metaKey && !e.ctrlKey) findOverflow();
});
Press f and every offending element gets a magenta outline; the list also lands in the Output Console so you can inspect each node. Usually it is one element — a fixed-width image, an unbroken long string, a negative margin — and now you know precisely which.
A column / grid ruler
To check that content lines up to a grid, overlay evenly spaced columns. This draws a 12-column ruler with gutters across the viewport.
function toggleRuler() {
let ruler = document.getElementById('jz-ruler');
if (ruler) { ruler.remove(); return; }
ruler = document.createElement('div');
ruler.id = 'jz-ruler';
Object.assign(ruler.style, {
position: 'fixed', inset: '0',
display: 'grid', gap: '16px',
gridTemplateColumns: 'repeat(12, 1fr)',
maxWidth: '1200px', margin: '0 auto',
padding: '0 16px',
zIndex: 2147483500, pointerEvents: 'none',
});
for (let i = 0; i < 12; i++) {
const col = document.createElement('div');
col.style.background = 'rgba(0, 120, 255, .12)';
ruler.appendChild(col);
}
document.body.appendChild(ruler);
}
// Press 'g' to toggle the grid ruler
window.addEventListener('keydown', e => {
if (e.key === 'g' && !e.metaKey && !e.ctrlKey) toggleRuler();
});
})();
Match maxWidth, gap and column count to the site's actual grid. Now you can see at a glance whether headings, cards and images snap to the same lines — or drift off by a few pixels.
The full keyboard map
- o — toggle outline-everything.
- f — find horizontal overflow culprits.
- g — toggle the 12-column grid ruler.
- The size badge updates on every resize, no key needed.
Keep the modifier checks (!e.metaKey && !e.ctrlKey) so the shortcuts do not collide with browser commands. If the site itself listens for plain letter keys, swap to something like Alt+O.
Pairing it with the CSS pane
This overlay tells you what is wrong; the JustZix CSS pane lets you fix it without leaving the tab. The workflow:
- Inject the overlay from the JS pane and run it.
- Drag your window across breakpoints, watching the badge.
- See a scrollbar appear? Press
f, get the culprit. - Open the CSS pane and patch it live —
max-width: 100%,overflow-wrap: anywhere, whatever it needs. - When it looks right, save the CSS into the rule so the fix sticks.
See also
- A live accessibility audit overlay — the same on-page-overlay approach for a11y.
- A custom print stylesheet for better PDFs — fixing layout for a different medium.
Stop fighting device mode for bugs it cannot diagnose. Install JustZix, inject the overlay, and debug responsive layouts in your real browser at full speed.
Rate this post
No ratings yet — be the first.