Skip to content

fix(css): map <svg> width/height attributes to CSS lengths - #292

Merged
tannevaled merged 1 commit into
mainfrom
svg-presentation-size
Oct 18, 2026
Merged

tannevaled merged 1 commit into
mainfrom
svg-presentation-size

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Problem

<span style="display:inline-block;width:2em;height:2em"><svg width="100%" height="100%" viewBox="0 0 100 100">…</svg></span> at font-size 20px rendered 100×100 (the viewBox size) instead of 40×40. <svg width="2em" height="2em"> rendered 2×2.

Spec read

SVG 2 §7.8 (sizing properties): the outermost svg has width/height presentation attributes for the CSS properties, and auto means 100%. A negative value is invalid and behaves as auto. The value syntax is CSS's, so %, em and rem apply.

Root cause

Only the image loader read these attributes, through attrDim (svg.go). It keeps the leading digits (2em → 2) and ignores percentages. The cascade never saw them, because presentationalHints (css/presentational.go) covered only HTML length hints (img, table, …).

Change

presentationalHints maps an <svg>'s width/height to CSS declarations, so they get the same zero specificity as <img width> and an author style still wins. A bare number becomes px; any other valid non-negative length or percentage is kept; auto, negative and invalid values are dropped.
<img src=x.svg width=…> is unchanged: on img these are HTML dimension attributes, where 2em legitimately parses as 2.

Tests

  • TestSVGWidthHeightAttributes (pixel bbox): %, em and rem failed on main (100×100, 2×2, 3×1) and pass now. px, bare number, style-wins and auto were already correct and are kept as controls.
  • TestSVGLengthHint (css unit). css coverage 99.5%.
  • Note: TestLoadFontFacesTriesSlotCandidatesConcurrentlyNotSequentially failed once locally at 615ms against its 600ms bound while the machine was loaded. It passed 3/3 when rerun; that is a timing test, unrelated to this change.

🤖 Generated with Claude Code

On an outermost <svg>, width and height are presentation attributes for
the CSS width/height properties (SVG 2 §7.8), so they take any CSS
<length-percentage>. They were read only by the image loader's attrDim,
which kept the leading digits: width="2em" became 2px and width="100%"
was ignored, so the SVG fell back to its viewBox size (100x100 instead of
40x40 in a 2em box).

They are now presentation hints (zero specificity, before author rules,
like <img width>): a bare number is px, any other valid non-negative
length or percentage is kept, and auto/negative/invalid values are
dropped, so the cascade resolves em/rem/% like any other length.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit 43b7f82 into main Oct 18, 2026
7 checks passed
@tannevaled
tannevaled deleted the svg-presentation-size branch October 18, 2026 14:31
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.

1 participant