Yow will discover the <particulars>
ingredient all around the internet nowadays. We had been enthusiastic about it when it first dropped and toyed with utilizing it as a menu again in 2019 (however most likely don’t) amongst many different experiments. John Rhea made a complete sport that combines <particulars>
with the Popover API!
Now that we’re 5+ years into <particulars>
, we all know extra about it than ever earlier than. I believed I’d spherical that info up so it’s in a single place I can reference sooner or later with out having to go looking the location — and different websites — to search out it.
The fundamental markup
It’s a single ingredient:
<particulars>
Open and shut the ingredient to toggle this content material.
</particulars>
That “particulars” label is a default. We are able to insert a <abstract>
ingredient to give you one thing customized:
<particulars>
<abstract>Toggle content material</abstract>
Open and shut the ingredient to toggle this content material.
</particulars>
From right here, the world is sorta our oyster as a result of we are able to stuff any HTML we wish contained in the ingredient:
<particulars>
<abstract>Toggle content material</abstract>
<p>Open and shut the ingredient to toggle this content material.</p>
<img src="path/to/picture.svg" alt="">
</particulars>
The content material is (sorta) searchable
The difficulty with tucking content material inside a component like that is that it’s hidden by default. Early on, this was thought-about an inaccessible apply as a result of the content material was undetected by in-page looking (like utilizing CMD
+F
on the web page), however that’s since modified, no less than in Chrome, which can open the <particulars>
ingredient and reveal the content material if it discovers a matched time period.
That’s sadly not the case in Firefox and Safari, each of which skip the content material stuffed inside a closed <particulars>
ingredient when doing in-page searches on the time I’m scripting this. But it surely’s much more nuanced than that as a result of Firefox (testing 134.0.1) matches searches when the <particulars>
ingredient is open, whereas Safari (testing 18.1) skips it altogether. That might very effectively change by the tip of this yr since searchability is likely one of the gadgets being tackled in Interop 2025.
So, as for now, it’s a good suggestion to maintain essential content material out of a <particulars>
ingredient when potential. For instance, <particulars>
is usually used as a sample for Often Requested Questions, the place every “query” is an expandable “reply” that reveals further info. That may not be the perfect thought if that content material needs to be searchable on the web page, no less than for now.
Open separately
All we have now to do is give every <particulars>
an identical identify
attribute:
<particulars identify="notes">
<abstract>Open Be aware</abstract>
<p> ... </p>
</particulars>
<particulars identify="notes"> <!-- and so on. --> </particulars>
<particulars identify="notes"> <!-- and so on. --> </particulars>
<particulars identify="notes"> <!-- and so on. --> </particulars>
This permits the weather to behave much more like true accordions, the place one panel collapses when one other expands.
Model the marker
The marker is that little triangle that signifies whether or not the <particulars>
ingredient is open or closed. We are able to use the ::marker
pseudo-element to fashion it, although it does include constraints, specifically that each one we are able to do is change the colour and font measurement, no less than in Chrome and Firefox which each totally assist ::marker
. Safari partially helps it within the sense that it really works for ordered and unordered listing gadgets (e.g., li::marker
), however not for <particulars>
(e.g., abstract::marker
).
Let’s have a look at an instance that kinds the markers for each <particulars>
and an unordered listing. On the time I’m scripting this, Chrome and Firefox assist styling the ::marker
in each locations, however Safari solely works with the unordered listing.
Discover how the ::marker
selector in that final instance selects each the <particulars>
ingredient and the unordered listing ingredient. We have to scope the selector to the <particulars>
ingredient if we need to goal simply that marker, proper?
/* This does not work! */
particulars::marker {
/* kinds */
}
Nope! As an alternative, we have to scope it to the <abstract>
ingredient. That’s what the marker is definitely connected to.
/* This does work */
abstract::marker {
/* kinds */
}
You may suppose that we are able to fashion the marker even when we had been to depart the abstract out of the markup. In any case, HTML robotically inserts one for us by default. However that’s not the case. The <abstract>
ingredient needs to be current within the markup for it to match kinds. You’ll see within the following demo that I’m utilizing a generic ::marker
selector that ought to match each <particulars>
components, however solely the second matches as a result of it incorporates a <abstract>
within the HTML. Once more, solely Chrome and Firefox assist in the interim:
You may also suppose that we are able to swap out the triangle for one thing else since that’s one thing we are able to completely do with listing gadgets by means of the list-style-type
property:
/* Doesn't work! */
abstract::marker {
list-style-type: sq.;
}
…however alas, that’s not the case. An article over at internet.dev says that it does work, however I’ve been unsuccessful at getting a correct instance to work in any browser.
That isn’t to say it shouldn’t work that means, however the specification isn’t express about it, so I’ve no expectations a method or one other. Maybe we’ll see an edit in a future specification that will get particular with <particulars>
and to what extent CSS can modify the marker. Or perhaps we received’t. It will be good to have some strategy to chuck the triangle in favor of one thing else.
And what about eradicating the marker altogether? All we have to do is ready the content material
property on it with an empty string worth and voilà!
As soon as the marker is gone, you would determine to craft your personal customized marker with CSS by hooking into the <abstract>
ingredient’s ::earlier than
pseudo-element.
Simply take notice that Safari shows each the default marker and the customized one because it doesn’t assist the ::marker
pseudo-element on the time I’m scripting this. You’re most likely as drained studying that as I’m typing it. 🤓
Model the content material
Let’s say all it’s essential to do is slap a background coloration on the content material contained in the <particulars>
ingredient. You could possibly choose the complete factor and set a background on it:
particulars {
background: oklch(95% 0.1812 38.35);
}
That’s cool, however it might be higher if it solely set the background coloration when the ingredient is in an open
state. We are able to use an attribute selector for that:
particulars[open] {
background: oklch(95% 0.1812 38.35);
}
OK, however what in regards to the <abstract>
ingredient? What in the event you don’t need that included within the background? Effectively, you would wrap the content material in a <div>
and choose that as an alternative:
particulars[open] div {
background: oklch(95% 0.1812 38.35);
}
What’s even higher is utilizing the ::details-content
pseudo-element as a selector. This manner, we are able to choose all the pieces contained in the <particulars>
ingredient with out reaching for extra markup:
::details-content {
background: oklch(95% 0.1812 38.35);
}
There’s no want to incorporate particulars
within the selector since ::details-content
is simply ever selectable within the context of a <particulars>
ingredient. So, it’s like we’re implicitly writing particulars::details-content
.
The ::details-content
pseudo continues to be gaining browser assist once I’m scripting this, so it’s value keeping track of it and utilizing it cautiously within the meantime.
Animate the opening and shutting
Click on a default <particulars>
ingredient and it instantly snaps open and closed. I’m not against that, however there are occasions when it’d look (and really feel) good to transition like a clean operator between the open and closed states. It used to take some intelligent hackery to drag this off, as Louis Hoebregts demonstrated utilizing the Net Animations API a number of years again. Robin Rendle shared one other means that makes use of a CSS animation:
particulars[open] p {
animation: animateDown 0.2s linear forwards;
}
@keyframes animateDown {
0% {
opacity: 0;
remodel: translatey(-15px);
}
100% {
opacity: 1;
remodel: translatey(0);
}
}
He sprinkled in a bit JavaScript to make his ultimate instance totally interactive, however you get the thought:
Discover what’s taking place in there. Robin selects the paragraph ingredient contained in the <particulars>
ingredient when it’s in an open
state then triggers the animation. And that animation makes use of intelligent positioning to make it occur. That’s as a result of there’s no strategy to know precisely how tall the paragraph — or the guardian <particulars>
ingredient — is when expanded. We now have to make use of express sizing, padding, and positioning to drag all of it collectively.
However guess what? Since then, we received a huge present from CSS that enables us to animate a component from zero top to its auto (i.e., intrinsic) top, even when we don’t know the precise worth of that auto top upfront. We begin with zero top and clip the overflow so nothing hangs out. And since we have now the ::details-content
pseudo, we are able to straight choose that somewhat than introducing extra markup to the HTML.
::details-content {
transition: top 0.5s ease, content-visibility 0.5s ease allow-discrete;
top: 0;
overflow: clip;
}
Now we are able to decide into auto-height transitions utilizing the interpolate-size
property which was created simply to allow transitions to key phrase values, akin to auto
. We set it on the :root
ingredient in order that it’s accessible all over the place, although you would scope it on to a extra particular occasion in the event you’d like.
:root {
interpolate-size: allow-keywords;
}
Subsequent up, we choose the <particulars>
ingredient in its open
state and set the ::details-content
top to auto
:
[open]::details-content {
top: auto;
}
We are able to make it in order that this solely applies if the browser helps auto-height transitions:
@helps (interpolate-size: allow-keywords) {
:root {
interpolate-size: allow-keywords;
}
[open]::details-content {
top: auto;
}
}
And eventually, we set the transition on the ::details-content
pseudo to activate it:
::details-content {
transition: top 0.5s ease;
top: 0;
overflow: clip;
}
/* Browser helps interpolate-size */
@helps (interpolate-size: allow-keywords) {
:root {
interpolate-size: allow-keywords;
}
[open]::details-content {
top: auto;
}
}
However wait! Discover how the animation works when opening <particulars>
, however issues snap again when closing it. Bramus notes that we have to embody the content-visibility
property within the transition as a result of (1) it’s implicitly set on the ingredient and (2) it maps to a hidden state when the <particulars>
ingredient is closed. That’s what causes the content material to snap to hidden when closing the <particulars>
. So, let’s add content-visibility
to our listing of transitions:
::details-content {
transition: top 0.5s ease, content-visibility 0.5s ease allow-discrete;
top: 0;
overflow: clip;
}
/* Browser helps interpolate-size */
@helps (interpolate-size: allow-keywords) {
:root {
interpolate-size: allow-keywords;
}
[open]::details-content {
top: auto;
}
}
That’s significantly better:
Be aware the allow-discrete
key phrase which we have to set since content-visibility
is a property that solely helps discrete animations and transitions.
Fascinating tips
Chris has a demo that makes use of <particulars>
as a system for floating footnotes in content material. I forked it and added the identify
attribute to every footnote in order that they shut when one other one is opened.
I discussed John Rhea’s “Pop(over) The Balloons” sport on the prime of those notes:
Bramus with a slick-looking horizontal accordion forked from one other instance. Be aware how the <particulars>
ingredient is used as a flex container:
Chris with one other intelligent trick that makes use of <particulars>
to play and pause animated GIF picture information. It’s doesn’t really “pause” however the impact makes it look like it does.
Ryan Trimble with styling <particulars>
as a dropdown menu after which utilizing anchor positioning to set the place the content material opens.
References
- HTML Dwelling Customary (Part 4.11.1) by WHATWG
- “Fast Reminder that Particulars/Abstract is the Best Manner Ever to Make an Accordion” by Chris Coyier
- “A (horrible?) strategy to do footnotes in HTML” by Chris Coyier
- “Utilizing
<particulars>
for Menus and Dialogs is an Fascinating Thought” by Chris Coyier - “Pausing a GIF with particulars/abstract” by Chris Coyier
- “Exploring What the Particulars and Abstract Components Can Do” by Robin Rendle
- “Extra Particulars on
<particulars>
“ by Geoff Graham - “
::details-content
“ by Geoff Graham - “Extra choices for styling
<particulars>
“ by Bramus - “Easy methods to Animate the Particulars Component Utilizing WAAPI” by Louis Hoebregts
- “Particulars and abstract” by internet.dev
Utilizing & Styling the Particulars Component initially revealed on CSS-Methods, which is a part of the DigitalOcean household. It is best to get the e-newsletter.
Subscribe to MarketingSolution.
Receive web development discounts & web design tutorials.
Now! Lets GROW Together!