Skip to content

Add .pseudoTarget property to selected event types#413

Open
danielsakhapov wants to merge 13 commits intow3c:mainfrom
danielsakhapov:spec_edit_for_css_12163
Open

Add .pseudoTarget property to selected event types#413
danielsakhapov wants to merge 13 commits intow3c:mainfrom
danielsakhapov:spec_edit_for_css_12163

Conversation

@danielsakhapov
Copy link

As resolved in w3c/csswg-drafts#12163, add .pseudoTarget property to selected event types and describe the initialization process for it.

@danielsakhapov
Copy link
Author

@garykac could you ptal?

@danielsakhapov danielsakhapov requested a review from dbaron February 3, 2026 19:46
@danielsakhapov danielsakhapov requested a review from dbaron February 5, 2026 11:35

<p class="note">
This {{CSSPseudoElement}} must be the same object instance that would be returned
by calling <code>.pseudo(type)</code> on the |pseudoElement|'s originating element
Copy link

@smaug---- smaug---- Feb 9, 2026

Choose a reason for hiding this comment

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

What is .pseudo(type) ?
I guess this.

Copy link
Author

Choose a reason for hiding this comment

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

Updated this part to include links

</p>

1. Set |event|'s <code>pseudoTarget</code> attribute to |pseudoInstance|

Choose a reason for hiding this comment

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

Are there tests for this (and for pseudo(type))? In this event case there should be tests ensuring that event.pseudoTarget doesn't change even if the event.target is moved to a different place in DOM, or get different styling during event dispatch.

Copy link
Author

Choose a reason for hiding this comment

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

There is https://wpt.fyi/results/css/css-pseudo/events-on-pseudo-element.tentative.html, but I'll definetly going to add more tests, once I merge this spec edit.

Do you ask this to add those tests to the spec here?

Choose a reason for hiding this comment

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

just asking if there are tests for this proposed API change. Those need some reviewing too. But sounds like there will be, but there aren't yet.

Copy link

@smaug---- smaug---- left a comment

Choose a reason for hiding this comment

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

This doesn't seem to handle event dispatch in Shadow DOM. We don't want to leak pseudo element usage in shadow DOM to light DOM.

@danielsakhapov
Copy link
Author

This doesn't seem to handle event dispatch in Shadow DOM. We don't want to leak pseudo element usage in shadow DOM to light DOM.

Not entirely sure how to phrase that, ptal!


1. Let |ultimateOriginatingElement| be the |pseudoElement|'s [=ultimate originating element=].

1. If |ultimateOriginatingElement| is in a shadow tree (that is, its [=tree/root=] is a {{ShadowRoot}}) and |eventTarget| is not contained within the same shadow tree, then exit.

Choose a reason for hiding this comment

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

I would expect that "ultimateOriginatingElement" (maybe we can find some other name for that ;) ) would be compared to the currentTarget and then the getter of pseudoElement would either return the object or null. Something similar-ish to https://html.spec.whatwg.org/#dom-commandevent-source perhaps?

Copy link
Author

Choose a reason for hiding this comment

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

Updated

@smaug----
Copy link

Just FYI, there is now a rather major refactoring happening to UI Events spec, so this one might need to wait until w3c/pointerevents#564 and related PRs are done. Those should happen real soon.

@danielsakhapov
Copy link
Author

Just FYI, there is now a rather major refactoring happening to UI Events spec, so this one might need to wait until w3c/pointerevents#564 and related PRs are done. Those should happen real soon.

I see, thanks for the heads up!

Does this PR look good now btw?

1. If {{UIEvent/pseudoTarget}} internal slot is <code>null</code>, then return <code>null</code>.
1. Let |currentTarget| be {{Event/currentTarget}}.
1. If |currentTarget| is <code>null</code>, then return <code>null</code>.
1. Let |origin| be {{Event/target}} (which would be {{UIEvent/pseudoTarget}}'s [=ultimate originating element=]).

Choose a reason for hiding this comment

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

"ultimate originating element" sounds a bit, hmm, comical :)

Copy link
Author

Choose a reason for hiding this comment

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

true... but since there can be nested pseudo-elements, the originating element can be also pseudo-element, so ultimate originating element is Element... that's an established CSS term! :)

constructor(DOMString type, optional UIEventInit eventInitDict = {});
readonly attribute Window? view;
readonly attribute long detail;
readonly attribute CSSPseudoElement? pseudoTarget;

Choose a reason for hiding this comment

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

Hmm, actually, why are we adding pseudoTarget to UIEvent? Which all events this will be used with?

I'm just pondering if this could be in MouseEvent

Copy link
Author

Choose a reason for hiding this comment

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

I initially added it only to selected list of events, but David suggested to put it on UIEvent.
But your comment made me realize I didn't include a note saying that mouse boundary events are disabled for .pseudoTarget! Which I was sure I added... Coming with a fix now

Copy link
Author

Choose a reason for hiding this comment

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

Added a note, including pointer events to prepare for future MEGAMERGE

<h3 id="pseudo-element-event-dispatch">Pseudo-Element Event Dispatch</h3>

When the target of a user interaction is a [=pseudo-element=], the
{{UIEvent/pseudoTarget}} attribute is set to identify the specific pseudo-element involved.

Choose a reason for hiding this comment

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

Is this stuff supposed to work with click events? If so, how? Click events are dispatched to the common ancestor, so the pseudo-element on which mouse/pointerup happens might have nothing to do with the target of the click.

Copy link
Author

Choose a reason for hiding this comment

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

Yeah, so the same way as for elements? If both ends of a click happen on a pseudo-element, it goes into .pseudoTarget, if no, then a common ancestor determines that "the target of a user interaction is not a [=pseudo-element=]" and .pseudoTarget is null?

@danielsakhapov danielsakhapov force-pushed the spec_edit_for_css_12163 branch from e0b6dac to c4c7e79 Compare February 24, 2026 13:44
@danielsakhapov
Copy link
Author

The blocking PR has been merged now it seems, ptal

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants