aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Rees <mrees@noeontheend.com>2025-04-03 12:30:42 -0500
committerGitHub <noreply@github.com>2025-04-03 17:30:42 +0000
commitdfcd9de138ece3c7999c76cd9ba1d170c27af97b (patch)
tree7a7f3a77a96630d0b0629cc81648cec837d1c346
parentf29c18292908f1cea00505341f4611f07ef0276b (diff)
downloadservo-dfcd9de138ece3c7999c76cd9ba1d170c27af97b.tar.gz
servo-dfcd9de138ece3c7999c76cd9ba1d170c27af97b.zip
fix: root element not establishing stacking context (#35390) (#36174)
- [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #35390 - [X] There are tests for these changes [Successful WPT run](https://github.com/reesmichael1/servo/actions/runs/14097679625) (which includes the new test files) (I didn't make the formatting changes intentionally--those came from `mach format` following `mach test-tidy`.) --------- Signed-off-by: Michael Rees <mrees@noeontheend.com>
-rw-r--r--components/layout_2020/dom_traversal.rs5
-rw-r--r--components/layout_2020/fragment_tree/base_fragment.rs2
-rw-r--r--components/layout_2020/style_ext.rs6
-rw-r--r--components/script/layout_dom/element.rs4
-rw-r--r--components/shared/script_layout/wrapper_traits.rs6
-rw-r--r--tests/wpt/meta/MANIFEST.json17
-rw-r--r--tests/wpt/tests/css/CSS2/stacking-context/root-element-creates-stacking-context-ref.html4
-rw-r--r--tests/wpt/tests/css/CSS2/stacking-context/root-element-creates-stacking-context.html9
8 files changed, 53 insertions, 0 deletions
diff --git a/components/layout_2020/dom_traversal.rs b/components/layout_2020/dom_traversal.rs
index 33e500bfe87..bcb6555fd13 100644
--- a/components/layout_2020/dom_traversal.rs
+++ b/components/layout_2020/dom_traversal.rs
@@ -105,6 +105,7 @@ where
if element.is_body_element_of_html_element_root() {
flags.insert(FragmentFlags::IS_BODY_ELEMENT_OF_HTML_ELEMENT_ROOT);
}
+
match element.get_local_name() {
&local_name!("br") => {
flags.insert(FragmentFlags::IS_BR_ELEMENT);
@@ -123,6 +124,10 @@ where
) {
flags.insert(FragmentFlags::IS_TEXT_CONTROL);
}
+
+ if ThreadSafeLayoutElement::is_root(&element) {
+ flags.insert(FragmentFlags::IS_ROOT_ELEMENT);
+ }
};
Self {
diff --git a/components/layout_2020/fragment_tree/base_fragment.rs b/components/layout_2020/fragment_tree/base_fragment.rs
index 8e529f40ba6..d26ae71264f 100644
--- a/components/layout_2020/fragment_tree/base_fragment.rs
+++ b/components/layout_2020/fragment_tree/base_fragment.rs
@@ -102,6 +102,8 @@ bitflags! {
/// and the fragment can be a flex item. This flag is used to cache items during flex
/// layout.
const SIZE_DEPENDS_ON_BLOCK_CONSTRAINTS_AND_CAN_BE_CHILD_OF_FLEX_ITEM = 1 << 8;
+ /// Whether or not the node that created this fragment is the root element.
+ const IS_ROOT_ELEMENT = 1 << 9;
}
}
diff --git a/components/layout_2020/style_ext.rs b/components/layout_2020/style_ext.rs
index 4a8d15b9fd3..f3269fb5461 100644
--- a/components/layout_2020/style_ext.rs
+++ b/components/layout_2020/style_ext.rs
@@ -746,6 +746,12 @@ impl ComputedValuesExt for ComputedValues {
return true;
}
+ // From https://www.w3.org/TR/CSS22/visuren.html#z-index:
+ // > The root element forms the root stacking context.
+ if fragment_flags.contains(FragmentFlags::IS_ROOT_ELEMENT) {
+ return true;
+ }
+
// TODO: We need to handle CSS Contain here.
false
}
diff --git a/components/script/layout_dom/element.rs b/components/script/layout_dom/element.rs
index 6a267f16077..85c04039323 100644
--- a/components/script/layout_dom/element.rs
+++ b/components/script/layout_dom/element.rs
@@ -868,6 +868,10 @@ impl<'dom> ThreadSafeLayoutElement<'dom> for ServoThreadSafeLayoutElement<'dom>
fn is_body_element_of_html_element_root(&self) -> bool {
self.element.is_html_document_body_element()
}
+
+ fn is_root(&self) -> bool {
+ self.element.is_root()
+ }
}
/// This implementation of `::selectors::Element` is used for implementing lazy
diff --git a/components/shared/script_layout/wrapper_traits.rs b/components/shared/script_layout/wrapper_traits.rs
index f64ec94a777..3e021052280 100644
--- a/components/shared/script_layout/wrapper_traits.rs
+++ b/components/shared/script_layout/wrapper_traits.rs
@@ -390,4 +390,10 @@ pub trait ThreadSafeLayoutElement<'dom>:
/// of the parent data is fine, since the bottom-up traversal will not process
/// the parent until all the children have been processed.
fn is_body_element_of_html_element_root(&self) -> bool;
+
+ /// Returns whether this node is the root element in an HTML document element.
+ ///
+ /// Note that, like `Self::is_body_element_of_html_element_root`, this accesses the parent.
+ /// As in that case, since this is an immutable borrow, we do not violate thread safety.
+ fn is_root(&self) -> bool;
}
diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json
index 5798aa29c28..70903a3077a 100644
--- a/tests/wpt/meta/MANIFEST.json
+++ b/tests/wpt/meta/MANIFEST.json
@@ -102180,6 +102180,19 @@
{}
]
],
+ "root-element-creates-stacking-context.html": [
+ "be7b027ee791d8d83d6fcecae60654eb22ff960c",
+ [
+ null,
+ [
+ [
+ "/css/CSS2/stacking-context/root-element-creates-stacking-context-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"zindex-affects-block-in-inline.html": [
"5a5c9e3dcca6171910f85790e13dc754acda58e0",
[
@@ -405642,6 +405655,10 @@
"65138c9a66713e1ed8c2f649751deb1ceb22eac3",
[]
],
+ "root-element-creates-stacking-context-ref.html": [
+ "9bb42041498c4a5b2b86e6b282ec49e603a0880b",
+ []
+ ],
"zindex-affects-block-in-inline-ref.html": [
"c0fdb338d08198cfd058ccdabd7766a9e57375fd",
[]
diff --git a/tests/wpt/tests/css/CSS2/stacking-context/root-element-creates-stacking-context-ref.html b/tests/wpt/tests/css/CSS2/stacking-context/root-element-creates-stacking-context-ref.html
new file mode 100644
index 00000000000..9bb42041498
--- /dev/null
+++ b/tests/wpt/tests/css/CSS2/stacking-context/root-element-creates-stacking-context-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<body style="width: 100px; margin: 0">
+ <div style="height: 100px; background: green"></div>
+</body>
diff --git a/tests/wpt/tests/css/CSS2/stacking-context/root-element-creates-stacking-context.html b/tests/wpt/tests/css/CSS2/stacking-context/root-element-creates-stacking-context.html
new file mode 100644
index 00000000000..be7b027ee79
--- /dev/null
+++ b/tests/wpt/tests/css/CSS2/stacking-context/root-element-creates-stacking-context.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html style="width: 0; height: 0; border: 50px solid red">
+ <link rel="help" href="https://drafts.csswg.org/css2/#stacking-context">
+ <link rel="match" href="root-element-creates-stacking-context-ref.html">
+ <link rel="author" title="Michael Rees" href="mailto:mrees@noeontheend.com">
+ <meta name="assert" content="root element forms the root stacking context">
+ <body style="border: 50px solid green; margin: -50px; position: relative; z-index: -1">
+ </body>
+</html>