render: z-index paint layers and clear ending float zones

Paint order was pure tree order, so a dropdown/overlay declared before a
later sibling lost to it and a z:-1 decorative backdrop covered its own
content. A positioned element with a non-zero z-index now lifts its
whole subtree into a separate paint layer: negative layers under the
normal flow, positive above it, each sorted ascending with tree order
preserved within equal z. Nested z roots paint inside their ancestor
root's subtree in tree order, the pragmatic core of CSS stacking
contexts.

clear (left/right/both, previously unparsed) now ends the float zone,
so a clearfix element drops below the float at full width instead of
joining the flow column beside it.

Repro-verified: an earlier z:10 overlay paints over a later sibling, a
later z:-1 backdrop paints under earlier content, and the clear repro
matches Chromium within 3px on every measure. Spot set unchanged or
slightly improved; obstacle course 33/33.
This commit is contained in:
SGavrl committed 2026-07-16 13:10:28 +00:00
1 parent 953292563d
commit 22f33e4dec
4 files changed
+93 -2

No files matched your search

+14
View File
@@ -442,6 +442,20 @@ fn apply_value(style: &mut LayoutStyle, name: &str, value: &str) {
}
"visibility" => style.visibility_hidden = Some(value.eq_ignore_ascii_case("hidden")),
"opacity" => style.opacity = value.trim().parse::<f32>().ok(),
"z-index" => {
style.z_index = match value.trim() {
"auto" | "inherit" | "initial" => None,
v => v.parse::<i32>().ok(),
};
}
"clear" => {
style.clear = match value.trim().to_ascii_lowercase().as_str() {
"left" | "inline-start" => Some(crate::Clear::Left),
"right" | "inline-end" => Some(crate::Clear::Right),
"both" => Some(crate::Clear::Both),
_ => None,
};
}
"vertical-align" => {
style.vertical_align = match value.trim().to_ascii_lowercase().as_str() {
"top" | "baseline" | "text-top" => Some(crate::VerticalAlign::Top),