Skip to content

fix(css): resolve em against the element font-size - #221

Merged
LeadcodeDev merged 1 commit into
chantier/audit-2026-09from
fix/em-font-size
Sep 22, 2026
Merged

LeadcodeDev merged 1 commit into
chantier/audit-2026-09from
fix/em-font-size

Conversation

@LeadcodeDev

Copy link
Copy Markdown
Owner

Severity Low, category correctness. Location: crates/rustmotion-core/src/css/taffy_bridge.rs:292

Impact

build() (layout_pass.rs:122-154) hands the same ConversionContext to to_taffy_style for every node in the tree and never re-derives it from the node's own (cascaded) font-size, and the only production builder keeps ..LengthContext::default() → font_size: 16.0 (scene.rs:29-37). So padding: "1em", gap: "0.5em", width: "10em", top: "2em" all resolve against 16px regardless of the element's actual font size: on a 48px-font card, padding: "1em" reserves 16px instead of 48px. Unlike the context-free .px() accessors — which were deliberately made to warn loudly for exactly this class of drop (units.rs:240-256) — this path is silent, so the wrong geometry reaches both the renderer and the validator with no signal.

Fix

Derive a per-node LengthContext while building the taffy tree: resolve the node's own font-size (post-cascade) to px and pass it as ctx.length.font_size to its own to_taffy_style call and to its children's. Until that exists, emit the same one-shot warning order already uses (taffy_bridge.rs:142-151) whenever an em reaches this bridge.

Evidence the audit read

ParsedLength::Em(em) => tf::LengthPercentage::length(em * ctx.length.font_size),
ParsedLength::Rem(r) => tf::LengthPercentage::length(r * ctx.length.root_font_size),

Based directly on the chantier branch.

Part of the September 2026 audit remediation chantier. Refs #220 (RM-26).

@LeadcodeDev LeadcodeDev added the bug Something isn't working label Sep 21, 2026
@LeadcodeDev LeadcodeDev self-assigned this Sep 21, 2026
@LeadcodeDev
LeadcodeDev force-pushed the fix/em-font-size branch 2 times, most recently from 9ad0f9d to 95ffad7 Compare September 21, 2026 23:43
@LeadcodeDev
LeadcodeDev force-pushed the fix/em-font-size branch 2 times, most recently from 3b3111e to 5b5c226 Compare September 22, 2026 08:36
build() (layout_pass.rs:122-154) hands the *same* ConversionContext to
to_taffy_style for every node in the tree and never re-derives it from the
node's own (cascaded) font-size, and the only production builder keeps
..LengthContext::default() → font_size: 16.0 (scene.rs:29-37). So padding:
"1em", gap: "0.5em", width: "10em", top: "2em" all resolve against 16px
regardless of the element's actual font size: on a 48px-font card, padding:
"1em" reserves 16px instead of 48px. Unlike the context-free .px() accessors
— which were deliberately made to warn loudly for exactly this class of drop
(units.rs:240-256) — this path is silent, so the wrong geometry reaches both
the renderer and the validator with no signal.

Fix: Derive a per-node LengthContext while building the taffy tree: resolve
the node's own font-size (post-cascade) to px and pass it as
ctx.length.font_size to its own to_taffy_style call and to its children's.
Until that exists, emit the same one-shot warning order already uses
(taffy_bridge.rs:142-151) whenever an em reaches this bridge.

Refs #220
@LeadcodeDev
LeadcodeDev merged commit 39d9584 into chantier/audit-2026-09 Sep 22, 2026
0 of 3 checks passed
@LeadcodeDev
LeadcodeDev deleted the fix/em-font-size branch September 22, 2026 08:54
LeadcodeDev added a commit that referenced this pull request Sep 22, 2026
build() (layout_pass.rs:122-154) hands the *same* ConversionContext to
to_taffy_style for every node in the tree and never re-derives it from the
node's own (cascaded) font-size, and the only production builder keeps
..LengthContext::default() → font_size: 16.0 (scene.rs:29-37). So padding:
"1em", gap: "0.5em", width: "10em", top: "2em" all resolve against 16px
regardless of the element's actual font size: on a 48px-font card, padding:
"1em" reserves 16px instead of 48px. Unlike the context-free .px() accessors
— which were deliberately made to warn loudly for exactly this class of drop
(units.rs:240-256) — this path is silent, so the wrong geometry reaches both
the renderer and the validator with no signal.

Fix: Derive a per-node LengthContext while building the taffy tree: resolve
the node's own font-size (post-cascade) to px and pass it as
ctx.length.font_size to its own to_taffy_style call and to its children's.
Until that exists, emit the same one-shot warning order already uses
(taffy_bridge.rs:142-151) whenever an em reaches this bridge.

Refs #220
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant