Styling the HTML details and summary elements


Is this accordion built with the details and summary elements?
Yes.
Will find-in-page open the relevant details element?
Yes, at least in Chrome/Microsoft Edge. Try searching for this text when this section is closed. The browser's find-in-page search will automatically open the relevant section of the accordion. You do not need to manually add hidden="until-found" as that behaviour is the default.
Do URL text fragments work?
In Chrome and Edge, URL text fragments will automatically open the relevant details element. Try pressing the link below when this section is closed.

URL text fragment link

By default, without any custom styles applied, the <details> and <summary> elements looks like this:

SummaryLorem ipsum dolor sit amet consectetur adipisicing elit.

Firefox, Chrome/Edge and the forthcoming Safari 18.4 give the summary element a default display value of list-item. That means the ::marker selector can be used to style the default triangle icon, or to replace it via the content property.

summary::marker {
    content: url('/chevron-down.svg');
}

The limitations of ::marker

The ::marker pseudo-element only supports a limited set of CSS properties:

  • All font properties
  • white-space
  • color
  • text-combine-upright
  • unicode-bidi
  • direction
  • content
  • Animation and transition properties

This makes accurately positioning a custom icon practically impossible.

Safari supports ::marker, but unlike other browsers, does not support the content property when using this selector. Customization of the default icon is severely limited. A better approach is to hide the default icon and make use of ::before or ::after, which offer far more stylistic flexibility.

Hiding the default icon

The display property is not supported for ::marker, so ::marker { display: none; } will not work. Safari does not support the content property for ::marker so content: "" will not work in that browser. By default, <summary> is set to display: list-item. Setting display to any other value removes the marker:

summary {
    display: flex;
}

The following also works:

summary {
    list-style-type: none;
}

Some older browsers require the following code:

summary::-webkit-details-marker {
  display: none;
  margin-inline-end: 0;
}

A custom icon with ::before or ::after

Once the default icon is removed, ::before or ::after can be used to set a custom icon.

summary::after {
    content: url('/chevron-down.svg');
}

Unlike ::marker, ::before and ::after offer full stylistic versatility.