Freeze any hover state with one line of JavaScript
Some elements only exist while you're hovering: a tooltip, a dropdown, a custom
cursor, the :hover styles on a button. The moment you move your mouse toward
the DevTools panel to inspect them — they're gone. You can't select what you
can't keep on screen.
There's a one-line trick that's been quietly passed around for years, and it solves exactly this:
setTimeout(() => { debugger; }, 3000);Open the console, run it, then hover the thing you care about. After 3
seconds the debugger statement trips, the JS event loop halts, and the page is
frozen mid-state. Now you can poke around the Elements panel freely — the
tooltip is still open, the dropdown still expanded, the :hover styles still
applied.
Try it
Drag this to your bookmarks bar, or copy it. Pick how long you need to get your mouse into position:
(function () {var ms = 3000;var b = document.createElement("div");b.style.cssText ="position:fixed;z-index:2147483647;left:16px;bottom:16px;padding:8px 12px;" +"font:600 13px ui-monospace,SFMono-Regular,monospace;color:#fff;" +"background:#0a0a0a;border:1px solid #333;border-radius:8px;pointer-events:none";document.body.appendChild(b);var end = Date.now() + ms;var id = setInterval(function () {var left = end - Date.now();if (left <= 0) {clearInterval(id);b.remove();debugger;return;}b.textContent = "freezing in " + (left / 1000).toFixed(1) + "s — hover now";}, 80);})();
The bookmarklet adds a tiny countdown badge so you know how long you've got, then freezes. Hit the button (or your bookmark) on any page, mouse over the hover-only element, and wait for the freeze.
Why it works
debugger; is a real JavaScript statement — when DevTools is open, it acts like
a breakpoint at that line. Wrapping it in setTimeout buys you a window to move
the mouse and trigger the transient state before execution pauses.
When the breakpoint hits, the whole event loop stops. Nothing re-renders,
no mouseleave fires, no animation advances. The DOM is suspended exactly as it
was, so :hover / :focus-within styles and any JS-driven open state stay put
while you inspect.
Two things to know:
- DevTools must be open for
debugger;to break. No open DevTools, no pause. - To resume, hit the ▶ (resume) button in the Sources panel, or press
F8.
When you don't need it
Chrome and Firefox both let you force element states directly:
- Select the element in the Elements panel.
- In the Styles pane, click :hov.
- Tick
:hover,:focus,:active, etc.
That's cleaner for pure-CSS states. The debugger trick wins when the element
only exists while hovering — JS-mounted tooltips, portals, menus that unmount
on mouseleave — because forcing :hover can't bring back a node that isn't in
the DOM yet. Freeze first, inspect second.
Takeaways
setTimeout(() => { debugger; }, 3000)freezes the page mid-interaction so hover-/focus-only UI stays on screen.- DevTools must be open; resume with
F8. - For plain CSS states, the :hov toggle is tidier — reach for the freeze when the node disappears the instant you stop hovering.