script: Return None for offsetParent on root <html> and all <body> elements (#39397)

We were returning null for all `<html>` elements, but now we will check
for the root element instead.

We were also returning null for "the body element", now we will return
null for all `<body>` elements even if they aren't "the body element".
This part diverges from the spec, but matches what all browsers do.
https://github.com/w3c/csswg-drafts/issues/12834

Testing: Adding new test
Fixes: #10521

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Oriol Brufau 2025-09-19 21:38:12 +02:00 committed by GitHub
parent c017420ee7
commit 994d767ae5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 55 additions and 1 deletions

View file

@ -462,7 +462,7 @@ impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
/// <https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetparent> /// <https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetparent>
fn GetOffsetParent(&self) -> Option<DomRoot<Element>> { fn GetOffsetParent(&self) -> Option<DomRoot<Element>> {
if self.is_body_element() || self.is::<HTMLHtmlElement>() { if self.is::<HTMLBodyElement>() || self.upcast::<Element>().is_root() {
return None; return None;
} }

View file

@ -631326,6 +631326,13 @@
{} {}
] ]
], ],
"offsetParent-body-and-html.html": [
"ed83b317088c01e6ff23025b12f20a0144f897ed",
[
null,
{}
]
],
"offsetParent-fixed.html": [ "offsetParent-fixed.html": [
"a2c4255a77729066fedc1ba21101cb123a396380", "a2c4255a77729066fedc1ba21101cb123a396380",
[ [

View file

@ -0,0 +1,47 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSSOM View: offsetParent</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://drafts.csswg.org/cssom-view-1/#dom-htmlelement-offsetparent">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/12834">
<meta name="assert" content="Checks offsetParent on <body> and <html> elements.">
<style>html, body { position: relative }</style>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
const root = document.documentElement;
const other_html = document.createElement("html");
const other_body_1 = document.createElement("body");
const other_body_2 = document.createElement("body");
const other_body_3 = document.createElement("body");
other_body_2.append(other_body_3);
other_html.append(other_body_2);
root.append(other_html, other_body_1);
test(() => {
assert_equals(root.offsetParent, null);
}, "The offsetParent of the root element is null");
test(() => {
assert_equals(other_html.offsetParent, root);
}, "The offsetParent of a <html> element which is not the root is computed normally");
test(() => {
assert_equals(document.body.offsetParent, null);
}, "The offsetParent of 'the body element' is null");
test(() => {
assert_equals(other_body_1.offsetParent, null);
}, "The offsetParent of a <body> element which has a previous <body> sibling is also null");
test(() => {
assert_equals(other_body_2.offsetParent, null);
}, "The offsetParent of a <body> element which is a child of a non-root <html> is also null");
test(() => {
assert_equals(other_body_3.offsetParent, null);
}, "The offsetParent of a <body> element which is a child of a non-<html> is also null");
</script>
</body>