You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[cssom-view-1] offsetParent spec says that we return elements from open shadow trees, no browser does. #12392
If ancestor is not closed-shadow-hidden from the element and satisfies at least one of the following, terminate this algorithm and return ancestor.
See https://jsbin.com/negusux/edit?html,js,output
In particular, I think the offsetParent of <DIV id="openInnerElement" class="target"> should be the .shadow-scroller element in the <open-component> if browsers were following the spec, however every browser returns the same <DIV id="outerScroller" class="scroller"> for both the open and closed shadow trees, skipping the shadow tree entirely.
I propose we update the spec to match what browsers do, skipping elements from inner shadow trees, for both offsetParent and the new scrollParent.
The CSS Working Group just discussed [cssom-view-1] offsetParent spec says that we return elements from open shadow trees, no browser does., and agreed to the following:
RESOLVED: Make offsetParent spec match reality
ACTION: flackr to open issue on making scrollParent a function
ACTION: dbaron to open an issue on replacements for offsetParent
The full IRC log of that discussion
<fantasai> scribe+
<lea> q?
<emilio> flackr: As I was implementing scrollParent I discovered that the spec for offsetParent claims we should expose elements within open shadow trees yet no impl does that
<lea> q+
<emilio> ... I'd like to resolve to change it to match implementations and do the same for scrollParent
<emilio> q+
<astearns> ack lea
<emilio> lea: is there a reason for what browsers do?
<lea> q+
<fantasai> emilio: implementation-wise it's the same, but I don't think any DOM API distinguishes between both
<fantasai> emilio: DOM event targetting etc. works the same in open vs closed shadow root
<masonf> +1
<fantasai> emilio: So I think it's best to not differentiate here either
<fantasai> emilio: for APIs where you might want to get things from shadow roots, we've added option to pass shadow roots to have access to
<fantasai> emilio: that way you can access both closed and open shadow roots depending on what you have access to
<emilio> lea: what do they actually return?
<astearns> ack lea
<emilio> ... do they return the host or do they skip that element?
<emilio> flackr: they skip to the shadow host but it might traverse further up if the shadow host doesn't meet the requirements
<emilio> lea: the current behavior seems more useful
<emilio> ... wondering if we could also add a corresponding property that does the right thing
<emilio> q+
<oriol> q+
<astearns> ack emilio
<astearns> ack oriol
<fantasai> emilio: Could add an argument to do it consistently in the DOM, but I don't think it should be specific to offsetParent APIs
<flackr> +1
<lea> s/lea: the current behavior seems more useful/lea: the current behavior seems more useful, but I also understand the web compat argument of speccing what browsers already do/
<emilio> oriol: I think scrollParent should be a function to allow eventual extensions?
<astearns> ack dbaron
<lea> +1 oriol
<emilio> dbaron: I think we should be looking at offset* as a legacy API
<emilio> ... I think the implementation of these existed well before the spec did
<emilio> ... in general we want to bias towards specifying what's implemented
<emilio> ... to some degree we have various APIs that are trying to replace them
<emilio> ... some of that is implemented like getBoundingClientRect and other pieces in the geometry spec?
<masonf> examples: innerHTML --> getHTML(), getRangeAt() --> getComposedRanges(), etc.
<emilio> ... not sure what the state of all of them are?
<lea> q?
<lea> q+
<emilio> ... I would not try and improve offset*
<emilio> ... I'd try and build the API we want more generally
<astearns> ack lea
<emilio> q+
<emilio> lea: I agree these are weird and fine to treat them as legacy
<emilio> ... but not sure what'd be the replacement
<emilio> ... is there an API that could replace them today?
<astearns> ack emilio
<fantasai> emilio: [missed]
<fantasai> emilio: The consistent thing to do is to not distinguish between open and closed shadow roots
<lea> many scripts were written before shadows were a thing and use these properties for positioning and ideally should not break too badly when dropped into a page that has shadow roots
<masonf> q+
<fantasai> emilio: We can decide to use a function for scoped parent or add a new function for passing list of shadow roots or whatever
<astearns> s/[missed]/yes these things were implemented before being specced, but shadow root came after the spec
<fantasai> emilio: but big +1 to spec what's implemented for offsetParent because it's the right thing to do
<astearns> ack masonf
<Kurt> +1 emilio
<fantasai> emilio: consistent with the way it works elsewhere in DOM
<lea> q?
<lea> q+
<emilio> masonf: I commented with some precedent on the DOM side (innerHTML / getHTML() / etc)
<astearns> ack lea
<emilio> ... not a technical issue, just a consistency argument
<emilio> lea: Fine to spec what's implemented, but we should work to close the gap because there's no way of doing what the spec says
<emilio> dbaron: yeah it'd be good to have some element-to-element coord space conversion
<emilio> PROPOSED: Fix offsetParent by spec-ing reality, but work into a way to opt into looking into shadow roots
<emilio> q+
<kbabbitt> +1
<lea> (though hopefully anchor positioning renders many of the use cases for these properties obsolete)
<masonf> +1
<lea> +1
<astearns> ack emilio
<fantasai> emilio: We should definitely update offsetParent.
<oriol> It's implemented in Blink and Servo
<fantasai> emilio: scrollParent is not implemented anywhere, so maybe we can make it functional already
<fantasai> flackr: We have an implementation, but not shipped yet
<fantasai> emilio: fair
<emilio> RESOLVED: Make offsetParent spec match reality
<dbaron> I think some of what I'm thinking of was for a time in a GeometryUtils interface in https://drafts.fxtf.org/geometry/#geometryutils
<emilio> astearns: if we make scrollParent a function we can allow passing a list of shadow roots
<emilio> flackr: I see
<emilio> astearns: we should file an issue for that
<fantasai> ACTION: flackr to open issue on making scrollParent a function
<emilio> astearns: we should look into whether appropriate replacements for offsetParent exist
<fantasai> ACTION: dbaron to open an issue on replacements for offsetParent
Activity
emilio commentedon Oct 1, 2025
Sounds good to me fwiw.
css-meeting-bot commentedon Oct 8, 2025
The CSS Working Group just discussed
[cssom-view-1] offsetParent spec says that we return elements from open shadow trees, no browser does., and agreed to the following:RESOLVED: Make offsetParent spec match realityACTION: flackr to open issue on making scrollParent a functionACTION: dbaron to open an issue on replacements for offsetParentThe full IRC log of that discussion
<fantasai> scribe+<lea> q?
<emilio> flackr: As I was implementing scrollParent I discovered that the spec for offsetParent claims we should expose elements within open shadow trees yet no impl does that
<lea> q+
<emilio> ... I'd like to resolve to change it to match implementations and do the same for scrollParent
<emilio> q+
<astearns> ack lea
<emilio> lea: is there a reason for what browsers do?
<lea> q+
<fantasai> emilio: implementation-wise it's the same, but I don't think any DOM API distinguishes between both
<fantasai> emilio: DOM event targetting etc. works the same in open vs closed shadow root
<masonf> +1
<fantasai> emilio: So I think it's best to not differentiate here either
<fantasai> emilio: for APIs where you might want to get things from shadow roots, we've added option to pass shadow roots to have access to
<fantasai> emilio: that way you can access both closed and open shadow roots depending on what you have access to
<emilio> lea: what do they actually return?
<astearns> ack lea
<emilio> ... do they return the host or do they skip that element?
<emilio> flackr: they skip to the shadow host but it might traverse further up if the shadow host doesn't meet the requirements
<emilio> lea: the current behavior seems more useful
<emilio> ... wondering if we could also add a corresponding property that does the right thing
<emilio> q+
<oriol> q+
<astearns> ack emilio
<astearns> ack oriol
<fantasai> emilio: Could add an argument to do it consistently in the DOM, but I don't think it should be specific to offsetParent APIs
<flackr> +1
<lea> s/lea: the current behavior seems more useful/lea: the current behavior seems more useful, but I also understand the web compat argument of speccing what browsers already do/
<emilio> oriol: I think scrollParent should be a function to allow eventual extensions?
<astearns> ack dbaron
<lea> +1 oriol
<emilio> dbaron: I think we should be looking at offset* as a legacy API
<emilio> ... I think the implementation of these existed well before the spec did
<emilio> ... in general we want to bias towards specifying what's implemented
<emilio> ... to some degree we have various APIs that are trying to replace them
<emilio> ... some of that is implemented like getBoundingClientRect and other pieces in the geometry spec?
<masonf> examples: innerHTML --> getHTML(), getRangeAt() --> getComposedRanges(), etc.
<emilio> ... not sure what the state of all of them are?
<lea> q?
<lea> q+
<emilio> ... I would not try and improve offset*
<emilio> ... I'd try and build the API we want more generally
<astearns> ack lea
<emilio> q+
<emilio> lea: I agree these are weird and fine to treat them as legacy
<emilio> ... but not sure what'd be the replacement
<emilio> ... is there an API that could replace them today?
<astearns> ack emilio
<fantasai> emilio: [missed]
<fantasai> emilio: The consistent thing to do is to not distinguish between open and closed shadow roots
<lea> many scripts were written before shadows were a thing and use these properties for positioning and ideally should not break too badly when dropped into a page that has shadow roots
<masonf> q+
<fantasai> emilio: We can decide to use a function for scoped parent or add a new function for passing list of shadow roots or whatever
<astearns> s/[missed]/yes these things were implemented before being specced, but shadow root came after the spec
<fantasai> emilio: but big +1 to spec what's implemented for offsetParent because it's the right thing to do
<astearns> ack masonf
<Kurt> +1 emilio
<fantasai> emilio: consistent with the way it works elsewhere in DOM
<lea> q?
<lea> q+
<emilio> masonf: I commented with some precedent on the DOM side (innerHTML / getHTML() / etc)
<astearns> ack lea
<emilio> ... not a technical issue, just a consistency argument
<emilio> lea: Fine to spec what's implemented, but we should work to close the gap because there's no way of doing what the spec says
<emilio> dbaron: yeah it'd be good to have some element-to-element coord space conversion
<emilio> PROPOSED: Fix offsetParent by spec-ing reality, but work into a way to opt into looking into shadow roots
<emilio> q+
<kbabbitt> +1
<lea> (though hopefully anchor positioning renders many of the use cases for these properties obsolete)
<masonf> +1
<lea> +1
<astearns> ack emilio
<fantasai> emilio: We should definitely update offsetParent.
<oriol> It's implemented in Blink and Servo
<fantasai> emilio: scrollParent is not implemented anywhere, so maybe we can make it functional already
<fantasai> flackr: We have an implementation, but not shipped yet
<fantasai> emilio: fair
<emilio> RESOLVED: Make offsetParent spec match reality
<dbaron> I think some of what I'm thinking of was for a time in a GeometryUtils interface in https://drafts.fxtf.org/geometry/#geometryutils
<emilio> astearns: if we make scrollParent a function we can allow passing a list of shadow roots
<emilio> flackr: I see
<emilio> astearns: we should file an issue for that
<fantasai> ACTION: flackr to open issue on making scrollParent a function
<emilio> astearns: we should look into whether appropriate replacements for offsetParent exist
<fantasai> ACTION: dbaron to open an issue on replacements for offsetParent
Loirooriol commentedon Feb 12, 2026
This was resolved in #12731 (comment)