Skip to content

::details-content vs details::part(content) #9951

@tabatkins

Description

@tabatkins

At the F2F, there was some discussion about how to expose the <slot> in the <details> element's shadow DOM that wraps the details' content.

There are two main options: a new pseudo-element (provisionally called ::details-content), or a shadow part (provisionally called ::part(content)).

Arguments for ::details-content:

  • Consistent with the collection of existing pseudo-elements exposed on various "special" elements, like input::file-selector-button

Arguments for ::part(content)

  • Clearer about what other things are allowed, like ::part(content):hover works by default
  • Integrates nicely with other shadow-parts functionality, like the ability to export it as one of the parts of a wrapping component. ¹

During the meeting, we seemed to recall that this topic had been previously brought up, and both WebKit engineers and the HTML spec editors disliked it. Our recollection of their reasoning was:

  1. consistency with existing pseudo-elements on special elements (aka the "arguments for" I already listed)
  2. part names are author-controlled, and the language shouldn't impinge on it

I think that (1) is reasonable, tho that's historical precedent from before ::part() even existed. It might be reasonable to change that. For example, we could make all those element-specific pseudo-elements also exposed as ::part(), as that would give you the "export this as one of the wrapping component's parts" ability that I allude to above.

But I will push back on (2) very strongly. It is important to not impinge on author-controlled namespaces; you don't want to accidentally clash with existing author-defined names, and it's not great to have certain special names be illegal for authors to use.

But neither of those apply here. The owner of a given element's ::part() namespace is the owner of that component's shadow DOM. I designed this very carefully to make sure that's 100% true - the owner of a component's shadow can choose to import the names from a sub-component for themselves, but it's always an extremely explicit choice. You'll never get surprised by names showing up in your namespace you don't expect.

So, here, the UA is the owner of the details shadow. If it wants to expose a part name, nothing any author can do will ever interact negatively with that.


¹: That is, if you have a custom component <my-widget> that contains a <details> element in its shadow, you could use <details exportparts=content>, and then my-widget::part(content) works, targeting the details-content box. This is impossible to do with a pseudo-element, at least right now.

Tho we could attack this from the other direction - rather than turn all existing element-specific pseudo-elements into ::part()s so they can be used in exportparts, we could just allow pseudo-elements to be used in exportparts, like <details exportparts="::details-content : content">.

/cc @emilio

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions