Skip to content

Commit 561c680

Browse files
lukemeliaclaude
andcommitted
Set the velcro overlay position:absolute from CSS to stop the first-frame jump
The hover overlay is positioned by velcro (floating-ui), but it only became `position: absolute` inside the offset middleware — which runs *after* floating-ui has already measured the rects on the first computePosition. So the first frame was measured against the wrong containing block and the whole overlay (the teal type-label tab, the select chip, the menu, the outline) painted ~60px off, then snapped into place one frame later. floating-ui requires the floating element to already be absolutely positioned when it first measures. Declare `position: absolute` in the overlay's CSS so it is in effect before velcro's first measurement; the middleware still sets it too, harmlessly. Confirmed via frame-by-frame capture that the overlay's own top/left was the thing jumping (526->466 between frame 0 and 1), so fixing it here fixes every piece of chrome that rides the overlay. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent dcd6003 commit 561c680

2 files changed

Lines changed: 15 additions & 0 deletions

File tree

packages/host/app/components/operator-mode/operator-mode-overlays.gts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,14 @@ export default class OperatorModeOverlays extends Overlays {
218218
</AdornContext>
219219
<style scoped>
220220
.actions-overlay {
221+
/* Establish `position: absolute` from CSS, before velcro's first
222+
computePosition runs. floating-ui requires the floating element to
223+
already be absolutely positioned when it first measures; the offset
224+
middleware also sets this, but that runs *after* the initial
225+
measurement, so without it here the overlay (and everything riding
226+
it — the type-label tab, the select chip, the menu) lands ~1 frame
227+
off and visibly jumps into place on first hover. */
228+
position: absolute;
221229
pointer-events: none;
222230
/* Allow the type-label tab and selection chip to extend outside the
223231
overlay's bounding box without being clipped. */

packages/host/app/components/operator-mode/overlays.gts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ export default class Overlays extends Component<OverlaySignature> {
9595
{{/each}}
9696
<style scoped>
9797
.base-overlay {
98+
/* Establish `position: absolute` from CSS, before velcro's first
99+
computePosition runs. floating-ui requires the floating element to
100+
already be absolutely positioned when it first measures; the offset
101+
middleware also sets this, but that runs *after* the initial
102+
measurement, so without it here the overlay lands ~1 frame off and
103+
visibly jumps into place on first appearance. */
104+
position: absolute;
98105
width: 100%;
99106
height: 100%;
100107
pointer-events: none;

0 commit comments

Comments
 (0)