IntersectionObserver's rect agrees with getBoundingClientRect
Check id client-rect-vs-observer
What an ordinary browser yields
The observer's rect and the accessor's rect place the element at the same coordinates when both are read in one frame.
What a detector infers
A third account of where one element sits, from the most ordinary API that has one. IntersectionObserver hands every entry a boundingClientRect, but it is produced by the intersection machinery working off the compositor's geometry, not by the DOMRect accessor a page calls directly. That makes it an independent route to the same fact — and a route that a modification applied at the accessor does not automatically travel down. The comparison is deliberately taken INSIDE the observer callback, calling the accessor again at that instant, so both numbers describe a single frame of a single layout; a scroll or a reflow between two reads could otherwise manufacture a difference that means nothing, and the probe is position:fixed so that scrolling cannot move it in the first place. This row exists alongside the SVG screen-matrix row rather than replacing it, because the two decline in different circumstances. The matrix check needs an SVG element and a matrix free of rotation and skew, since a rotated mapping legitimately separates a mapped corner from an axis-aligned box. IntersectionObserver has no such conditions and exists in every modern browser, but it is asynchronous and can fail to fire — measured happening in a zero-sized viewport, where it never delivered an entry at all. Between them, one is almost always able to speak. Measured on a shipping stealth browser: the observer reported the element at exactly its authored position on every launch while the accessor, called in the same callback, was displaced by a fraction of a pixel that changed per session.
How to resolve it
Both numbers describe one element in one frame of one layout, so they cannot be set independently. A value applied to the DOMRect accessor — the surface element-size and font fingerprinting actually reads — does not reach the intersection machinery, which carries on reporting the real geometry, and subtracting one from the other recovers the applied value directly. Not scored as a contradiction, because perturbing rects is a legitimate privacy technique. What it demonstrates is that such a technique has to cover every route to a position, and the routes are more numerous than the obvious one: the accessor, the SVG screen matrix, and the observer are three, and there is no reason to think that list is complete.
Read in the wild by
CloakBrowser (measured)
IntersectionObserver placed a fixed element at exactly its authored coordinates while getBoundingClientRect, called inside the same observer callback on the same element, placed it a fraction of a pixel away — on every launch measured, with the offset redrawn each session and differing between the horizontal and vertical axes. Because the observer's account is untouched, the applied value can be read straight off by subtraction.
3/3 launches at left:137px/top:41px — observer (137, 41) against accessor (136.953125, 40.953125), (136.96875, 41.0625) and (137.015625, 41.03125); deltas (0.046875, 0.046875), (0.03125, -0.0625) and (-0.015625, -0.03125). Stock Chrome 150 and Clearcote on the same machine: delta exactly (0, 0).
CloakBrowser (measured)Every attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Render & GPU
- getBoundingClientRect === Range client rects
bcr-vs-rangeTwo independent APIs are pointed at the same laid-out text: an absolutely-positioned div containing "WWWWWiiiii" is measured with… - clientWidth and offsetWidth equal the box the element itself reports
layout-box-arithmeticclientWidth and offsetWidth are not opinions the browser offers — CSSOM defines them as arithmetic over values the same element hands you… - a box placed at the viewport origin measures its origin as zero
client-rect-origin-vs-positionZero is scale-invariant, and that single property is the whole check. - SVG's screen matrix agrees with the element's client rect
svg-ctm-vs-client-rectTwo independent routes to a single fact. getScreenCTM maps an SVG element's user space into viewport coordinates, and getBoundingClientRect… - WebGPU's build constants are identical in every realm
webgpu-sync-surface-vs-realmWebGPU's cheapest fingerprint is not the GPU at all. navigator.gpu.getPreferredCanvasFormat() and navigator.gpu.wgslLanguageFeatures are… - the GL limits the driver reports are limits the driver will actually honour
webgl-limits-vs-driverEvery other WebGL check on this page reads what getParameter SAYS. - ANGLE's translated shader is written in the dialect the renderer string implies
shader-backend-vs-rendererThe UNMASKED_RENDERER_WEBGL string is a label — a piece of text a page can rewrite to name any GPU and any graphics backend. - every extension WebGL advertises can actually be instantiated
webgl-extensions-vs-drivergetSupportedExtensions() returns a list a page can rewrite; getExtension(name) either hands back a real extension object or null, and that…
Clearcote is a browser built for fingerprint coherence
It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.
This audit takes no position on how Clearcote scores on Render & GPU checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.
See the other checks in Render & GPU — the family client-rect-vs-observer belongs to.