Honor auto-height reset keywords in stripe detection

Treat initial and unset as auto for non-inherited height in both absolute and flex stripe detection. Cover keyword casing and keep definite-height tiles excluded.

AI-assisted by Codex at the request of maintainer pbakaus.
This commit is contained in:
Paul Bakaus
2026-09-21 11:38:21 -07:00
parent e940f019d8
commit abc7785b40
2 changed files with 19 additions and 6 deletions
+5 -6
View File
@@ -496,17 +496,18 @@ pub fn check_element_stripe_child(el: &StaticElement<'_>, style: &StyleValues) -
let width = css_length_to_px(sv(style, "width")).unwrap_or_else(|| pf0(sv(style, "width")));
let position = js::to_lower_case(sv(style, "position"));
let height_raw = js::to_lower_case(sv(style, "height"));
// Height is not inherited, so initial and unset both reset it to auto.
let auto_height = matches!(height_raw.as_str(), "" | "auto" | "initial" | "unset");
let host_style = host.style();
let edge = if position == "absolute" || position == "fixed" {
let height_raw = sv(style, "height");
// The cascade already expands inset; a winning `auto` longhand
// must not be overwritten by the earlier shorthand.
let inset = ["top", "right", "bottom", "left"].map(|prop| sv(style, prop));
// Opposing insets stretch only an auto-height box. With a definite
// height CSS drops the bottom constraint instead of stretching it.
let height_stretches = height_raw == "100%"
|| ((height_raw.is_empty() || height_raw == "auto")
&& static_edge_hugs(&inset[0]) && static_edge_hugs(&inset[2]));
|| (auto_height && static_edge_hugs(&inset[0]) && static_edge_hugs(&inset[2]));
if !height_stretches {
return Vec::new();
}
@@ -535,9 +536,7 @@ pub fn check_element_stripe_child(el: &StaticElement<'_>, style: &StyleValues) -
let is_stretch = effective_align.is_empty()
|| effective_align == "stretch"
|| effective_align == "normal";
let height_raw = sv(style, "height");
let height_stretches =
height_raw == "100%" || ((height_raw.is_empty() || height_raw == "auto") && is_stretch);
let height_stretches = height_raw == "100%" || (auto_height && is_stretch);
if !height_stretches {
return Vec::new();
}
+14
View File
@@ -74,6 +74,20 @@ fn absolute_definite_height_does_not_stretch_between_insets() {
}
}
#[test]
fn auto_height_keywords_stretch_between_insets_and_in_flex_rows() {
for height in ["auto", "initial", "unset", "INITIAL", "UNSET"] {
for layout in ["position:absolute;left:0;top:0;bottom:0;", ""] {
let html = format!(r#"<html><body><div style="position:relative;display:flex;width:320px;height:100px">
<span style="{layout}width:4px;height:{height};background:#3b82f6"></span><div>Content</div>
</div></body></html>"#);
let hits = side_tab_snippets(&html);
assert_eq!(hits.len(), 1, "height {height}, layout {layout}: {hits:?}");
assert!(hits[0].contains("stripe child (left)"));
}
}
}
#[test]
fn interactive_host_stripes_keep_the_border_rule_exemptions() {
for tag in ["a", "button"] {