- From: Daniil Sakhapov via GitHub <sysbot+gh@w3.org>
- Date: Mon, 05 May 2025 13:40:41 +0000
- To: public-css-archive@w3.org
danielsakhapov has just created a new issue for https://github.com/w3c/csswg-drafts: == How to handle addEventListener on `CSSPseudoElement`? == 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. Proposed variants are included in the table: | Model | `event.target` Behavior (for existing events like `click`) | `addEventListener` on Pseudo? | Pros | Cons | Feasibility Notes | |----------------------------|-----------------------------------------------------------|------------------------------|------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------| | A: Status Quo | `Element` (retargeted) | No | Full web compatibility. Simple. | No direct script interaction with pseudo events. | Current state. | | B: Full `EventTarget` | `CSSPseudoElement` | Yes | Direct event handling on pseudo. Conceptually clean object model. | Major breaking change for web compatibility. Complex bubbling definition needed, esp. for non-tree pseudos. | Highly unlikely due to web compatibility constraints. | | C: Hybrid (Parent + Selector) | `Element` (retargeted) | No (Interaction via parent) | Avoids web compat issues. Sidesteps pseudo lifetime/eventing complexity for the use case. | Less direct object model. Requires specific API pattern (like Web Animations `pseudoElement`). | Proven feasible for Web Animations L1. Potentially applicable to other interactions. | | D: Limited `EventTarget` | `Element` (for existing events). `CSSPseudoElement` (for new specific events only). | Yes (for specific events) | Maintains web compat for existing events. Allows direct handling for new use cases. | Complex dispatch logic. Bubbling complexity remains for events targeting pseudo. Potential developer confusion. | Requires careful definition of which events target what, and clear bubbling rules. Avoids the main breaking change of Model B. | Potential solutions on example of `::scroll-marker`: * No direct listening on pseudo element (Status Quo): * **Description**: Do not allow `addEventListener('click',...)` directly on the `CSSPseudoElement` for `::scroll-marker`. Clicks physically hitting the marker would continue to dispatch with `event.target` set to the originating scrollable `Element`. Developers would have to attach the listener to the `Element` 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 its `EventTarget` inheritance. * 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 invokes `counterFunction` (and any other listeners attached directly to this specific `CSSPseudoElement` handle). * Standard Phase: The event dispatch continues as normal, but crucially, `event.target` is set to the originating scrollable `Element`. The event then proceeds through the capture and bubble phases relative to the `Element`, without re-invoking `counterFunction` during this standard flow. * **Pros:** * Directly addresses the developer need: allows attaching listeners specifically to the pseudo-element of interest. * Preserves web compatibility by ensuring `event.target` remains the `Element` during the standard, observable event flow. * Provides a meaningful use for the `EventTarget` inheritance on `CSSPseudoElement`. * 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. * Introduce a new specific event type: * **Description**: Instead of using the standard `click` event, define a new event type like `scrollMarkerClick` that only fires on the `CSSPseudoElement` handle for the `::scroll-marker`. Standard `click` events would continue to target the `Element` only. * **Pros:** * Avoids any ambiguity or modification related to the standard `click` event dispatch. * Clearly separates the interaction. * **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. **Soft, but somewhat desired recommendation:** Option 2: Allow Direct Listening with Special Dispatch Phase. Justification: This option provides the best balance. It directly enables the desired developer use case (listening for clicks on the 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`. While it requires implementing a modification to the event dispatch mechanism, this internal complexity seems justified to provide a usable and compatible solution. Option 1 is too cumbersome for developers, and Option 3 introduces a new event type which might be unnecessary if the dispatch modification in Option 2 can be generalized for other standard events targeting pseudo-elements. Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/12163 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Monday, 5 May 2025 13:40:42 UTC