Skip to content

[css-anchor-position-1] Accommodate pseudo-elements when sorting anchor elements by tree order#61306

Open
tuankiet65 wants to merge 1 commit intoWebKit:mainfrom
tuankiet65:eng/css-anchor-position-1-Accommodate-pseudo-elements-when-sorting-anchor-elements-by-tree-order
Open

[css-anchor-position-1] Accommodate pseudo-elements when sorting anchor elements by tree order#61306
tuankiet65 wants to merge 1 commit intoWebKit:mainfrom
tuankiet65:eng/css-anchor-position-1-Accommodate-pseudo-elements-when-sorting-anchor-elements-by-tree-order

Conversation

@tuankiet65
Copy link
Member

@tuankiet65 tuankiet65 commented Mar 25, 2026

24688fe

[css-anchor-position-1] Accommodate pseudo-elements when sorting anchor elements by tree order
rdar://173032203
https://bugs.webkit.org/show_bug.cgi?id=310398

Reviewed by NOBODY (OOPS!).

When determining which element is the anchor, the last element in tree order that satistifes
the anchor query wins [1]:

> If an ancestor of query el satisfies the following conditions, return the nearest such element
> to query el. Otherwise, return the last element el in tree order that satisfies the conditions.

WebKit implemented this by sorting anchors with the same anchor name in reverse tree order,
using treeOrder<ComposedTree> to determine the order. But treeOrder doesn't work with
pseudo-elements (e.g ::before, ::after). Fix this by re-writing the sort comparison logic
to handle pseudo-elements:

* If two elements aren't pseudo-elements, use treeOrder as usual
* If one is, and the other isn't, the order is the order between the pseudo-element's host and the non-pseudo element
* If both are pseudo-elements of different hosts: the order is their host elements' order
* Otherwise, both are pseudo-elements of the same host, and ::before is before ::after

[1]: https://drafts.csswg.org/css-anchor-position-1/#target

Tests: imported/w3c/web-platform-tests/css/css-anchor-position/anchor-function-chain-pseudo-elements.html
       imported/w3c/web-platform-tests/css/css-anchor-position/anchor-size-function-chain-pseudo-elements.html
       imported/w3c/web-platform-tests/css/css-anchor-position/position-area-chain-pseudo-elements.html
       imported/w3c/web-platform-tests/css/css-anchor-position/pseudo-element-anchor-tree-order.html

* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchor-function-chain-pseudo-elements-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchor-function-chain-pseudo-elements.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchor-size-function-chain-pseudo-elements-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchor-size-function-chain-pseudo-elements-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchor-size-function-chain-pseudo-elements.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/position-area-chain-pseudo-elements-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/position-area-chain-pseudo-elements.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/pseudo-element-anchor-tree-order-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/pseudo-element-anchor-tree-order.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/reference/pseudo-element-chain-ref.html: Added.
* Source/WebCore/style/AnchorPositionEvaluator.cpp:
(WebCore::Style::orderInComposedTreeAccountingForPseudoElements):
(WebCore::Style::collectAnchorsForAnchorName):

24688fe

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows Apple Internal
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 win ⏳ 🛠 ios-apple
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ✅ 🧪 win-tests ⏳ 🛠 mac-apple
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe ⏳ 🛠 vision-apple
✅ 🧪 ios-wk2-wpt ✅ 🧪 api-mac-debug ✅ 🛠 gtk3-libwebrtc
✅ 🧪 api-ios ✅ 🧪 mac-wk1 ✅ 🛠 gtk
✅ 🛠 ios-safer-cpp ✅ 🧪 mac-wk2 ✅ 🧪 gtk-wk2
✅ 🛠 vision ✅ 🧪 mac-AS-debug-wk2 ✅ 🧪 api-gtk
✅ 🛠 vision-sim ✅ 🧪 mac-wk2-stress ✅ 🛠 playstation
✅ 🧪 vision-wk2 ✅ 🧪 mac-intel-wk2
✅ 🛠 tv ✅ 🛠 mac-safer-cpp
✅ 🛠 tv-sim
✅ 🛠 watch
✅ 🛠 watch-sim

…or elements by tree order

rdar://173032203
https://bugs.webkit.org/show_bug.cgi?id=310398

Reviewed by NOBODY (OOPS!).

When determining which element is the anchor, the last element in tree order that satistifes
the anchor query wins [1]:

> If an ancestor of query el satisfies the following conditions, return the nearest such element
> to query el. Otherwise, return the last element el in tree order that satisfies the conditions.

WebKit implemented this by sorting anchors with the same anchor name in reverse tree order,
using treeOrder<ComposedTree> to determine the order. But treeOrder doesn't work with
pseudo-elements (e.g ::before, ::after). Fix this by re-writing the sort comparison logic
to handle pseudo-elements:

* If two elements aren't pseudo-elements, use treeOrder as usual
* If one is, and the other isn't, the order is the order between the pseudo-element's host and the non-pseudo element
* If both are pseudo-elements of different hosts: the order is their host elements' order
* Otherwise, both are pseudo-elements of the same host, and ::before is before ::after

[1]: https://drafts.csswg.org/css-anchor-position-1/#target

Tests: imported/w3c/web-platform-tests/css/css-anchor-position/anchor-function-chain-pseudo-elements.html
       imported/w3c/web-platform-tests/css/css-anchor-position/anchor-size-function-chain-pseudo-elements.html
       imported/w3c/web-platform-tests/css/css-anchor-position/position-area-chain-pseudo-elements.html
       imported/w3c/web-platform-tests/css/css-anchor-position/pseudo-element-anchor-tree-order.html

* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchor-function-chain-pseudo-elements-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchor-function-chain-pseudo-elements.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchor-size-function-chain-pseudo-elements-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchor-size-function-chain-pseudo-elements-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/anchor-size-function-chain-pseudo-elements.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/position-area-chain-pseudo-elements-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/position-area-chain-pseudo-elements.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/pseudo-element-anchor-tree-order-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/pseudo-element-anchor-tree-order.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-anchor-position/reference/pseudo-element-chain-ref.html: Added.
* Source/WebCore/style/AnchorPositionEvaluator.cpp:
(WebCore::Style::orderInComposedTreeAccountingForPseudoElements):
(WebCore::Style::collectAnchorsForAnchorName):
@tuankiet65 tuankiet65 self-assigned this Mar 25, 2026
@tuankiet65 tuankiet65 added the Layout and Rendering For bugs with layout and rendering of Web pages. label Mar 25, 2026
@tuankiet65 tuankiet65 requested a review from anttijk March 25, 2026 05:13
@@ -1217,6 +1217,63 @@ static RefPtr<Element> findLastAcceptableAnchorWithName(ResolvedScopedName ancho
return { };
}

static std::partial_ordering orderInComposedTreeAccountingForPseudoElements(const Element& a, const Element& b)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sorting logic in WebAnimationUtilities.cpp follows the defined ordering in the CSS animation spec, while the anchor spec just says "in tree order" without specifying the order of pseudo-elements. I can certainly try to consolidate them, but that would imply that CSS animations and anchor element use the same ordering (are they?) Maybe this is worth raising an issue to CSSWG?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Layout and Rendering For bugs with layout and rendering of Web pages.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants