In https://github.com/whatwg/html/issues/3805 a concern was raised by @bzbarsky (perhaps on behalf of @MatsPalmgren) that expressing details through shadow trees results in a placement of ::before and ::after that's not desirable.
So the question is whether ::before and ::after on a host element should perhaps be shadow tree aware and end up "assigned" to a slot. This would perhaps be somewhat more natural given that element children end up being assigned.
cc @zcorpan @emilio @hayatoito @rniwa
I personally don't see a logical need for slotting ::before/::after in the template. The pseudos always go before/after _all_ the element's children in the flattened tree, whether those children are from the light DOM or the shadow. It's not super convenient, but it's predictable.
However, I'm sure there are cases where it could be useful to reposition CSS generated content. For example, if you have a <chapter-header> component which has a chapter number assigned with CSS counters, and you want to control exactly where that gets laid out.
If they _were_ to be slottable in the template, how would that work? A ::before on the host is implicitly slotted before all shadow DOM content _unless_ an explicit <slot name="::before"/> is included elsewhere in the tree? What other pseudo-elements would be slottable? Could you slot a ::marker? But then what about pseudo-elements that are just shortcuts to style boxes in the shadow tree (as in the proposed ::part() selector, or the many existing selectors for form element or scrollbar components)?
More comments on the specifics of details/summary vs fieldset/legend on the other issue: https://github.com/whatwg/html/issues/3805#issuecomment-422488912
I think I wouldn't like to implement this in Gecko.
This means layout needs to shuffle pseudo-elements around and figure out the right insertion point when slots gets changed and moved around, feels a bit of a layering violation that DOM needs to care about pseudo-elements for slotting.
Also this would have implications... An element with a pseudo-element would no longer display the slot's fallback, right? Which means that there's no way to have both fallback and pseudo-elements at the same time. So from an author's perspective doesn't sound as great either. There'd also be no way to assign a pseudo-element to a non-default slot (or keeping the usual behavior) without even more special-casing...
That makes sense, the motivation was making ::before and ::after on details elements (defined in terms of internal shadow trees) work similarly to fieldset elements (defined as creating a specific box tree), but perhaps that's not a worthwhile enough goal. And the way fieldset works now I understand it better is that really their legend element is positioned in a special way, which isn't really the case with details elements' summary element.
I would prefer we not define details the same way as fieldset; magical rendering that can't be reproduced by users of the platform is something to be avoided whenever possible.
That's why we defined details in terms of shadow DOM - it was the only way to explain the rendering using the platform. And thus the behavior of ::before/::after falls out of that, matching how it works with every other shadow-dom–using component in the world — ::before/::after get jammed into the flat tree as the first/last child of the originating element. So yeah, they show up whether the details is open or closed, and ::before will precede the summary in either case.
I'm potentially open to the idea of letting a host element describe where it would like its ::before/::after to go. I think I'd prefer, tho, just continuing to develop and support ::part(), which allows ::before/::after on it, and then defining the name of the built-in details part so authors can target it.
That way, details::before would work as today, with the ::before showing up all the time, and before all other content including summary; details::part(content)::before would only show up when the details was open, and would just go at the start of the content, after the summary.
Rather than using ::part() explicitly, since it's intended as an authoring mechanism, we should probably instead define ::details-content as a pseudo-element on details, pointing to the anonymous box wrapped around the contents (or, in shadow dom terms, the div in the <shadow><div><slot selector=":not(summary:first-child)"></slot></div></shadow> of the UA shadow tree).
This would solve a number of problems all at once:
::before/::after before/after the contents, so they're not displayed when the details is closeddetails as open via CSS, for print styles or the like (see https://github.com/w3c/csswg-drafts/issues/2084 for this request)details with a non-block display value, without requiring an extra wrapper elementIf this sounds like something worthwhile, I'm happy to help write up spec text. I expect it would be defined in HTML.
Most helpful comment
Rather than using
::part()explicitly, since it's intended as an authoring mechanism, we should probably instead define::details-contentas a pseudo-element ondetails, pointing to the anonymous box wrapped around the contents (or, in shadow dom terms, thedivin the<shadow><div><slot selector=":not(summary:first-child)"></slot></div></shadow>of the UA shadow tree).This would solve a number of problems all at once:
::before/::afterbefore/after the contents, so they're not displayed when thedetailsis closeddetailsas open via CSS, for print styles or the like (see https://github.com/w3c/csswg-drafts/issues/2084 for this request)detailswith a non-blockdisplayvalue, without requiring an extra wrapper elementIf this sounds like something worthwhile, I'm happy to help write up spec text. I expect it would be defined in HTML.