Repository navigation
layout: block and inline formatting, CSS 2.1 §8.3.1, §9.4, §10 and §16 to a fragment tree - #154
Merged
Merged
Conversation
The output types (a fragment tree keyed by box id with line boxes and glyph runs), the states of block and inline formatting (a set of adjoining margins, a container's block flow, the width equation's input and output, a line box's extent, each box's role in the walk), their invariants, and the contract of every step over them, before the implementation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CSS 2.1 §8.3.1 collapsing margins (negative ones included) as a pending set of adjoining margins in each block container's flow; §9.4.1 block formatting contexts; §9.4.2 inline formatting contexts and line boxes over item 5.12's units, opportunities and first-fit step, with item 5.11's shaping through a font parameter; §10.3.2 to §10.3.4 and §10.3.9 widths with §10.4, §10.3.5 shrink-to-fit from min-content and max-content sizes; §10.6.2, §10.6.3, §10.6.7 heights with §10.7; §10.8 line heights, the strut and vertical-align; §16.1 text-indent and §16.2 text-align; HTML's align descendants; the Quirks Mode Standard's §3.3 to §3.7. Tables have a stated block placeholder until item 5.15. One walk with an explicit stack; lengths in 1/64 px with saturating arithmetic; a fragment tree keyed by box id. ERRATA: CSS 2.1 §8.3.1's definition and bullets disagree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Unit tests (36) with a font whose glyphs are em squares, so each expected position is worked out by hand: each of §8.3.1's adjoining pairs and results (negative margins, Hacker News' -10px), §10.3.3's five rules and the over-constrained cases, §10.4, align descendants, shrink-to-fit, replaced sizes, §10.5 and the percentage quirk, §10.6 and §10.7, §10.8.1's example and vertical-align values, the strut and quirks §3.3, §3.4, §3.6, §3.7, text-align and text-indent, markers, the table placeholder and a 100,000-deep tree. Golden dumps: html5lib's 1,761 documents and two pages of our own, cascaded and laid out in the vendored TrueType faces. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Eighteen harnesses: the margin set (against §8.3.1's rule written a second time), each step of a block container's flow from any state satisfying its invariant (enter, place, close, exit, finish), a line box's extent, §10.3.3's equality and rules, align descendants, §10.4, §10.3.5, §10.7 and the fill quirks, §10.8.1's half-leading, §16.2's offset, the walk's roles and the length arithmetic. All verified locally, each under 20 s and 0.7 GB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…i and Miri (5.14) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
atiernan
temporarily deployed
to
full-verification
November 13, 2026 00:01 — with
GitHub Actions
Inactive
This was referenced Nov 13, 2026
Merged
Merged
This branch was previously deployed
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.
What
Item 5.14 of
docs/phases/phase-5.md: new modulecrates/clazel-layout/src/flow/. Branchclaude/flow-layout-050856, tipc35d902, onmainat6e581e9.flow::layout(tree, arena, styles, fonts, viewport)takes item 5.13's box tree, the DOM arena (for the document's mode and replaced elements' attributes), the computed style (StyleFns), the fonts and the viewport. It returns aFragmentTreekeyed by box id:Lengths are 1/64 px in
i32with saturating arithmetic. The passes:style.rs: each box's style. Anonymous boxes inherit; §17.4 splits a table's properties between its wrapper and table boxes.inline.rs, preparation: each inline formatting context's units (5.12's Phase I output), wrap opportunities, and each text run shaped once.intrinsic.rs: min-content and max-content widths, leaves first, for §10.3.5's shrink-to-fit.block.rs: one walk with an explicit stack of tasks and a stack of block-container frames:widths.rs: §10.3.3's five rules, §10.3.4, §10.3.9, §10.4, HTML's "align descendants";replaced.rs: §10.3.2, §10.6.2);margins.rs): each container keeps a set of pending adjoining margins, and a resolution walk closes "open" containers from the outermost in when content is placed;inline.rs): 5.12'sfit_stepwith each line's width, Phase II, §16.1text-indent, §16.2text-align, and §10.8's line heights with the strut, half-leading and everyvertical-alignvalue;heights.rs: §10.6.3, §10.6.7, §10.7);state.rsstates each state, its invariant as a function, and each step's contract. It was committed first, on its own (78718e9), before the implementation. Nothing recurses: a tree 100,000 blocks deep lays out in 0.04 s (release).Fonts are a parameter,
flow::TextFns, as computed style is for the box tree:flow::FaceFontsis the real one, overclazel-fontfaces with 5.10's matching and 5.11's shaper;flow::BoxFontgives every glyph an em square with Ahem's metrics, so tests can be worked out by hand.Tables have a placeholder until 5.15. Wrapper and table boxes are laid out as blocks (the table's margins and
widthon the wrapper, shrink-to-fit whenauto). Row groups, rows, cells and captions are blocks stacked in their parent's flow; cells and captions are block formatting context roots. Columns are empty boxes. Every box in a table is laid out and its text readable.border-spacing, column widths, cellvertical-alignandcolspanhave no effect yet.No new dependency of any class. No
unsafe, no lint override, no tier change.Decisions taken from the plan (maintainer away)
These are recorded in
crates/clazel-layout/README.md("Decisions taken for 5.14") and at the top of each file.OS/2's typo metrics whenUSE_TYPO_METRICSis set, else fromhhea, as engines read them.line-height: normalis A + D + the line gap.sxHeight, or half an em.sublowers by 1/5 of the parent's font size andsuperraises by 1/3.autowidth is 0; the box is then over-constrained andmargin-rightfollows.center,div align, table parts'align):autoand that rule 2 over-constrained, using the nearest aligning ancestor;automargins would place the box;text-indent:each-lineandhangingare applied, and so is §16.1's rule for anonymous blocks;justifyis drawn asleft, and a line too wide for its box is start-aligned (CSS Text 3 §7.1†).body's parent content box is thehtmlbox as §3.6 makes it at least.imgis 0×0;iframehas none, so 300×150;inputandtextareause HTML §15.5.6's character-width conversion (the average width is the advance of0) and the line height;value(or "Submit" / "Reset");overflowis notvisibleunless it propagates to the viewport.min-heightfor the parent-bottom pair; "no in-flow children" against "all of its in-flow children's margins collapse"). The bullets are followed. "Reported upstream: not yet."bodythat §3.7 stretched. The result:<p>One<p>Twogives a 608pxhtmlbox in a 600px viewport.5a06deb5. CSS Text 3 §7.1 keeps its †.css/CSS2/normal-flow,margin-padding-clear,box-display,linebox,visudet,visuren) need 5.25's harness. They are not vendored or run here.Evidence
Unit tests (
src/flow/tests.rs, 36). Each uses the real cascade with adisplay-only UA sheet andBoxFont, with every expected position worked out by hand in a comment. Covered:margin-bottom:-10px, collapse-through and its position, BFC roots, inline blocks, the root element;1.2/1.2em/120%example; the half-leading; the strut and §3.4; §3.3 (a 1px spacer image gives a 1px line in quirks mode and a 10px one in no-quirks mode); everyvertical-alignvalue;br,text-alignandtext-indent, inline edges;Golden fragment dumps (
tests/golden_flow.rs,tests/golden/flow/):CLAZEL_BLESS=1regenerates them.Kani (
src/flow/proofs.rs). Each harness ran alone, in its own process group, under the lock, capped at 20 min and 8 GB RSS (polled every 5 s), on an Apple-silicon Mac. Times include cargo's start.collapsed_any(the margin set against §8.3.1's rule written a second time)enter_anyplace_anyclose_anyexit_anyfinish_anyline_extent_anysolve_block_any(no panic, width ≥ 0)solve_block_sum(§10.3.3's equality and rules)align_anywidth_min_max_anyshrink_to_fit_anyheights_anyhalf_leading_anyalign_offset_anyrole_anyhalves_anytimes_anyof,adjoin,join,resolve), each flow step (enter,place,close,exit,finishwith theBlockFactspredicates), andLineExtent::add.solve_block(panic-free, width ≥ 0),widths::min_max,shrink_to_fit, the height functions,half_leading(panic-free),align_offset,role, and the length arithmetic.Miri. Every test this item adds was run alone, one test per process, capped at 10 min, under the lock and never alongside Kani. All 37 passed. Times are on Miri's clock (
--report-time):golden_fragment_trees(case 0 only)vertical_aligntext_alignlast_child_and_parent_bottominline_blocks_shrink_to_fitmargins_collapse_through_an_empty_boxdeep_trees_lay_out_without_recursion(300 levels under Miri)Not done
overflowclipping (5.16); the WPT reftests (5.25).letter-spacingandword-spacing.Verification status
cargo xtask verify --changedwas not run locally, as instructed; nor wasscripts/verify.sh.cargo fmt --all -- --check;cargo clippy --workspace --all-targets --locked -- -D warnings;cargo test -p clazel-layout(all pass);cargo xtask check, whose last line isRESULT: STATIC CHECKS PASSED (no build, tests or proofs run; use cargo xtask verify);full-verificationapproval.docs/STATUS.mdand its SVGs,SPEC-REVIEWS.md,SYS-AUDITS.md,CLAUDE.mdandclazel-sysare untouched.🤖 Generated with Claude Code