render: let an overflowing inline-block wrap instead of running one line - #750
Open
alexskinner wants to merge 1 commit into
Open
render: let an overflowing inline-block wrap instead of running one line#750alexskinner wants to merge 1 commit into
alexskinner wants to merge 1 commit into
Conversation
An auto-width inline-block without block children is built as a NoWrap flex row so a short control shrink-fits to its max-content line. CSS shrink-to-fit is min(max-content, available), though: when that line is wider than the containing block the box must wrap internally. An inline-block <ul> of inline-block <li>s (Wikipedia's `.cslist`) instead ran as one ~1000px line, and inside an infobox cell that line became the table's min-content floor, pushing a `width:22em` table from 310px to 641px and squeezing the article text beside it to one character per line. Two changes: - After the preliminary layout, switch any such NoWrap inline-block whose margin box exceeds its parent's content box to Wrap and re-run Taffy, alongside the other post-layout repairs. - While measuring a table's (and each cell's) min-content width, treat those inline-blocks as Wrap so the floor reflects breakable content, then restore NoWrap for the max-content and final passes.
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 changed
Fixes #737.
An auto-width inline-block without in-flow block children is built as a
NoWrapflex row so that a short control shrink-fits to one max-content line (dom.rs, inline-block branch of the node builder). CSS shrink-to-fit ismin(max-content, available)though, and nothing enforced theavailablehalf: when the max-content line is wider than the containing block the box simply overflowed. Wikipedia's.cslist— aninline-block<ul>ofinline-block<li>s with::aftercommas — ran as one ~1000px line. Inside the infobox<td>that line became the table's min-content floor, so thewidth:22emtable laid out at 641px instead of 310px and the article text beside the float collapsed to a few characters per line.Two changes, both in
crates/obscura-render/src/dom.rs:wrap_overflowing_inline_blocks— a post-preliminary-layout repair in the same chain asrepair_intrinsic_column_flex_negative_margins: any suchNoWrapinline-block whose margin box exceeds its parent's content box is switched toWrap, and Taffy is re-run. Boxes that fit keep their single max-content line, so the two-word-button case theNoWrapapproximation exists for is unchanged.Wrapwhile measuring the table's and each cell's min-content width (nowrap_inline_block_rows/set_flex_wrap), then restoresNoWrapfor the max-content and final passes. Without this the table floor is computed before the repair can run.Validation
overflowing_inline_block_list_wraps_inside_its_containerintests/layout_test.rs: the list stays ≤352px and wraps onto several lines (was 1023px on one line).cargo test -p obscura-render --test layout_test: same 11 pre-existing failures asmainon this machine, +1 pass. Note that on this machinemainalready failstable_width_uses_local_space_and_keeps_width_hints_shrinkable(a<table style="width:300px">lays out at the viewport width in the unit harness), so I could not assert the table half of the fix in the harness; it is validated end-to-end below.https://en.wikipedia.org/wiki/Rust_(programming_language)at 1280×900:.infobox641px → 310px. Chrome on the same page/viewport:309.76px(22emat the infobox's 14.08px computed font-size — the 352px figure in the issue assumed a 16px root). Article text flows normally beside the float.ul/liwith and without::after;inlineli;div/spanequivalents; the same list inside awidth:352pxtable (was 1000px).Rendering
Layout only. Fixture, viewport 1280×900, DSF 1:
Before:
ul1023×20 (one line, overflowing), table 1000px. After:ul352×74, table 352px.Performance
The repair pass is one
id_mapscan plus a style read per node, and triggers a relayout only when an overflowing inline-block exists (previously a mis-rendered page). The table path adds twoset_stylesweeps over the inline-block set per min-content measurement; that set is usually empty or tiny. No hot-path change otherwise.Checklist
main.)