Fixed-position outer <svg> lands outside a clip after scroll; fixed HTML boxes are re-anchored
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 72/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- html, javascript
- Domain
- frontend
Research direction
Start in src/utils/capture.helpers.js at freezeViewportPositioned (around line 134), where clones that aren't HTML elements are skipped. Run the reproduction page with the clip, then check that the svg pixel at (120, 100) is red. Confirm that an outer svg whose parent is not in the SVG namespace gets re-anchored, while nested SVG children are left alone and the div result stays the same.
Written by the indexing model from the issue text.
Description
Describe it simply:
With clip on a scrolled page, a position: fixed <div> is drawn where it is painted, but a position: fixed outer <svg> is not. The svg keeps position: fixed in the clone, so in the foreignObject it sits at its viewport offset from the top of the document and falls outside a clip of the scrolled viewport.
Seen in 3.3.0 and 3.3.4 (Chromium 153).
Quick demo to reproduce
<!doctype html>
<html>
<body style="margin: 0; height: 3000px">
<svg width="200" height="100" style="position: fixed; left: 20px; top: 50px">
<rect width="200" height="100" fill="red" />
</svg>
<div style="position: fixed; left: 300px; top: 50px; width: 200px; height: 100px; background: blue"></div>
<script type="module">
import { snapdom } from "https://unpkg.com/@zumer/[email protected]/dist/snapdom.mjs";
window.scrollTo(0, 1000);
// The visible viewport strip that holds both fixed boxes.
const image = await snapdom(document.body, { clip: { x: 0, y: 1000, width: 600, height: 200 } });
const canvas = await image.toCanvas();
const pixel = (x, y) => [...canvas.getContext("2d").getImageData(x * canvas.width / 600, y * canvas.height / 200, 1, 1).data];
console.log(JSON.stringify({ svg: pixel(120, 100), div: pixel(400, 100) }));
</script>
</body>
</html>
Observed: {"svg":[0,0,0,0],"div":[0,0,255,255]}: the div is drawn and the svg is missing.
Expected: the svg's centre is red, [255,0,0,255], as it is on screen.
Where
freezeViewportPositioned skips any clone that isn't an HTML element, so an outer <svg> is never re-anchored:
An outer <svg> (one whose parent isn't SVG) is a CSS box like any HTML element and takes the same absolute position and size. Letting it through that check (isHTMLEl(cloneEl) || (cloneEl.localName === 'svg' && <its source parent is not in the SVG namespace>)) draws the svg in the right place. We carry that patch against the built bundle for now.
This was written by Claude Code on behalf of max-sixty
- Dominant language
- JavaScript
- Stars
- 8.2k
- Forks
- 308
- Avg merge
- 2h 47m
- Merged PRs (30d)
- 3
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from zumerlab/snapdom
-
🔧 in development
Difficulty 3/5 1-2 days Newbie friendliness 52/100
All issues in zumerlab/snapdom
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
Add: EUROTV NEWSOpenchannels:add check:passed
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
-
curriculum documentation quality
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
githubnext/gh-aw-workshop#4638 ·
Maintainers usually reply within 1 day
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster no-stale P2
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
openclaw/openclaw-enterprise#2571 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
fabriziosalmi/certmate#1247 ·
Maintainers usually reply within 1 day