fix(layout): preserve intrinsic width keywords across inline formatting roles

Subtract horizontal margins for explicit inline-block fit-content widths and carry float min/max-content constraints across the IFC boundary. Cover six font-backed role/keyword combinations, including an inline break that exercises the float path.

Validation: cargo fmt --all; cargo clippy --workspace --all-targets --all-features -- -D warnings; cargo nextest run --no-fail-fast (20284 passed, 18 skipped). The combined working tree passed these checks before this logical split. Frozen Release and focused browser/WPT validation also passed; final full WPT is running.

Original-commit: 00cfb54b45
This commit is contained in:
ldm0
2026-10-21 17:55:02 +08:00
committed by Donough Liu
parent a1965aa9ae
commit 87e044db18
3 changed files with 42 additions and 2 deletions
+1 -1
View File
@@ -81,7 +81,7 @@ where
let preferred_width = layout_box.style.taffy.size.width;
let is_replaced = layout_box.is_replaced();
let uses_fit_content = !layout_box.is_replaced()
&& layout_box.style.taffy.size.width.is_auto()
&& (preferred_width.is_auto() || preferred_width.is_fit_content())
&& matches!(
layout_box.style.display(),
LayoutDisplay::InlineBlock
+11 -1
View File
@@ -2915,10 +2915,20 @@ where
// All floats receive the space remaining after horizontal
// margins, matching Taffy's block-float parent. Replaced
// measurement carries this ownership explicitly.
let available_width = if style.size.width.is_min_content() {
AvailableSpace::MinContent
} else if style.size.width.is_max_content() {
AvailableSpace::MaxContent
} else {
child_inputs
.available_space
.width
.maybe_sub(margin.left + margin.right)
};
let layout_inputs = LayoutInput {
available_space: child_inputs
.available_space
.map_width(|width| width.maybe_sub(margin.left + margin.right)),
.map_width(|_| available_width),
..child_inputs
};
let output = self.compute_child_layout(child.to_taffy(), layout_inputs);
@@ -184,3 +184,33 @@ fn flex_percentage_padding_keeps_the_text_content_width_before_line_breaking() -
}
Ok(())
}
#[test]
fn intrinsic_width_keywords_keep_margin_space_for_float_and_inline_roles() -> Result<()> {
let mut body = String::new();
for role in ["float", "inline"] {
for (keyword, _) in [
("min-content", 46.0),
("fit-content", 70.0),
("max-content", 94.0),
] {
let display = if role == "float" {
"float:left"
} else {
"display:inline-block"
};
body.push_str(&format!("<section style='width:80px;height:100px'><div id='{role}-{keyword}' style='{display};width:{keyword};margin:5px;padding:2px;border:3px solid'>aaa bbb</div><br></section>"));
}
}
let value = run_layout(&probe_font_document(&body), GEOMETRY, true)?;
for role in ["float", "inline"] {
for (keyword, width) in [
("min-content", 46.0),
("fit-content", 70.0),
("max-content", 94.0),
] {
assert_dimension(&value, &format!("{role}-{keyword}"), "width", width);
}
}
Ok(())
}