Skip to content

fix(php-transformer): include table-cell box model in layout-table tracks - #2213

Merged
chubes4 merged 3 commits into
trunkfrom
fix/layout-table-track-remainder
Sep 25, 2026
Merged

chubes4 merged 3 commits into
trunkfrom
fix/layout-table-track-remainder

Conversation

@chubes4

@chubes4 chubes4 commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Problem

After #2211, sized layout-table columns keep their authored CSS width (flex-basis + flex-grow:0). A fixed-layout post + sidebar row still came out 10px too wide in the leftover (unsized) column.

Measured at 1440×900 on a public two-column blog post:

Source WordPress after #2211
Post column (content-box) 735px 745px
Sidebar 215px at x=981 215px at x=985
First photo 735×490 745×496

The leftover track was container − 215, ignoring the table box model. Photos sized to the post column inherited the extra 10px.

Root cause

A CSS width on a td is content-box. Flex columns are border-box with box-sizing:border-box. Copying 215px as flex-basis made the sized track 2px too small (UA td padding is 1px per side) and dropped UA border-spacing:2px (engine-support forces gap:0 to beat Gutenberg's 2em).

On a 960px table-layout:fixed row:

Stage: php-transformer layout-table → columns lowering (layoutTableCellTrackWidth / layoutTableColumnsAttributes / engine-support CSS). Not capture.

Fix

  • Absolute cell tracks include horizontal padding (UA 1px per side when unset, or authored/cellpadding) and border widths, converting content-box width to the border-box flex-basis.
  • Percent tracks stay as-is (padding remains inside, matching existing contract).
  • :where() restores UA table-cell padding:1px at zero specificity so authored padding still wins.
  • Separate-border leftover rows (an unsized column remains) reconstruct spacing as column-gap + padding-inline on a carrier whose selector beats the gap:0 reset. Collapsed and all-percent rows keep gap:0.
  • Box 1–4 value shorthands expand through one helper, CssValueInspector::expandBoxShorthand() → [top, right, bottom, left]. Layout-table track sums and StyleAttributeMapper::boxSides() both use it. Border-width tokens in border shorthands go through CssValueInspector::isBorderWidthToken().

No product or platform names.

Test

php-transformer/tests/unit/layout-table-column-track-width.php

  • Fails on trunk: content-box pixel cell width plus ua padding becomes the border-box column track (got 215px, want 217px) plus HTML width, authored padding, UA padding CSS, and leftover spacing (6 failing assertions).
  • Passes with the fix: 14 assertions (CSS px, HTML width, authored padding:0 keeps 215px, authored padding:0 4px becomes 223px, leftover spacing, collapsed/percent rows do not emit UA gap).

php-transformer/tests/unit/css-value-inspector.php covers the shared side-expansion helper.

composer test, php tests/contract/production-acceptance-matrix.php, and visual-parity npm test passed locally.

Before / after (Playwright, 1440×900 unless noted)

Post: /blog/experiencing-the-rural-life-of-100-years-ago/

Post content-box Sidebar x First photo scrollWidth @390
Source 735 981 735×490 —
After #2211 745 985 745×496 390
This PR 735 981 735×490 390 (no overflow)

/blog/ at 1440: post 735, sidebar x=981. 768 and 390 stack (flex-basis:100%), no overflow.

Block editor (rural-life post): 97 blocks, all isValid.

AI disclosure

Written by Claude (Anthropic) via Claude Code, orchestrated by chubes4. Claude measured source vs WordPress table geometry (content-box width, UA padding, border-spacing), extended layout-table column lowering to include the cell box model and leftover-row spacing, added a regression test that failed on trunk, ran php-transformer suites, built an SSI dev package from this worktree, imported the kept capture, and measured before/after including Gutenberg isValid. Review follow-up extracted CssValueInspector::expandBoxShorthand() / isBorderWidthToken() so track sums and StyleAttributeMapper share one side-expansion implementation.

@chubes4

chubes4 commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

Reviewed and reproduced: the root cause is right (a td's CSS width is content-box; the UA 1px cell padding and 2px border-spacing were dropped, leaving the unsized track 10px wide), and the fresh-import numbers match the source exactly.

One change before merge: this adds a new padding/border shorthand parser (layoutTableCellInlinePadding, layoutTableCellInlineBorderWidths) while StyleAttributeMapper::parseBorderShorthand() already exists and several call sites already enumerate padding sides. Please reuse or extract a single shared side-expansion helper (e.g. on CssValueInspector) and build the track sum on it, so there is one shorthand implementation. Behavior and tests stay the same.

Review by Claude (Anthropic) via Claude Code, orchestrated by @chubes4: AI read the diff, checked for existing primitives, and drafted these notes.

…acks

Absolute cell widths are content-box; flex columns are border-box, so
the leftover track was 10px too wide after sized columns kept their CSS
width. Add UA/authored padding to the column flex-basis, restore UA
table-cell padding, and carry separate-border spacing as column-gap plus
padding-inline when a row still has an unsized column.
…eset

The leftover-track spacing carrier was one class. Engine-support gap:0 is
more specific, so column-gap never applied and the unsized column kept the
inter-cell 2px.
@chubes4
chubes4 force-pushed the fix/layout-table-track-remainder branch from 54c70fc to 0862757 Compare September 25, 2026 13:37
@chubes4
chubes4 merged commit 212d575 into trunk Sep 25, 2026
10 checks passed
@chubes4
chubes4 deleted the fix/layout-table-track-remainder branch September 25, 2026 14:13
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