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 second you move your mouse toward
the DevTools panel to inspect one, it's gone. You can't select what won't stay
on screen.
There's a one-line trick for this that's been quietly passed around for years:
setTimeout(() => { debugger; }, 3000);Open the console, run it, then hover the thing you care about. After three
seconds the debugger statement trips, the JS event loop stops, and the page
freezes mid-state. The tooltip is still open, the dropdown still expanded, the
:hover styles still applied. Now you can dig around the Elements panel as long
as you like.
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);})();
It drops a small countdown badge so you know how long you've got, then freezes. Click it on any page, mouse over the hover-only element, and wait.
Why it works
debugger; is a real JavaScript statement. When DevTools is open, it behaves
like a breakpoint on that line. Wrapping it in setTimeout buys you a few
seconds to move the mouse and trigger the transient state before execution
pauses.
Once 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 your :hover and :focus-within styles (and any JS-driven open state)
stay put while you poke at them.
Two things to remember. DevTools has to be open or debugger; won't break. And
to start the page again, hit the resume button (▶) in the Sources panel or
press F8.
When you don't need it
For plain CSS states, Chrome and Firefox can just force them. Select the element,
open the :hov menu in the Styles pane, and tick :hover, :focus,
:active, whatever you need. Cleaner, no freezing required.
The debugger trick earns its keep when the element only exists while you're
hovering: JS-mounted tooltips, portals, menus that unmount on mouseleave.
Forcing :hover can't bring back a node that isn't in the DOM yet. So freeze
first, then inspect.
Ask your agent to implement this
Read the full writeup at https://seangeng.com/writing/freeze-hover-states-in-devtools.md and implement it in my project.
It covers: Freeze any hover state with one line of JavaScript. The setTimeout(debugger) trick: pause the page mid-hover so you can finally inspect tooltips, dropdowns, and other hover-only elements in the Elements panel. Comes with a bookmarklet to do it in one click.
Requirements:
- Follow the technique/approach exactly as described in the writeup.
- Adapt names, colors, and styling to my project's existing conventions.
- If it's a component, make it reusable with sensible props and TypeScript types.
- Keep it accessible: semantic HTML, keyboard support, and respect prefers-reduced-motion.
- When done, tell me which files you created or changed and how to use it.Paste into Claude Code, Codex, Cursor, or any agent. view raw .md