Re: [csswg-drafts] [css-pseudo-4] Proxying pseudo-elements as "real" (`<slot>`) elements (#12575)

The CSS Working Group just discussed ``[css-pseudo-4] Proxying pseudo-elements as "real" (`<slot>`) elements``.

<details><summary>The full IRC log of that discussion</summary>
&lt;TabAtkins> noamr: this is from a proposal for how to deal with pseudo elements<br>
&lt;TabAtkins> noamr: we're getting a lot more pseudo-elements added by VT, carousel, etc<br>
&lt;TabAtkins> noamr: plus older ones like before/after<br>
&lt;TabAtkins> noamr: lot of requests of how to get event listeners for them, getBoundingClientRect, etc<br>
&lt;TabAtkins> noamr: usually things related to layout and rendering. UI events, like clicks or pointer events<br>
&lt;TabAtkins> noamr: so an issue is, is this a bit more than style, or a little less than dom?<br>
&lt;TabAtkins> noamr: I think usually the former<br>
&lt;TabAtkins> noamr: discussed in whatwg, lot of objection to adding more DOM-ish thing (like addeventlistener) to things that aren't in the dom<br>
&lt;TabAtkins> noamr: my proposal then is a bit different, entirely in css<br>
&lt;TabAtkins> noamr: proposal is we add actual DOM elements that can represent one or more pseudo elements<br>
&lt;TabAtkins> noamr: the original proposal was to use &lt;slot>, but has evolved a bit<br>
&lt;TabAtkins> noamr: do `display: pseudo-element`; it makes the element a layout/event proxy for the pseudo<br>
&lt;TabAtkins> noamr: it's regular dom, you can add event listeners, aria, popovertarget, etc<br>
&lt;TabAtkins> noamr: but everything to do with layout/rendering/etc is still normal css, per the pseudo-elmeent's definition<br>
&lt;futhark> q+<br>
&lt;TabAtkins> noamr: this is slightly radical, not sure if I've explained all the tidbits<br>
&lt;TabAtkins> noamr: thinking of this as a display value because it's not actually displayed at all<br>
&lt;TabAtkins> noamr: no layout, no rendering, similar to dipslay:none<br>
&lt;astearns> ack futhark<br>
&lt;lea> q+<br>
&lt;fantasai> s/Topic/Subtopic<br>
&lt;TabAtkins> futhark: what about like :nth-child() and such? should be skipped by selectors?<br>
&lt;RRSAgent> I have made the request to generate https://www.w3.org/2025/08/20-css-minutes.html fantasai<br>
&lt;TabAtkins> noamr: it's part of the dom, so yes, selectors will see it. but you can't add any meaningful styles for it<br>
&lt;TabAtkins> noamr: it's effectively display:none<br>
&lt;fantasai> i/Subtopic: [css-conditional-5] Clarify/Topic: Conditional Rules<br>
&lt;TabAtkins> noamr: as neutral as possible for DOM and related stuff<br>
&lt;astearns> ack lea<br>
&lt;RRSAgent> I have made the request to generate https://www.w3.org/2025/08/20-css-minutes.html fantasai<br>
&lt;TabAtkins> lea: I quite like the idea. like that this is really a dom element<br>
&lt;TabAtkins> lea: also ahs potential for another pain point. pseudos can't currnetly be exposed by a web component<br>
&lt;fantasai> i/Subtopic: [css-pseudo/Topic: Pseudo-selectors/<br>
&lt;TabAtkins> lea: you can expose elements as a part, but not pseudo-elements<br>
&lt;RRSAgent> I have made the request to generate https://www.w3.org/2025/08/20-css-minutes.html fantasai<br>
&lt;TabAtkins> lea: maybe there's some synergy there<br>
&lt;TabAtkins> lea: you can expose a &lt;slot> as a ::part, after all<br>
&lt;TabAtkins> noamr: correct, it's a regular element, bu tit's not rendered<br>
&lt;astearns> q+<br>
&lt;TabAtkins> TabAtkins: That means Lea's request wouldn't work, the element isn't meaningfully styleable.<br>
&lt;TabAtkins> noamr: ah right, you can't style it from outside<br>
&lt;TabAtkins> astearns: for your use-case of a component using a native element and wanting to expose its pseudos, where would you put this new element backing for it?<br>
&lt;TabAtkins> lea: you usually have it in your shadow dom already...<br>
&lt;TabAtkins> lea: another complication. this assumes you can nest the slots inside the element, but not all elements take contents<br>
&lt;astearns> ack astearns<br>
&lt;TabAtkins> TabAtkins: yeah, like a pseudo from an input?<br>
&lt;lea> s/lea: you usually have it in your shadow dom already.../lea: you have it in your shadow dom already — if it's nested within another component, you'd use `exportparts`/<br>
&lt;TabAtkins> noamr: Possibly could use &lt;pseudo for="">, so it doesn't need to be a direct child of the element it's targeting<br>
&lt;TabAtkins> noamr: we could perhaps start with tree-abiding, though, and then have some semantic for cross-referencing<br>
&lt;TabAtkins> noamr: But the main initial use-case is for things like carousel buttons or VT before/after, things that are content-ful<br>
&lt;TabAtkins> noamr: but there's space to make it all work with some extnesions, i'd say<br>
&lt;sakhapov> q+<br>
&lt;lea> q+<br>
&lt;noamr> q+<br>
&lt;TabAtkins> astearns: anyone else ahve reservations about requiring users to chang emarkup to get this added functionality on pseudos? a little weird that css wants to add event listenres to its own pseudos, and to do that you ahve to go outside of css<br>
&lt;lea> q-<br>
&lt;astearns> ack sakhapov<br>
&lt;TabAtkins> sakhapov: the alternative was CSSPseudoElement in JS, and we discussed the issue of existence<br>
&lt;TabAtkins> sakhapov: we decided the CSSPsuedoElement was a persistent handle even if the pseudo didn't exist at the time<br>
&lt;TabAtkins> noamr: I don't see it as CSS wanting to add something, the web platform needs something between DOM and CSS<br>
&lt;TabAtkins> noamr: pseudo-elements are in the middle there, and can fall behind the chairs<br>
&lt;TabAtkins> noamr: philosophical question of what's DOM and what's CSS is blurry<br>
&lt;TabAtkins> noamr: But this is really close to a DOM thing - bubbling event listernes, direct DOM access... everything becomes pretty DOM-ish rather than a style thing<br>
&lt;TabAtkins> noamr: So I don't see this as a problem, I see it as a feature, it's actually in the DOM<br>
&lt;astearns> agreed that event listeners are DOMmish :)<br>
&lt;TabAtkins> noamr: so the css feature is just to dipslay it like it's styled by th enormal css feature<br>
&lt;TabAtkins> noamr: about the reflection thing, I think we can add things to cssom that lets you query info about the pseudo-element<br>
&lt;TabAtkins> noamr: that can be the CSSPseudoElement API, reflecting about this connection<br>
&lt;fantasai> TabAtkins: Because the pseudo-element doesn't actually do anything stylistically, its presence in the DOM doens't result in anything happening, whether pseudo exists is a CSS question, I'm ok with it<br>
&lt;fantasai> TabAtkins: I would be uncomfortable if markup was necessary to create the pseudo<br>
&lt;fantasai> TabAtkins: but since a proxy, it's fine<br>
&lt;fantasai> TabAtkins: They'll work if they need to, won't work if they don't need to<br>
&lt;sakhapov> q+<br>
&lt;andruud> q+<br>
&lt;noamr> q-<br>
&lt;fantasai> TabAtkins: should be flexible wrt CSS, so happy with how this looks<br>
&lt;astearns> ack sakhapov<br>
&lt;TabAtkins> sakhapov: one point, in carousel we have ::column pseudo which isn't really representable in DOM, and in there you can have ::scroll-marker. the number of these is layout-dependent, so you can't know in advance how many &lt;pseudo>s you'll need.<br>
&lt;TabAtkins> sakhapov: not sure how that's addressable<br>
&lt;TabAtkins> noamr: I talked to that point a little bit. the proxy element can represeent one or more pseudo-elements<br>
&lt;TabAtkins> noamr: so if you have multiple scroll-buttons, etc, the proxy is a proxy for all the pseudo-elements with that name<br>
&lt;TabAtkins> noamr: in terms of events, there are a few things we'll have to figure out, like gBCR()<br>
&lt;TabAtkins> noamr: but I think some of those internall css reflection mechanisms... "this element supports ten pseudo-elements", we can start with the idea that &lt;pseudo> represents 0-N pseudos<br>
&lt;TabAtkins> sakhapov: and with this approach you'll lose the ability to identify which marker, specifically, was clicked<br>
&lt;TabAtkins> noamr: I think we'll have to take some of the things from the addEventListnere proposal<br>
&lt;TabAtkins> noamr: a lot fo the concerns whatwg had with it will be gone. we have a proper element now that can bubble, etc. and then we can add info to the event about what the exact pseudo it's for<br>
&lt;TabAtkins> noamr: so we can have JS reflection about it to solve that<br>
&lt;TabAtkins> noamr: but those are details we'll need to discuss, it's not set yet. but i think ther'es a trajectory to solving it<br>
&lt;astearns> q?<br>
&lt;astearns> ack andruud<br>
&lt;TabAtkins> andruud: tab, you argued we'd be okay with it because the pseudos don't do anythign stylistically<br>
&lt;TabAtkins> andruud: but this'll change you sibling index. is that okay?<br>
&lt;TabAtkins> andruud: should we really not doing special about that?<br>
&lt;lea> q+<br>
&lt;kizu> q+<br>
&lt;TabAtkins> TabAtkins: [missed, but re-explaining why they thin kthis is fine]<br>
&lt;astearns> zakim, close queue<br>
&lt;Zakim> ok, astearns, the speaker queue is closed<br>
&lt;TabAtkins> andruud: sibling-index() would still just give changed results, tho<br>
&lt;astearns> ack lea<br>
&lt;TabAtkins> TabAtkins: yeah, it would jsut need to get worked around<br>
&lt;andruud> ^ sibling-count()<br>
&lt;TabAtkins> lea: I do think not being able to nest them into some elements would be a blocker, don't wnat to invent something new for &lt;input> or &lt;img><br>
&lt;TabAtkins> lea: not as much of a blocker, i think it would be desirable to expose pseudos with this mechanism for shadows<br>
&lt;TabAtkins> TabAtkins: I have a proposal in an issue for allowing pseudos in exportparts="", fwiw<br>
&lt;TabAtkins> lea: ah, let's look at that then. but still the first point<br>
&lt;astearns> ack kizu<br>
&lt;TabAtkins> noamr: point taken, we can make sure it's addressed in the proposal<br>
&lt;TabAtkins> kizu: two things, maybe long shot<br>
&lt;lea> noamr: I suppose it could use a relative element reference for empty elements, whatever we decide to do with those :D<br>
&lt;lea> s/noamr: I suppose it could use a relative element reference for empty elements, whatever we decide to do with those :D /noamr, I suppose it could use a relative element reference for empty elements, whatever we decide to do with those :D /<br>
&lt;emilio> scribe+<br>
&lt;fantasai> scribe- lea<br>
&lt;emilio> kizu: would be nice to allow inline styles<br>
&lt;emilio> ... so that they could be proxied to the pseudo-elements<br>
&lt;emilio> ... we probably don't want to allow any content inside, and as an author I'd expect content to work<br>
&lt;emilio> q+<br>
&lt;emilio> ... this could fix some of the potential a11y issues with pseudos<br>
&lt;emilio> ... so anything that can translate the dom could translate it<br>
&lt;emilio> ... so this could be some sort of templating solution<br>
&lt;emilio> ... so you could put inline svg inside the button's before slot<br>
&lt;fantasai> astearns: I think we can take this back to the issue<br>
&lt;fantasai> astearns: roman just introduced an entirely new idea<br>
&lt;fantasai> emilio: if you do ::before, the 'content' property would create the content inside that element<br>
&lt;fantasai> emilio: that's why you don't want to mess with it<br>
&lt;fantasai> astearns: it's an interesting idea, we should explore more, but no more time to day<br>
&lt;fantasai> astearns: Noam, let's take this back to the issue<br>
&lt;fantasai> astearns: you'll also need to take this to WHATNOT<br>
&lt;fantasai> noamr: not introducing a new alement<br>
&lt;fantasai> noamr: let's take back to issue with minutes<br>
&lt;TabAtkins> (I think we do need a new element, we can discuss in the issue.)<br>
&lt;fantasai> noamr: seems fairly positive in the room<br>
&lt;fantasai> astearns: I am cautiously positive. :) Seems like an interesting idea but also very scary<br>
</details>


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


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

Received on Wednesday, 20 August 2025 09:47:25 UTC