Description
Full context: https://github.com/danielsakhapov/CSSPseudoElementDoc?tab=readme-ov-file#41-addeventlistener-on-a-proxyhandle
Description:
Given that the CSSPseudoElement object acts as a persistent handle, attaching an event listener via addEventListener raises further questions.
- What does it mean to listen for an event on a handle when the actual pseudo element might not be currently rendered (e.g., due to display: none)?
- Should the listener only become active when the pseudo element is actually rendered?
- How does this interact with the retargeting behavior?
- If event.target remains the Element, how does a listener on the CSSPseudoElement get invoked?
- Does it require a special dispatch phase?
This would require some heavy discussions, as it’s already known that authors want to be able to count clicks on ::scroll-marker pseudo elements for analytics purposes.
Potential solutions on example of ::scroll-marker
:
- No direct listening on pseudo element (Status Quo):
- Description: Do not allow
addEventListener('click',...)
directly on theCSSPseudoElement
for::scroll-marker
. Clicks physically hitting the marker would continue to dispatch withevent.target
set to the originatingElement
. Developers would have to attach the listener to theElement
and use coordinate-based hit-testing within that listener to infer if the click landed on the marker area. - Pros:
- Requires no changes to the event dispatch model.
- Zero web compatibility risk regarding
event.target
.
- Cons:
- Very poor developer ergonomics for this specific use case. Calculating marker positions and sizes to perform manual hit-testing is complex, brittle (breaks with style changes), and potentially slow.
- Makes the
CSSPseudoElement
object less useful and doesn't leverage itsEventTarget
inheritance.
- Description: Do not allow
- Allow direct listening with special dispatch phase:
- Description: Allow developers to call
scrollMarkerPseudoElement.addEventListener('click', counterFunction)
. When a click physically occurs on the scroll marker:- Special Phase: The browser's event system identifies the hit target as the
::scroll-marker
and invokescounterFunction
(and any other listeners attached directly to this specificCSSPseudoElement
handle). - Standard Phase: The event dispatch continues as normal, but crucially,
event.target
is set to the originating scrollableElement
. The event then proceeds through the capture and bubble phases relative to theElement
, without re-invokingcounterFunction
during this standard flow.
- Special Phase: The browser's event system identifies the hit target as the
- Pros:
- Directly addresses the developer need: allows attaching listeners specifically to the pseudo-element of interest.
- Preserves web compatibility by ensuring
event.target
remains theElement
during the standard, observable event flow. - Provides a meaningful use for the
EventTarget
inheritance onCSSPseudoElement
. - Much better developer ergonomics than manual coordinate checking.
- Cons:
- Requires implementing the modified event dispatch logic (the "special phase").
- The event model becomes slightly more complex internally, though the developer-facing API (
addEventListener
on the pseudo) is intuitive.
- Description: Allow developers to call
- Introduce a new specific event type:
- Description: Instead of using the standard
click
event, define a new event type likepseudoElementClick
that only fires on theCSSPseudoElement
handle for pseudo elements. Standardclick
events would continue to target theElement
only. - Pros:
- Avoids any ambiguity or modification related to the standard
click
event dispatch. - Clearly separates the interaction.
- Avoids any ambiguity or modification related to the standard
- Cons:
- Introduces a new event type for a very specific interaction, potentially leading to event type proliferation.
- Developers might intuitively try to listen for
click
first and be confused why it doesn't work directly on the pseudo-element handle without the special dispatch phase. - Doesn't fully resolve the general question of how other standard events (like
mouseover
) should interact with pseudo-elements if direct listeners are desired.
- Description: Instead of using the standard
- Add
event.pseudoElement
as inKeyframeEffect
for Web Animations:- Description: Add
pseudoElement
parameter as eitherCSSPseudoElement
orstring
toevent
which will be set if the event was fired from the pseudo element. Allowing callingaddEventListener
onCSSPseudoElement
can even be optional here. - Pros:
- Avoids web compat issues.
- Sidesteps pseudo lifetime/eventing complexity for the use case if
pseudoElement
is represented asstring
. - Proven feasible for Web Animations.
- Cons:
- Adding new API.
- Description: Add
Recommendation:
Add event.pseudoElement
as in KeyframeEffect for Web Animations.
Justification: This option provides the best balance. It directly enables the desired developer use case (listening for clicks on the scroll marker) with good ergonomics (addEventListener
on the pseudo element object). Crucially, it achieves this while adhering to the non-negotiable web compatibility requirement that event.target
for standard events like click
must remain the originating Element
.