Skip to content

Fix SVG intrinsic sizing for replaced elements - #606

Merged
nicoburns merged 5 commits into
mainfrom
devin/1784873193-svg-intrinsic-sizing
Aug 4, 2026
Merged

Fix SVG intrinsic sizing for replaced elements#606
nicoburns merged 5 commits into
mainfrom
devin/1784873193-svg-intrinsic-sizing

Conversation

@nicoburns

@nicoburns nicoburns commented Aug 4, 2026

Copy link
Copy Markdown
Member

Summary

Implement CSS intrinsic sizing for SVG replaced elements instead of using usvg::Tree::size() as the intrinsic dimensions in every case.

SvgImageData tracks absolute root dimensions separately from the root viewBox aspect ratio. intrinsic_size() resolves both declared dimensions, derives a missing dimension from the intrinsic ratio, and applies the CSS default object size (300x150) for ratio-only SVGs.

This now uses usvg::Tree::intrinsic_dimensions() — a new upstream API (branch DioxusLabs/resvg#devin/1785858271-intrinsic-dimensions, proposed for linebender/resvg) exposing the declared root width/height/viewBox with percentages unresolved — instead of re-parsing the SVG XML with roxmltree. usvg is bumped to 0.48.1, whose viewBox-ratio missing-dimension fix (resvg#1045) also removes the previous inject-attribute-and-re-parse hack.

Temporary [patch.crates-io] entries point usvg/anyrender/anyrender_svg at git branches until the upstream resvg PR lands+releases and DioxusLabs/anyrender#78 is released.

WPT (css/css-flexbox, full local run)

  • main: 713 PASS → branch: 721 PASS (+9 newly passing flex-aspect-ratio-img-*, −1 aspect-ratio-intrinsic-size-007.html)
  • The 007 regression: the reference page uses <svg viewBox=...> with no width/height, which per SVG spec should default to width:100% but is now sized with the 300x150 default object size. Pre-existing in this PR before the usvg migration; needs separate handling of the root <svg> element's presentation-attribute defaults.

Test Plan

cargo test -p blitz-dom svg_tests, cargo test -p blitz-tests --test svg_background_size, cargo clippy -p blitz-dom, cargo fmt --check all pass.

Link to Devin session: https://app.devin.ai/sessions/1372da3cbba94b90a9c63cad94bdbdc1
Requested by: @nicoburns

WPT results

15 newly passing, 0 newly failing (net +15).

Full diff (15 changed tests)
+ Fail => Pass css/css-backgrounds/background-size/vector/tall--contain--height.html
+ Fail => Pass css/css-backgrounds/background-size/vector/tall--contain--width.html
+ Fail => Pass css/css-backgrounds/background-size/vector/wide--contain--height.html
+ Fail => Pass css/css-backgrounds/background-size/vector/wide--contain--width.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-column-013.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-column-014.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-column-015.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-column-018.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-008.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-009.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-010.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-011.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-015.html
+ Fail => Pass css/css-sizing/aspect-ratio/replaced-element-039.html
+ Fail => Pass css/css-sizing/aspect-ratio/replaced-element-040.html

Generated by the WPT workflow.

@nicoburns nicoburns self-assigned this Aug 4, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review August 4, 2026 13:03
@devin-ai-integration
devin-ai-integration Bot force-pushed the devin/1784873193-svg-intrinsic-sizing branch from 408fba7 to 3df6c8e Compare August 4, 2026 15:11
Bumps usvg to 0.48.1 (with git patches for usvg's pending
intrinsic_dimensions API and anyrender's usvg bump) and replaces the
roxmltree attribute sniffing and re-parse hack in parse_svg_image.
@devin-ai-integration
devin-ai-integration Bot force-pushed the devin/1784873193-svg-intrinsic-sizing branch from a08f3a0 to 7a72d91 Compare August 4, 2026 16:19
SvgImageData now stores only the Arc<usvg::Tree>; intrinsic
width/height and the viewBox ratio are derived on demand from
Tree::intrinsic_dimensions, leaving room to resolve percentage
dimensions against layout context in future.
…ng block

For an inline <svg> element the width/height attributes are presentation
attributes: absent attributes default to 100% and percentages resolve
against the containing block. SVG loaded as an image keeps context-free
intrinsic dimensions per CSS. Adds SvgImageData::resolved_width/height
and feeds them into the replaced element attr_size for svg elements.
…l flow

Absent width/height attributes on an inline <svg> element no longer
default to 100% of the containing block (which broke bare <svg>
elements). Instead, a replaced SVG with only an intrinsic aspect ratio
uses the CSS2 stretch-fit width when the available width is definite,
and keeps the default object size in shrink-to-fit contexts (floats,
abspos).
@nicoburns
nicoburns merged commit ff7fb21 into main Aug 4, 2026
27 of 28 checks passed
dotmonkey added a commit to tti-inspirata/ebook_blitz that referenced this pull request Aug 5, 2026
上游该 commit 依赖未发布的 usvg Tree::intrinsic_dimensions(仅存在于
DioxusLabs/resvg 临时分支)与配套的 anyrender_svg,靠 blitz workspace 的
[patch.crates-io] 兜住;而 ReaderEngine 以 root 身份构建时该 patch 被 cargo
忽略,直接编译失败。等上游 usvg 0.48.2 / anyrender_svg 发布后取消本 revert。
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