docs: render handover, fix plan, and repro fixtures

Adds docs/render with a handover covering what shipped on this branch,
the verification methodology, build gotchas, and the prioritized list of
remaining work, alongside the phase plan and the index of the Gecko
layout study that informed it.

Adds render-repros: one HTML fixture per bug fixed here (absolute fills,
mixed inline+block layout, carousel clipping, z-index order, clear,
tables, image density and alt fallback) plus run.sh to render them all
in obscura and Chromium for side-by-side checking. Run before and after
any layout or paint change.
This commit is contained in:
SGavrl
2026-07-22 12:32:25 +00:00
parent 22f33e4dec
commit b7c3d086bf
8 changed files with 123 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html><html><head><title>abs fill</title><style>body{margin:0}
.box{width:400px;border:2px solid red;margin:6px}</style></head><body>
<p>Every colored area below must FILL its box. Before P0 all were 0x0 (blank).</p>
<div class="box"><span>A rel(auto-width)+BLOCK, abs inset:0:</span>
<div style="position:relative;height:100px"><div style="position:absolute;inset:0;background:blue"></div></div></div>
<div class="box"><span>B rel+FLEX, abs inset:0:</span>
<div style="position:relative;height:100px;display:flex"><div style="position:absolute;inset:0;background:green"></div></div></div>
<div class="box"><span>C rel+GRID, abs inset:0:</span>
<div style="position:relative;height:100px;display:grid"><div style="position:absolute;inset:0;background:purple"></div></div></div>
<div class="box"><span>D abs width:100%/height:100%:</span>
<div style="position:relative;height:100px"><div style="position:absolute;top:0;left:0;width:100%;height:100%;background:teal"></div></div></div>
<div class="box"><span>E padding-hack ratio + abs fill IMG:</span>
<div style="position:relative;height:0;padding-bottom:40%"><img src="https://web.dev/static/images/ai-feature.png" style="position:absolute;top:0;left:0;width:100%;height:100%;object-fit:cover"></div></div>
</body></html>

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html><html><head><title>carousel clip</title><style>
body{margin:0;font-family:sans-serif}
.viewport{width:300px;height:110px;overflow:hidden;border:2px solid red;margin:8px;position:relative}
.track{display:flex;width:900px;transform:translate(-300px,0)}
.slide{width:300px;height:100px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:24px}
.s1{background:#e33}.s2{background:#3a3}.s3{background:#36e}
</style></head><body>
<p>Track translated -300px: ONLY slide TWO (green) may be visible.</p>
<div class="viewport"><div class="track">
<div class="slide s1">ONE</div><div class="slide s2">TWO</div><div class="slide s3">THREE</div>
</div></div>
<p>Control (transform:none): only slide ONE (red) visible.</p>
<div class="viewport"><div class="track" style="transform:none">
<div class="slide s1">ONE</div><div class="slide s2">TWO</div><div class="slide s3">THREE</div>
</div></div>
</body></html>

View File

@@ -0,0 +1,12 @@
<!DOCTYPE html><html><head><title>clear</title><style>body{margin:0;font-family:sans-serif;width:500px}
.thumb{float:left;width:120px;height:80px;background:#8bd}
.cleared{clear:both;background:#fc6;height:40px}
</style></head><body>
<p>clear:both must drop BELOW the float at full width (orange bar under the blue thumb):</p>
<div>
<div class="thumb"></div>
<p style="margin:4px 0">short text beside the float.</p>
<div class="cleared">CLEARED: full width below</div>
<p>after content flows normally.</p>
</div>
</body></html>

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html><html><head><title>img density + alt</title><style>body{margin:0;font-family:sans-serif}
.box{border:2px solid red;margin:6px;display:inline-block}</style></head><body>
<p>Density: A raw 648px, B srcset 2x -> ~324 CSS px, C 648w + sizes:300px -> ~300px</p>
<div><span>A:</span><div class="box"><img src="https://web.dev/static/images/ai-feature.png"></div></div>
<div><span>B:</span><div class="box"><img srcset="https://web.dev/static/images/ai-feature.png 2x"></div></div>
<div><span>C:</span><div class="box"><img srcset="https://web.dev/static/images/ai-feature.png 648w" sizes="300px"></div></div>
<p>Broken-image fallback: D alt text only, E alt="" nothing, F no alt -> grey box</p>
<div>D: <img src="https://web.dev/nope-404.png" alt="a description of the missing photo" style="width:200px;height:60px"></div>
<div>E: <img src="https://web.dev/nope-404.png" alt="" style="width:200px;height:60px"></div>
<div>F: <img src="https://web.dev/nope-404.png" style="width:200px;height:60px"></div>
<p>G: cover img half-outside an overflow:hidden viewport must not bleed past the red border:</p>
<div style="width:300px;height:100px;overflow:hidden;border:2px solid red;margin-left:120px">
<div style="display:flex;transform:translate(-150px,0)">
<img src="https://web.dev/static/images/ai-feature.png" style="width:300px;height:100px;object-fit:cover;flex-shrink:0">
<img src="https://web.dev/static/images/ai-feature.png" style="width:300px;height:100px;object-fit:cover;flex-shrink:0">
</div>
</div>
</body></html>

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html><html><head><title>mixed inline+block</title><style>body{margin:0;font-family:sans-serif}
.box{width:400px;border:2px solid red;margin:8px}</style></head><body>
<p>Block children of a mixed-content block must stay FULL WIDTH (not shrink to content),
and inline runs must wrap as text, not one word per line.</p>
<div class="box">
leading inline text that should wrap across the full width of this container as a normal paragraph would
<div style="background:#cdf">block child: must span the full 400px</div>
trailing inline text after the block child
<div style="position:relative;height:60px;background:#efe">
<div style="position:absolute;inset:0;background:rgba(0,128,0,.5)">contentless wrapper w/ abs fill</div>
</div>
</div>
</body></html>

17
render-repros/run.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
# Render every repro fixture in obscura and Chromium side by side.
# Usage: ./run.sh [outdir] (default: ./out)
set -u
BIN="${OBSCURA_BIN:-$(cd "$(dirname "$0")/.." && pwd)/target/release/obscura}"
DIR="$(cd "$(dirname "$0")" && pwd)"
OUT="${1:-$DIR/out}"
mkdir -p "$OUT"
for f in "$DIR"/*.html; do
n=$(basename "$f" .html)
OBSCURA_SHOT_W=900 OBSCURA_SHOT_H=1000 OBSCURA_ALLOW_PRIVATE_NETWORK=1 \
timeout 60 "$BIN" fetch "file://$f" --screenshot "$OUT/$n.obscura.png" --timeout 30000 --wait 2 >/dev/null 2>&1
timeout 60 google-chrome-stable --headless --disable-gpu --no-sandbox --hide-scrollbars \
--force-device-scale-factor=1 --window-size=900,1000 --screenshot="$OUT/$n.chrome.png" "file://$f" >/dev/null 2>&1
echo "rendered $n"
done
echo "output in $OUT"

21
render-repros/tables.html Normal file
View File

@@ -0,0 +1,21 @@
<!DOCTYPE html><html><head><title>tables</title><style>
body{margin:0;font-family:sans-serif;font-size:13px}
table{border-collapse:separate;border-spacing:2px;background:#eee}
td,th{background:#cde;padding:4px}
.w1 td.fixed{width:200px;background:#fc9}
.rowbg tr.hl{background:#f66}
.va td{height:70px}
</style></head><body>
<p>T1: td width:200px must set the whole COLUMN to 200px:</p>
<table class="w1"><tr><td class="fixed">fixed 200</td><td>auto col</td></tr>
<tr><td>second row same col</td><td>x</td></tr></table>
<p>T2: tr background must show behind its cells' gaps:</p>
<table class="rowbg"><tr><td>normal</td><td>row</td></tr>
<tr class="hl"><td style="background:transparent">HIGHLIGHTED</td><td style="background:transparent">ROW</td></tr></table>
<p>T3: cell text CENTERS vertically by default; top/bottom explicit:</p>
<table class="va"><tr><td>default middle</td><td style="vertical-align:top">explicit top</td><td style="vertical-align:bottom">explicit bottom</td></tr></table>
<p>T4: col width=150 must size column 1:</p>
<table><colgroup><col style="width:150px"><col></colgroup><tr><td>col 150</td><td>auto</td></tr></table>
<p>T5: percent width cell 50% of a 400px table (~198px):</p>
<table style="width:400px"><tr><td style="width:50%;background:#9f9">half</td><td>rest</td></tr></table>
</body></html>

View File

@@ -0,0 +1,12 @@
<!DOCTYPE html><html><head><title>z-index</title><style>body{margin:0;font-family:sans-serif}</style></head><body>
<p>A: z:10 overlay declared BEFORE a later sibling must paint ON TOP (green wins):</p>
<div style="position:relative;height:120px">
<div style="position:absolute;top:0;left:0;width:200px;height:100px;background:green;z-index:10"></div>
<div style="position:absolute;top:20px;left:40px;width:200px;height:100px;background:red"></div>
</div>
<p>B: z:-1 backdrop declared AFTER content must paint UNDER it (blue stays visible, orange edges show):</p>
<div style="position:relative;height:120px">
<div style="width:220px;height:90px;background:blue"></div>
<div style="position:absolute;top:0;left:0;width:260px;height:110px;background:orange;z-index:-1"></div>
</div>
</body></html>