Skip to content

Implement CSS Grid layout - #45

Closed
brainkim wants to merge 9 commits into
mainfrom
grid-layout
Closed

Implement CSS Grid layout#45
brainkim wants to merge 9 commits into
mainfrom
grid-layout

Conversation

@brainkim

Copy link
Copy Markdown
Member

Implements css-grid-2's mandatory core: explicit track lists (lengths, percentages, fr, auto, min-/max-content, minmax(), fit-content(), repeat() including auto-fill/auto-fit with empty-track collapse, named lines), grid-template-areas with line-name derivation, placement by number/span/name/area with negative lines, sparse and dense auto-placement with implicit tracks in both directions, the full §12 track-sizing algorithm (span-ordered intrinsic distribution, fr expansion, stretch), §10 alignment including justify-items/justify-self (new to the engine) and baseline rows, §9 absolutely-positioned children against grid-area containing blocks, inline-grid, gaps, and the grid/grid-template/grid-area/grid-row/grid-column shorthands (off the exhaustiveness-test exclusion list, which now enforces them). grid-template-columns/rows report used track sizes in getComputedStyle.

Excluded by name: subgrid and masonry, refused in the track-list parser with reasoning at the site and in the compatibility classification.

fr units tile integer cells exactly through the existing absolute-edge rounding — 1fr 1fr 1fr over 80 columns is 27/26/27, snapshot-pinned across widths 20–40.

Six bugs found and fixed during construction, including between-track space landing inside areas, double-counted spanning distribution, and item percentages resolving against the container instead of the area. justify-content/align-content now default to CSS's normal (flex behavior bit-identical).

Tests: 140 cases (~1700 lines) including 12 mutation-path tests asserting incremental === fresh for template rewrites, item moves, display toggles, and area-map changes — written to interlock with the in-flight invalidation consolidation. Plus examples/grid.ts and a tmux scenario asserting a grid-template-areas dashboard lands where its picture says.

Performance: a 200-row grid relayout costs the same as flex (2.07ms vs 2.02ms); a 600-item grid is 7.6ms, inside the 8ms keystroke budget; non-grid paths unregressed. No new caches.

Compatibility: 187 properties supported, up from 170; all fifteen grid-family rows measured yes.

Full suite: node 1387/0, bun 1412/0 (exit 0 in the agent's uncontended run; my re-verification hit the two known load-flake files under concurrent agents, both green in isolation).

🤖 Generated with Claude Code

https://claude.ai/code/session_01C8sSHf9EvBZroVnsXJbJSD

brainkim and others added 9 commits August 14, 2026 15:19
display: grid lands beside table and flexbox in the layout dispatch, with
css-grid-2's track sizing (§12), placement (§8.3, §8.5) and alignment (§10)
written from the spec. layoutAbsoluteChild learns a containing block that is
not the parent's padding box, which is what §9 asks of a placed out-of-flow
child.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Track lists, area maps and grid lines are parsed with css-tree and handed to
the compute core already structured; the shorthands (grid, grid-template,
grid-area, grid-row, grid-column, grid-gap) expand, and the exhaustiveness
test no longer excuses them. justify-content and align-content take CSS's own
initial value, `normal`, which is what tells a grid's auto tracks to fill.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Atomic inlines are a kind, not one display: inline-grid joins inline-block
under isAtomicInline and lays its items out under a content root of its own.
Collapsible white space between items is suppressed by the items' USED
display, so a newline in the markup no longer becomes an item.

getComputedStyle resolves grid-template-columns/rows to the used track sizes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Space that justify-content puts BETWEEN tracks was landing inside the areas
either side of it, so an item in a 4-cell track came out 26 cells wide. A grid
line has two positions once the tracks are spread; an area takes the inner
pair.

With it: an out-of-flow child stretches to fill the area it was placed in
(css-align-3 §5.2), and a row is sized tall enough for the baseline alignment
it is about to be given (css-grid-2 §12.5).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
examples/grid.ts states its whole shape in grid-template-areas and places
every panel by naming the area it belongs in; the panels are grids of their
own, over auto-fill bars, max-content labels and justify-self.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
tests/grid.test.ts, 140 cases from css-grid-2 and css-align-3, including the
ones a terminal has to answer for itself: tracks that tile every width from
20 cells to 40 with no seam, and a grid built by mutation that lands exactly
where the same grid built at once does.

Three bugs the tests found: the spanning distribution counted the space a
previous step had already given away, an item's percentages resolved against
the grid container rather than its own area, and a blockified inline grid item
was being broken around the block inside it -- handing its children to the
grid as cells of their own. The placement shorthands serialize around slashes
now, so grid-area survives a round trip through cssText.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every grid property's probe now moves something -- a track list resolving to
the size the box already had measured as no support at all -- and
justify-items/justify-self are probed on a grid, which is the only container
whose inline axis they own. 187 features supported, up from 170.

The layout guide gains a grid section; subgrid and masonry are named as
refusals rather than omissions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The dashboard's bars flow down their columns instead of across a row: the
rows are the scale, and a bar is one item spanning from its own height to the
baseline. A tmux scenario checks the areas map lands where its picture says.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@brainkim

Copy link
Copy Markdown
Member Author

Need to redo this because of the refactor

@brainkim brainkim closed this Aug 20, 2026
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