Re: [csswg-drafts] How to handle addEventListener on `CSSPseudoElement`? (#12163)

The CSS Working Group just discussed ``How to handle addEventListener on `CSSPseudoElement`?``.

<details><summary>The full IRC log of that discussion</summary>
&lt;sakhapov> sakhapov<br>
&lt;zcorpan> sakhapov: We discussed in CSSWG. On board with event listeners for pseudo-elements. Went to whatwg to propose<br>
&lt;zcorpan> sakhapov: Feedback that pseudo-elements shouldn't have such powers<br>
&lt;zcorpan> sakhapov: Asking here with folks from both groups<br>
&lt;sakhapov> https://github.com/w3c/csswg-drafts/issues/12575<br>
&lt;zcorpan> sakhapov: New approach that Noam suggested<br>
&lt;sakhapov> 12575<br>
&lt;zcorpan> sakhapov: Reuse slot to represent the pseudo-element<br>
&lt;emilio> I have to drop (conflict), but I commented on Noam's proposal and it seems potentially nice / less complex?<br>
&lt;keithamus> q+<br>
&lt;zcorpan> sakhapov: Want to address concern from annevk and lea, about events<br>
&lt;zcorpan> astearns: Not a new ask to support this<br>
&lt;astearns> ack keithamus<br>
&lt;zcorpan> keithamus: From what I heard, it's a bit confusing. Adds a lot of API surface. How would events propagate?<br>
&lt;zcorpan> keithamus: Will not achieve the desired effect, i.e. understand when an event fired from a pseudo<br>
&lt;zcorpan> keithamus: Would be a closed shadow tree. The event path would be retargeted, would only see where the click originated from<br>
&lt;zcorpan> keithamus: other than the host<br>
&lt;zcorpan> keithamus: Don't understand how the two proposals can complement each other, or how the second proposal solves what teh first is claiming<br>
&lt;zcorpan> keithamus: Personally objecting to the notion to have events fired on pseudos<br>
&lt;zcorpan> sakhapov: We fire the second contained event, only for the pseudo object<br>
&lt;zcorpan> sakhapov: Add a property to event, e.g. pseudoTarget<br>
&lt;zcorpan> keithamus: Why not add that to the first event?<br>
&lt;zcorpan> sakhapov: For mouseover event, should not fire the second event when you move from pseudo to the real element<br>
&lt;zcorpan> sakhapov: For only one event, problem with target change<br>
&lt;lea> Thinking out loud, it seems that the right primitive that is needed is a way for the web platform to do regular elements (with regular DOM objects, targeted by selectors etc) where some things are off-limits  and cannot be accessed, set or matched (what things those are depends on the case, e.g. descendants, element type, attributes etc). That would also fix all the issues with `::slotted()` and `::part()` as well, and (depending on how it's<br>
&lt;lea> defined) has the potential to fix a ton of shadow DOM pain points too. But obviously, that's much larger scope.<br>
&lt;lea> Pseudo-elements were originally envisioned as a way for CSS to target parts of an element or not real elements, and using them to do encapsulation with regular elements it usually creates a host of issues.<br>
&lt;zcorpan> keithamus: practical ramifications? Why can't we do that? I've heard the theoretical issue, but is it an issue in practice?<br>
&lt;zcorpan> sakhapov: mouseover?<br>
&lt;flackr> q+<br>
&lt;zcorpan> sakhapov: Existing websites. Hovering, firing two events for teh same element can confuse or break things<br>
&lt;zcorpan> smaug: need mouseout. Don't get the right combination of events<br>
&lt;zcorpan> keithamus: aha, I see<br>
&lt;astearns> ack flackr<br>
&lt;zcorpan> flackr: Can we treat the pseuido as a real element?<br>
&lt;zcorpan> flackr: Already a problem if you have multiple real elements in an ancestor<br>
&lt;zcorpan> sakhapov: Fire an event only on the pseudo, which doesn't bubble. Second event is fired on the element as today<br>
&lt;zcorpan> flackr: If we restrict (MISSED)<br>
&lt;zcorpan> sakhapov: Don't want to change the old behavior<br>
&lt;zcorpan> sakhapov: only want to know info that a specific pseudo got some events<br>
&lt;astearns> s/(MISSED)/contained events to boundary events (I think)/<br>
&lt;zcorpan> flackr: Usually done with event delegation<br>
&lt;masonf> q+<br>
&lt;zcorpan> flackr: Would want to know at the root<br>
&lt;zcorpan> flackr: Don't think they don't want it, if we can solve it as bubbles<br>
&lt;zcorpan> annevk: One solution is to use real elements instead of pseudo-elements<br>
&lt;zcorpan> lea: agree with annevk. Psueod-elements are not real elements<br>
&lt;masonf> q-<br>
&lt;zcorpan> keithamus: ::part() and ::slot() are (MISSED)<br>
&lt;astearns> s/Psueod-elements/Some pseudo-elements/<br>
&lt;zcorpan> flackr: can exclude ::first-line<br>
&lt;zcorpan> lea: architecture becomes unclear<br>
&lt;keithamus> s/(MISSED)/element backed<br>
&lt;zcorpan> lea: Not consistent, more complicated story to tell<br>
&lt;zcorpan> lea: slotted and part are huge pain points today<br>
&lt;zcorpan> lea: Trying to make pseudo-elements do things they were not intended to do<br>
&lt;zcorpan> lea: Not sure the solution is to add more stuff to them<br>
&lt;zcorpan> lea: If you see the problem space as exposing elements while not exposing as elements, (MISSED)<br>
&lt;zcorpan> annevk: Also worried that it's a slippery slope<br>
&lt;lea> +1 annevk<br>
&lt;zcorpan> annevk: Easier if carousel use real elements, like all other widgets we have<br>
&lt;zcorpan> sakhapov: View transitions ...<br>
&lt;fantasai> +1 annevk<br>
&lt;zcorpan> flackr: We already distinguish element-backed pseudos. This is just an extension<br>
&lt;zcorpan> flackr: They are hit-testable<br>
&lt;lea> q?<br>
&lt;zcorpan> astearns: For clarification, are you suggesting we should stop adding new pseudos?<br>
&lt;zcorpan> annevk: If you have a use case that warrants an element, then use an element<br>
&lt;lea> q+<br>
&lt;zcorpan> annevk: If you want just styling, pseudo is OK<br>
&lt;zcorpan> keithamus: precedent for `details`. Implicit summary, but a real element can be added<br>
&lt;astearns> ack lea<br>
&lt;zcorpan> lea: I think element-backed pseudos were a mistake<br>
&lt;zcorpan> lea: Easier to introduce pseudos than a general solution<br>
&lt;jarhar> q+<br>
&lt;zcorpan> lea: We should have solved it differently imo<br>
&lt;zcorpan> lea: So many issues with the pseudo-element solution for slotted<br>
&lt;zcorpan> lea: Understand that it's bigger scope<br>
&lt;ntim> element-backed pseudos do not expose the underlying elements themselves fyi<br>
&lt;astearns> ack jarhar<br>
&lt;zcorpan> jarhar: For customizable select the picker was an author-provided element<br>
&lt;masonf> q+<br>
&lt;zcorpan> jarhar: Later, changed to shadowroot that the author doesn't provide since it always needs to exist<br>
&lt;zcorpan> jarhar: not up to date on carousel<br>
&lt;lea> q+<br>
&lt;zcorpan> jarhar: forcing the author to write every element, seems better to generate<br>
&lt;astearns> ack masonf<br>
&lt;lea> qq+<br>
&lt;zcorpan> masonf: too late to debate whether we should have pseudos<br>
&lt;zcorpan> masonf: developer-wise, pseudos are nice<br>
&lt;zcorpan> masonf: Nicely handled by the browser, e.g. ::after<br>
&lt;flackr> +1<br>
&lt;astearns> ack lea<br>
&lt;Zakim> lea, you wanted to react to masonf<br>
&lt;zcorpan> lea: I think misunderstanding. I think pseudos are great. Discussed element-backed pseudos<br>
&lt;zcorpan> lea: Didn't suggest authors should be writing them<br>
&lt;zcorpan> lea: expose regular elements<br>
&lt;zcorpan> lea: can be generated by teh browser<br>
&lt;zcorpan> masonf: In the shadow tree (can't expose) or in the real tree (also funny)<br>
&lt;zcorpan> lea: that's with what we currently have... Could change what we expose<br>
&lt;zcorpan> masonf: That's the shape of this proposal though?<br>
&lt;flackr> +1<br>
&lt;zcorpan> lea: Proposal to introduce DOM object to represent pseudo-elements<br>
&lt;zcorpan> annevk: I think what you're saying is also not "a real element". &lt;summary>-like is more what I had in mind<br>
&lt;zcorpan> sakhapov: My proposal is you have a pseudo ...<br>
&lt;zcorpan> annevk: We take issue with adding events to pseudo-elements, hence discussing these other things<br>
&lt;zcorpan> masonf: My understanding was if you want events or so, add a normal element<br>
&lt;ntim> I'm not aware of view transitions use cases<br>
&lt;lea> q?<br>
&lt;zcorpan> masonf: Let the browser do the nice thing by default, but allow<br>
&lt;zcorpan> annevk: I would like some more explanation on the view transitions use case<br>
&lt;flackr> q+<br>
&lt;zcorpan> annevk: hard to imagine why we want to listen for events there<br>
&lt;zcorpan> annevk: for scroll, seems more tricky<br>
&lt;keithamus> q+<br>
&lt;astearns> ack lea<br>
&lt;astearns> q+<br>
&lt;zcorpan> lea: If it boils down to making authors do more work, I would vote for using pseudo-elements due to the priority of constituencies<br>
&lt;astearns> ack flackr<br>
&lt;zcorpan> flackr: One alternative is, rather than pseudos being a full part of the event path, just add pseudo to the normal event<br>
&lt;lea> Oh that's a very interesting compromise<br>
&lt;zcorpan> astearns: No additional events<br>
&lt;zcorpan> astearns: If you have a listener only for a pseudo<br>
&lt;zcorpan> lea: part of adding the listener<br>
&lt;zcorpan> flackr: That was part of the proposal<br>
&lt;zcorpan> annevk: I thought exposing pseudo on the event was dismissed, but didn't understand why<br>
&lt;zcorpan> keithamus: can't observe changes<br>
&lt;zcorpan> keithamus: e.g. transition from ::before to the host element<br>
&lt;lea> e.g. `element.addEventListener("click", { pseudoElement: "foobar" })`<br>
&lt;zcorpan> masonf: can you add something to the options bag? opt-in when adding the event listener<br>
&lt;zcorpan> flackr: Sure<br>
&lt;zcorpan> lea: Do both?<br>
&lt;zcorpan> flackr: Yes<br>
&lt;smaug> rather ugly to use addEventListener as a way to change how events are dispatched<br>
&lt;astearns> ack keithamus<br>
&lt;zcorpan> keithamus: Earlier discussion about difficulty of authoring scroll markers<br>
&lt;zcorpan> keithamus: generate a carousel of however many images<br>
&lt;zcorpan> keithamus: N number of LIs and buttons<br>
&lt;lea> Slotting in these seems independently useful. E.g. you want a custom icon on a scroll marker, you shouldn't have to generate it in CSS (which currently involves a ton of hoops depending on the way you do icons…)<br>
&lt;zcorpan> flackr: Can create a scroll marker for pages, not possible without a lot of script<br>
&lt;zcorpan> astearns: propagation... If we added an event listener to the pseudo-object, never propagate<br>
&lt;zcorpan> astearns: Authors would need to send it manually to propagate<br>
&lt;zcorpan> lea: I don't follow<br>
&lt;flackr> keithamus: an example is https://codepen.io/flackr/pen/yLmyPEV or https://chrome.dev/carousel/horizontal/pages/<br>
&lt;zcorpan> astearns: Let's keep discussing in the issue<br>
</details>


-- 
GitHub Notification of comment by css-meeting-bot
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/12163#issuecomment-3164836504 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Thursday, 7 August 2025 16:02:16 UTC