Replace the expand ( ▶) icon of HTML5 details tag
According to MDN’s section on the topic, customising the disclosure marker, the standards-compliant way to do this is via the list-style
CSS property, since <details>
tags have display: list-item
applied to them.
Unfortunately Chrome does not support this (yet), and requires customisation via the -webkit-details-marker
pseudo-element.
To make styling easy and consistent across browsers, you can hide both the list-item marker and the WebKit marker, and then add the actual icon in the ::before
pseudo-element:
details > summary {
list-style-type: none;
}
details > summary::-webkit-details-marker {
display: none;
}
details > summary::before {
content: '▶️';
}
details[open] > summary::before {
content: '';
}
details {
border: 1px solid gray;
border-radius: 0.2rem;
padding: 0.5rem;
}
details[open] > summary {
margin-bottom: 0.5rem;
}
<details>
<summary>An example</summary>
With some example text shown when expanded.
</details>
In principle the same can be achieved more directly via the ::marker
pseudo-element; unfortunately support continues to be sketchy.
Is it possible to set a picture instead of the existing characters?
This is certainly possible ─ setting the baskground image to your icon and setting the original marker's colour to transparent will produce this effect.
Example:
details summary::-webkit-details-marker {
background: url(/images/toggle-expand.png) center no-repeat;
color: transparent;
}
details[open] summary::-webkit-details-marker {
background: url(/images/toggle-collapse.png) center no-repeat;
color: transparent;
}
This only works in Webkit browsers and Chrome. You might want to consider rotating the icon instead of replacing it with a different one, in which case you can use the following:
summary::--webkit-details-marker {
transform: rotate(-90deg);
}
details[open] summary::--webkit-details-marker {
transform: rotate(0deg);
}
[dir="rtl"] summary::--webkit-details-marker {
transform: rotate(90deg);
}
[dir="rtl"] details[open] summary::--webkit-details-marker {
transform: rotate(0deg);
}
This solution rotates the icon if it is originally pointing downwards. It also factors in details
elements that are within RTL parents; though be careful with this approach if mutliple text directions are used throughout the document.