css+layout: implement a scoped subset of multi-column layout (columns) - #244
Merged
Merged
Conversation
pkg.go.dev's own "Source Files" list (.UnitFiles-fileList{columns:
12.5rem 5;...}) rendered as one long single column instead of up to 5
narrow ones. Round 143 found this real but deferred it as too large;
this round re-read the actual spec mechanics before trusting that
estimate and found the one confirmed trigger narrower than it looked:
a <ul> of short, uniform-height <li>s, not arbitrary flowing prose.
Scoped to exactly that shape: each in-flow element child is laid out
once at the real column width (fully atomic, never split across
columns), then a single greedy cumulative-height pass buckets children
into N columns and repositions each already-correct box with the
existing translateBox helper. No true iterative balancing, no
column-span, no column-rule painting, no fragmenting a child's own
internal content across columns.
Reuses the existing column-gap field shared with flex/grid rather than
adding a new one (real CSS defines it once, in Box Alignment); its
shared "unset" default moved from the Go zero value to Length{Auto:
true} so multicol can resolve it differently (1em, not flex/grid's 0)
without touching their own behaviour, confirmed via their own gapLen/
gapPxCSS treating Auto and explicit-0 identically.
Caught along the way: two hand-built fallback css.Style{} literals
(place()'s and table.go's cellStyle()) never set ColumnWidth, so its Go
zero value read as "column-width:0" to any code checking !Auto,
breaking five pre-existing Shadow DOM slot tests. Fixed both to set it
explicitly, matching every other Auto-defaulted field in those same
literals.
Bench: every page's own webengine-side render is byte-identical to the
previous round's committed one except three, and none of those three
is this round's own effect (confirmed directly, not assumed) - see the
FIDELITY.md entry for the full attribution. The real fix sits at
~75,000px on pkg.go.dev's ~77,000px page, outside any bench comparison
region ever capped to a page's own top ~2,500px.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
.UnitFiles-fileList{columns:12.5rem 5;...}) rendered as one long single column instead of up to 5 narrow ones. Round 143 found this real but deferred it as too large; this round re-read the actual CSS Multi-column Layout spec mechanics before trusting that estimate and found the one confirmed trigger narrower than it looked: a<ul>of short, uniform-height<li>s, not arbitrary flowing prose needing mid-paragraph fragmentation.translateBoxhelper. No true iterative balancing, nocolumn-span, nocolumn-rulepainting, no fragmenting a child's own internal content across columns.column-gapfield shared with flex/grid rather than adding a new one (real CSS defines it once, in the Box Alignment module) — its shared "unset" default moved from the Go zero value toLength{Auto:true}so multicol can resolve it differently (1em, not flex/grid's 0) without touching their own behaviour, confirmed via their owngapLen/gapPxCSStreating Auto and explicit-0 identically.css.Style{}literals (place()'s andtable.go'scellStyle()) never setColumnWidth, so its Go zero value read as "column-width:0" to any code checking!Auto— breaking five pre-existing Shadow DOM slot-distribution tests. Fixed both to set it explicitly, matching every other Auto-defaulted field in those same literals.Test plan
go build ./...,go vet ./...,go test ./...all greenlayoutback to its 100.0% ratchet floor)css/parse_test.go(column-count/column-width/columns— every value shape, the||order-independence, invalid shapes,unset, explicitinherit,inheritFrom) and the newlayout/multicol_test.go(resolveColumnstested directly for every resolution case, plus full-pipeline tests for balanced columns,column-widthalone, the real trigger's own narrower-than-requested shape,display:none/out-of-flow/bare-text children correctly excluded, an overlong child staying whole, andcolumn-count:1falling back to ordinary block stacking)cssandlayout5, because the container is narrower than5×12.5rem+gaps— the spec's own documented "fewer columns when narrower" behaviour, confirmed correct)columns-*class anywhere in tailwindcss.com's real HTML, despite the utility being defined in its CSS). The real fix sits at ~75,000px on pkg.go.dev's ~77,000px page, outside any bench comparison region ever capped to a page's own top ~2,500px — see the FIDELITY.md entry for the full, page-by-page attribution🤖 Generated with Claude Code