Skip to content

Add support for the CSS aspect-ratio property#67

Draft
maitredede wants to merge 4 commits into
plutoprint:mainfrom
maitredede:feature/aspect-ratio
Draft

Add support for the CSS aspect-ratio property#67
maitredede wants to merge 4 commits into
plutoprint:mainfrom
maitredede:feature/aspect-ratio

Conversation

@maitredede

Copy link
Copy Markdown

Implements the CSS aspect-ratio property. Closes #46.

What

Parses aspect-ratio: auto || <ratio> (with <ratio> = <number [0,∞]> [ / <number [0,∞]> ]?) and applies the preferred aspect ratio during layout, following CSS Sizing Level 4 §4.

  • Parsing/storage — new AspectRatio longhand, a consumeAspectRatio consumer, and a BoxStyle::aspectRatio() accessor returning { isAuto, value }. The value is stored in the generic property map (not inherited), like width/height.
  • Replaced boxes — the CSS ratio is blended into ReplacedBox::computeAspectRatioInformation: a specified ratio overrides the natural one, unless auto was given and the element has a natural ratio of its own.
  • Non-replaced block boxes — the automatic axis is derived from the definite one in BlockBox::computeWidth/computeHeight, reusing the existing constrain* and box-sizing (adjust*) helpers.

Box-sizing

Per the spec, the reference box depends on the value:

  • intrinsic ratio and auto && <ratio>content box;
  • a bare <ratio> → the box designated by box-sizing (border box when box-sizing: border-box).

A degenerate ratio (a 0 side) behaves as auto.

Not covered (yet)

  • Full "transferred size constraints" from CSS Sizing 4 (min/max transferred through the ratio) — handled best-effort via the existing constrain* functions.
  • Dedicated integration for flex/grid/table items — the value is parsed and available via the accessor, but not consumed by those layouts.

Testing

Built with meson/ninja (no new warnings) and verified end-to-end by rendering to PNG and measuring the resulting box dimensions:

Case Expected Result
width:200px; aspect-ratio:2/1 200×100
height:100px; width:auto; aspect-ratio:3/1 300×100
width:150px; aspect-ratio:1/1; box-sizing:border-box; border:10px border box 150×150
width:100px; aspect-ratio:16/9 100×56.25
<img> (40×20) no aspect-ratio 40×20 (unchanged)
<img> width:80px; aspect-ratio:1/1 80×80 (CSS overrides intrinsic)
<img> aspect-ratio:auto 1/1 40×20 (intrinsic wins)

maitredede and others added 4 commits July 16, 2026 15:52
Register the `aspect-ratio` longhand, parse the `auto || <ratio>`
grammar into an ident/pair/list value, and expose it on BoxStyle via
an AspectRatio { isAuto, value } accessor. No layout effect yet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Blend the CSS aspect-ratio into ReplacedBox::computeAspectRatioInformation:
a specified ratio overrides the natural one, unless `auto` was given and
the element has a natural ratio of its own (per CSS Sizing 4).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Derive the automatic axis from the definite one in BlockBox::computeWidth
/computeHeight. The ratio applies to the content box, except for a bare
`<ratio>` where it applies to the box designated by `box-sizing`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

Add support for aspect-ratio

1 participant