Skip to content

Intrinsic sizing for inline SVG; viewport re-resolution and clipping for SVG content; img/object dimension attributes - #634

Open
nicoburns wants to merge 1 commit into
devin/1786156433-img-object-dimsfrom
devin/1786151607-block-replaced-sizing
Open

Intrinsic sizing for inline SVG; viewport re-resolution and clipping for SVG content; img/object dimension attributes#634
nicoburns wants to merge 1 commit into
devin/1786156433-img-object-dimsfrom
devin/1786151607-block-replaced-sizing

Conversation

@nicoburns

@nicoburns nicoburns commented Aug 8, 2026

Copy link
Copy Markdown
Member

Summary

Builds on #639 and #643 (img/object dimension attribute mapping, now the base branch of this PR). This PR fixes how replaced SVG (and img) elements are sized and painted. #642 (stacked on this PR) adds viewport re-resolution for viewBox-less SVG; together with #643 they make css/CSS2/normal-flow/block-replaced-height-001/002/004/005/006/007 pass and a full-suite comparison vs main shows 51 tests fixed, 3 regressed (regressions analysed below).

Inline SVG intrinsic sizing (layout/mod.rs, node/element.rs)

SvgImageData previously exposed only usvg::Tree::size(), which conflates "declared absolute dimensions" with usvg's fallbacks (percentages resolved against 100x100, viewBox size, etc.). New accessors preserve what the root <svg> actually declared:

  • intrinsic_width()/intrinsic_height(): Some only for absolute (non-percentage) width/height attributes
  • viewbox_aspect_ratio(): ratio from the viewBox when dimensions are missing
  • resolved_width()/resolved_height(): inline-<svg>-only resolution where percentage attributes resolve against the containing block

The replaced measure function now receives a correct inherent_size/inherent_ratio for SVG instead of usvg's fallback size, so CSS2's intrinsic-sizing rules (ratio transfer, 300x150 default) apply per spec.

SVG content clipping (render.rs)

SVG elements now participate in replaced-content clipping like raster images (fixes overflow bleed in e.g. css/CSS2/positioning/absolute-replaced-width-003b.xht and css/css-overflow/display-flex-svg-overflow-default.html). Exception: an SVG containing backdrop-blending groups (mix-blend-mode mapped by usvg) is not clipped, since the isolated buffer of a clip layer would make the blend composite against transparency instead of the page backdrop (css/compositing/mix-blend-mode/mix-blend-mode-svg.html).

Remaining known regressions (3)

  • css/css-rhythm/replaced-elements/block-level-{img,canvas}-margins-affected-by-block-step-size.html: these passed on main only because replaced elements were stretch-sized to the 100px container. With correct intrinsic sizing they need actual block-step-size support to pass.
  • css/css-lists/list-item-definition.html: display: list-item on <svg>/<img> plus ::before/::after list-item markers; the previous pass was accidental (test and ref both rendered identically wrong). Needs marker-box work unrelated to replaced sizing.

WPT results

52 newly passing, 5 newly failing (net +47).

Full diff (57 changed tests)
+ Fail => Pass css/CSS2/backgrounds/background-001.xht
+ Fail => Pass css/CSS2/backgrounds/background-002.xht
+ Fail => Pass css/CSS2/backgrounds/background-003.xht
+ Fail => Pass css/CSS2/backgrounds/background-006.xht
+ Fail => Pass css/CSS2/backgrounds/background-007.xht
+ Fail => Pass css/CSS2/backgrounds/background-008.xht
+ Fail => Pass css/CSS2/backgrounds/background-009.xht
+ Fail => Pass css/CSS2/backgrounds/background-010.xht
+ Fail => Pass css/CSS2/backgrounds/background-014.xht
+ Fail => Pass css/CSS2/backgrounds/background-018.xht
+ Fail => Pass css/CSS2/backgrounds/background-022.xht
+ Fail => Pass css/CSS2/backgrounds/background-087.xht
+ Fail => Pass css/CSS2/backgrounds/background-182.xht
+ Fail => Pass css/CSS2/backgrounds/background-328.xht
+ Fail => Pass css/CSS2/backgrounds/background-329.xht
- Pass => Fail css/CSS2/backgrounds/background-attachment-applies-to-007.xht
- Pass => Fail css/CSS2/backgrounds/background-attachment-applies-to-009.xht
- Pass => Fail css/CSS2/backgrounds/background-attachment-applies-to-012.xht
- Pass => Fail css/CSS2/backgrounds/background-attachment-applies-to-013.xht
- Pass => Fail css/CSS2/backgrounds/background-attachment-applies-to-014.xht
+ Fail => Pass css/CSS2/backgrounds/background-image-cover-002.xht
+ Fail => Pass css/CSS2/backgrounds/background-image-cover-004.xht
+ Fail => Pass css/CSS2/backgrounds/background-image-cover-attachment-001.xht
+ Fail => Pass css/CSS2/backgrounds/background-image-transparency-001.xht
+ Fail => Pass css/CSS2/backgrounds/background-repeat-001.xht
+ Fail => Pass css/CSS2/backgrounds/background-repeat-002.xht
+ Fail => Pass css/CSS2/backgrounds/background-repeat-003.xht
+ Fail => Pass css/CSS2/backgrounds/background-repeat-005.xht
+ Fail => Pass css/CSS2/borders/border-bottom-width-003.xht
+ Fail => Pass css/CSS2/borders/border-bottom-width-025.xht
+ Fail => Pass css/CSS2/borders/border-bottom-width-058.xht
+ Fail => Pass css/CSS2/borders/border-bottom-width-069.xht
+ Fail => Pass css/CSS2/borders/border-bottom-width-080.xht
+ Fail => Pass css/CSS2/borders/border-top-width-003.xht
+ Fail => Pass css/CSS2/borders/border-top-width-025.xht
+ Fail => Pass css/CSS2/borders/border-top-width-058.xht
+ Fail => Pass css/CSS2/borders/border-top-width-069.xht
+ Fail => Pass css/CSS2/borders/border-top-width-080.xht
+ Fail => Pass css/CSS2/borders/border-width-shorthand-001.xht
+ Fail => Pass css/CSS2/borders/border-width-shorthand-002.xht
+ Fail => Pass css/CSS2/borders/border-width-shorthand-003.xht
+ Fail => Pass css/CSS2/borders/border-width-shorthand-004.xht
+ Fail => Pass css/CSS2/floats-clear/float-replaced-width-011.xht
+ Fail => Pass css/CSS2/inline-svg-100-percent-in-body.html
+ Fail => Pass css/CSS2/normal-flow/block-replaced-width-006.xht
+ Fail => Pass css/CSS2/normal-flow/inline-block-replaced-width-006.xht
+ Fail => Pass css/CSS2/normal-flow/inline-replaced-width-006.xht
+ Fail => Pass css/CSS2/positioning/absolute-replaced-width-006.xht
+ Fail => Pass css/CSS2/positioning/absolute-replaced-width-013.xht
+ Fail => Pass css/CSS2/positioning/absolute-replaced-width-020.xht
+ Fail => Pass css/CSS2/positioning/absolute-replaced-width-027.xht
+ Fail => Pass css/CSS2/positioning/absolute-replaced-width-034.xht
+ Fail => Pass css/CSS2/positioning/absolute-replaced-width-069.xht
+ Fail => Pass css/CSS2/positioning/absolute-replaced-width-076.xht
+ Fail => Pass css/css-borders/corner-shape/corner-shape-svg-border.html
+ Fail => Pass css/css-images/object-position-svg-001i.html
+ Fail => Pass css/css-images/object-position-svg-002i.html

Generated by the WPT workflow.

Link to Devin session: https://dioxus.staging.devinenterprise.com/sessions/51256d0b440341bd874c6dc59e138478
Requested by: @nicoburns

@nicoburns nicoburns self-assigned this Aug 8, 2026
@staging-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

@staging-devin-ai-integration
staging-devin-ai-integration Bot changed the base branch from main to devin/1786154184-item-is-replaced August 8, 2026 01:57
@staging-devin-ai-integration
staging-devin-ai-integration Bot force-pushed the devin/1786151607-block-replaced-sizing branch from 32505e0 to 9f6188e Compare August 8, 2026 01:57
@staging-devin-ai-integration staging-devin-ai-integration Bot changed the title Intrinsic sizing for block-level replaced elements; unscaled rendering for viewBox-less SVG Intrinsic sizing for inline SVG; viewport re-resolution and clipping for SVG content; img/object dimension attributes Aug 8, 2026
@staging-devin-ai-integration
staging-devin-ai-integration Bot force-pushed the devin/1786151607-block-replaced-sizing branch from 9f6188e to 9e02773 Compare August 8, 2026 02:12
@staging-devin-ai-integration
staging-devin-ai-integration Bot changed the base branch from devin/1786154184-item-is-replaced to main August 8, 2026 02:13
@staging-devin-ai-integration
staging-devin-ai-integration Bot force-pushed the devin/1786151607-block-replaced-sizing branch from 9e02773 to 8cfe721 Compare August 8, 2026 02:19
@staging-devin-ai-integration
staging-devin-ai-integration Bot force-pushed the devin/1786151607-block-replaced-sizing branch from 8cfe721 to cc929f6 Compare August 8, 2026 02:34
@staging-devin-ai-integration
staging-devin-ai-integration Bot changed the base branch from main to devin/1786156433-img-object-dims August 8, 2026 02:34
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