Skip to content

A canvas patch no longer puts stale CSS back over a stylesheet Vite hot-swapped - #37

Merged
flowtricks merged 1 commit into
flowtricks:mainfrom
LilianBarbe:canvas-keeps-hot-swapped-styles
Oct 13, 2026
Merged

flowtricks merged 1 commit into
flowtricks:mainfrom
LilianBarbe:canvas-keeps-hot-swapped-styles

Conversation

@LilianBarbe

Copy link
Copy Markdown
Contributor

The bug

A style edit written to a stylesheet that reaches the page through a CSS @import is lost on the canvas: the file holds the new value, the canvas shows the one from when the dev server started. I hit it on a project whose global.css imports its sheets with @import "./utilities.css" layer(utilities);, where dragging a padding in the style panel never moved the canvas.

The cause

Astro renders such a stylesheet from its first server-side compile for as long as the server runs, while Vite hot-swaps the live <style> on every write. refreshDevStyles (413e468) copies the server's text into any live dev stylesheet whose text differs, so each patch of the page puts that first compile back over what Vite just wrote.

Measured on a real dev server (Astro 7.1.4, a page importing global.css, which @imports utilities.css into a layer), with style:writeFile and the page opened as the canvas opens it:

canvas padding-left server HTML
after three writes 30px 1px
after avb:patch-now 1px 1px

The fix

The patch takes the server's text only when the server changed it between its previous rendering and this one.

  • A page's own <style>, the case 413e468 fixed, still updates: the server's text changes with the edit.
  • A stylesheet the server renders as it did before keeps its live text, which is Vite's to update.
  • A stylesheet the previous rendering did not carry takes the server's text, as before.

With the fix the same run keeps 30px across three patches.

Tests

  • test/electron/previewClient/morph.test.js gets two cases: a hot-swapped stylesheet the server renders stale keeps its text, and a stylesheet new to the rendering takes the server's.
  • test/integration/styleLatency.js, opened with #avb-design, still shows every page and component style edit within 100 ms on Astro 7.2.10, and a text-only edit rewrites no stylesheet.

One thing I noticed on the way

npm run integration:style opens ${server.url}/ without the #avb-design hash, so the page runs as a browser tab and reloads on a page edit. Its counters come back NaN and "a text-only edit rewrites no stylesheet" fails. I did not check whether that predates this branch, and left the script alone.

🤖 Generated with Claude Code

A style edit written to a stylesheet that reaches the page through a CSS
`@import` (global.css importing utilities.css) showed on the canvas and
was then lost, or never showed: the file held the new value, the canvas
the one from when the dev server started.

Astro renders such a stylesheet from its first server-side compile for as
long as the server runs, while Vite hot-swaps the live <style> on every
write. refreshDevStyles (413e468) copied the server's text into any live
dev stylesheet whose text differed, so each patch of the page put that
first compile back over what Vite had just written. Measured on a real
dev server (Astro 7.1.4, `@layer` + `@import … layer()`): after three
writes the canvas read 30px and the server's HTML still said 1px; the
next `avb:patch-now` set the canvas back to 1px.

The patch now takes the server's text only when the server changed it
between its previous rendering and this one. That is still what brings a
page's own <style> (the case 413e468 fixed): the server's text changes
with the edit. A stylesheet the server renders as it did before keeps
its live text, which is Vite's to update. One the previous rendering did
not carry takes the server's text, as before.

With the fix the same run keeps 30px across three patches, and
test/integration/styleLatency.js, opened as the canvas opens it
(`#avb-design`), still shows every page and component style edit within
100 ms on Astro 7.2.10.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@flowtricks
flowtricks merged commit 5597a0c into flowtricks:main Oct 13, 2026
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants