::details-content

Avatar of Geoff Graham
Geoff Graham on

The CSS ::details-content pseudo-element provides a way to select and apply styles to the inner parts of a <details> element without leaking styles to the <summary>.

details::details-content {
  background-color: hsl(0 0% 0%);
}

Syntax

<element-selector>::details-content {}

We say <element-selector> in there, but ::details-content is specifically tied to the <details> element, meaning that’s what you’ll use as the selector in many cases:

details::details-content {}

Of course, if you want to select a particular <details> element, then it’s possible to select it by class as well:

.my-class::details-content {}

Finally, a way to style details content!

The HTML for a typical <details> element looks something like this:

<details>
  <summary>Details Example</summary>
  Whatever content or other markup we want in this space!
</details>

It’s easy to style the <details> element simply by selecting it in CSS:

We can also style the element when it’s expanded using the open attribute:

It’s just as easy to add styles to the <summary> element since we can directly select it as well:

Heck, we can even style the little arrow bit before the <summary>. If we open up developer tools and inspect the element, we’ll see a Shadow DOM in there with a -webkit-specific pseudo-element for it.

Inspecting a details element in devtools to reveal the markup containing the detail marker.

See that? It’s a pseudo-element to the <summary> element, so we can select it like this:

summary::-webkit-details-marker {
  /* Style away! */
}

But how in the world can we style the content inside a <details> element? That’s what we’ve been missing and what the ::details-content pseudo-element is for. At the time of this writing, ::details-content is not implemented by any browser, so we do not have a concrete way to show how it works. Assuming that nothing changes in the specification between now and when it is formally adopted as a feature, it might look like this:

details::details-content {
  background-color: hsl(0 0% 0% / .85);
  margin-block: 1rem;
}

That’s why we need ::details-content. It’s sort of a missing piece of the styling puzzle for <details>.

Example

We’ve already looked at an example, but the specification includes one that is worth calling out. It’s interesting because it demonstrates how we might be able to animate the content so that it fades into view:

details::details-content {
  display: block;
  opacity: 0;
  transition: content-visibility 300ms allow-discrete step-end, opacity 300ms;
}

details[open]::details-content {
  opacity: 1;
  transition: content-visibility 300ms allow-discrete step-start, opacity 300ms;
}

Whaaaaaat?!?! This suggests that the pseudo-element will work with native CSS transitions — even multi-step transitions! Let’s go ahead and drop in a live demo of this and see if it works if and when we get broader support.

Browser support

None at the moment! We’ll include a proper support table as support rolls out.

Specification

The ::details-content property is defined in the CSS Pseudo-Elements Module Level 4 specification. It’s currently in Editor’s Draft status, meaning it has yet to become a formal recommendation by the WHATWG on the HTML side and the CSS Working Group on the CSS side and it could change between now and when that happens. So, if you’re debating whether or not to try this out on a live site, it’s best to sit tight and wait for more browsers to implement support for it.

If you’re interested, the definition was added to the spec in June 2024 and you can find the commit right here. You can also find a discussion of it in a couple of GitHub threads for more context.