diff options
author | Michael Rees <mrees@noeontheend.com> | 2025-04-03 12:30:42 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-03 17:30:42 +0000 |
commit | dfcd9de138ece3c7999c76cd9ba1d170c27af97b (patch) | |
tree | 7a7f3a77a96630d0b0629cc81648cec837d1c346 | |
parent | f29c18292908f1cea00505341f4611f07ef0276b (diff) | |
download | servo-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>
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> |