gap-inspector
v0.2.2
Published
A React dev overlay that measures visual gaps and explains the CSS/layout contributions behind them.
Maintainers
Readme
Gap Inspector
Gap Inspector is a React dev overlay for explaining visual spacing. It lets you draw a horizontal or vertical line between rendered elements, then copies a markdown report with the selected DOM elements, total gap, CSS/layout contributors, and a pixel equation.
It is built for the frontend workflow where "make this gap match that gap" is too vague for an agent to execute reliably.
Install
npm install gap-inspector -DUsage
import { GapInspector } from "gap-inspector";
export function App() {
return (
<>
<YourApp />
<GapInspector />
</>
);
}The toolbar appears in the bottom-right corner. Open it and draw a line between two rendered edges; the measurement axis is inferred from the drag direction. Drag the panel header to move the inspector anywhere on screen.
What It Reports
Measured horizontal gap: 48px
From: `.Sidebar`
To: `.PreviewPanel`
Common ancestor: `.MainShell`
Contributions:
- 16px from `.MainShell` column-gap (16px) - flex parent
- 8px from `.TableWrap` padding-right (8px)
- 6px from `.MarketTableBody` scrollbar gutter - Native scrollbar gutter inside this scroll container.
- 24px from `.MainShell` flex space-between - Rendered space between sibling layout branches.
Equation: 16px + 8px + 6px + 24px = 54pxNotes
The tool measures rendered geometry first, then attributes pixels to computed CSS where it can. Some spacing is not directly caused by a single margin or padding declaration. Flex distribution, grid tracks, explicit widths, min-width, transforms, scrollbars, and empty wrappers may show up as layout or unattributed space.
That distinction is deliberate: the report should be useful to an LLM without inventing false causes.
Adjacent vertical margins that collapse are reported as the single winning margin (with a note about the collapsed sibling). Negative margins and transformed elements cannot be expressed as positive contributors, so they are surfaced as warnings instead.
Hold ⌥/Alt while the inspector is open to let pointer events through to the page — useful for opening click-driven menus or scrolling nested panes into the state you want to measure.
Limitations
- Closed shadow roots cannot be inspected. Open shadow roots are pierced for hit-testing and get
host >>> innerselectors in reports. - Iframes are measured as opaque boxes; their contents render in a separate document and cannot be attributed (the report warns when an endpoint is an iframe).
- CSS-only
:hoverstates collapse as soon as the pointer moves onto the inspector canvas, so they cannot be measured. The Alt passthrough covers UI that stays open after a click. position: fixed/stickyelements move relative to the document, so their committed overlays catch up one frame behind during scroll (everything else tracks scroll with zero lag).
API
<GapInspector
initiallyOpen={false}
onMeasure={(measurement) => {
console.log(measurement.markdown);
}}
/>You can also call the measurement engine directly:
import { measureGap } from "gap-inspector";
const measurement = measureGap({
axis: "horizontal",
start: { x: 220, y: 340 },
end: { x: 420, y: 340 }
});