Create a CSS Toggle Button with the <details> Element
Overview
If for some reason you can't use JavaScript, the following workaround is your best bet to create a toggle button. The <details>
HTML element creates a disclosure widget to hide and show content. We're going to (ab)use the <details>
element and some CSS, so let's call it the "details hack".
How it works
Here's a basic example.
CSS
details[open] summary {
color: red;
}
HTML
<details>
<summary>Toggle</summary>
</details>
Result
Toggle
Clicking the <summary>
element toggles the <details>
' open
attribute and the <summary>
's style. You can also toggle the style of the <details>
' next siblings.
CSS
details[open] summary {
color: red;
}
details[open] ~ p {
color: blue;
}
HTML
<details>
<summary>Toggle</summary>
</details>
<p>Hello, world!</p>
Result
Toggle
Hello, world!
An advantage of this method over the checkbox hack is that the button is keyboard accessible.
Notes
- The
<summary>
's contents can be any heading content, plain text, or HTML that can be used within a paragraph. - The
<summary>
'sdisplay
default value islist-item
. To remove the list item's triangle::marker
, change the value toinline-flex
, for example.summary { display: inline-flex; }
Alternatively, you may use one of the following rules:summary { list-style: none; }
summary::marker { content: none; }
To remove the disclosure triangle in Safari, use the following as well:summary::-webkit-details-marker { display: none; }
More examples
The following demos show the details hack's potential and give you an idea of how to use it.
Replace an element
CSS
summary {
display: inline-block;
cursor: default;
}
summary::-webkit-details-marker {
display: none;
}
span {
display: inline-block;
padding: 8px 24px;
border-radius: 10px;
background: linear-gradient(#eee, #ddd);
color: #333;
font: bold 72px monospace;
text-shadow: 0 1px white;
}
#on,
details[open] #off {
display: none;
}
details[open] #on {
display: inline-block;
}
HTML
<details>
<summary><span id="off">0</span><span id="on">1</span></summary>
</details>
Result
Replace an element with transition
CSS
summary {
display: inline-flex;
cursor: pointer;
}
summary::-webkit-details-marker {
display: none;
}
img {
transition: 0.3s linear;
}
[alt="Light off"] {
position: absolute;
}
[alt="Light on"],
details[open] [alt="Light off"] {
visibility: hidden;
opacity: 0;
}
details[open] [alt="Light on"] {
visibility: visible;
opacity: 1;
}
HTML
<details>
<summary><img src="light-off.png" width="100" height="180" alt="Light off"><img src="light-on.png" width="100" height="180" alt="Light on"></summary>
</details>
Result
A toggle switch
CSS
summary {
display: inline-block;
padding: 16px 32px;
border-radius: 16px;
background: radial-gradient(circle 12px, white 100%, transparent calc(100% + 1px)) #ccc -16px;
transition: 0.3s ease-in-out;
}
summary::-webkit-details-marker {
display: none;
}
details[open] summary {
background-color: dodgerBlue;
background-position: 16px;
}
HTML
<details>
<summary></summary>
</details>
Result
Multiple buttons
CSS
details,
summary {
display: inline-flex;
}
summary {
padding: 8px 12px;
border-radius: 5px;
background: linear-gradient(#eee, #ddd);
color: #333;
font: bold 1rem monospace;
text-shadow: 0 1px white;
cursor: default;
}
summary::-webkit-details-marker {
display: none;
}
details#italic summary,
details#italic[open] ~ p {
font-style: italic;
}
details#underline summary,
details#underline[open] ~ p {
text-decoration: underline;
}
details#theme {
float: right;
}
details#theme summary::before {
content: '☀️';
margin-right: 0.5em;
}
details[open]:not(#theme) summary {
background: dodgerBlue;
color: white;
text-shadow: 0 1px black;
}
details#theme[open] summary::before {
content: '🌙';
}
details#bold[open] ~ p {
font-weight: bold;
}
details#theme[open] ~ p {
background: #333;
color: white;
}
p {
font: 1em/1.5 Arial;
padding: 1em;
border: 1px solid #dedede;
border-radius: 5px;
}
HTML
<details id="bold">
<summary>B</summary>
</details>
<details id="italic">
<summary>I</summary>
</details>
<details id="underline">
<summary>U</summary>
</details>
<details id="theme">
<summary>Theme</summary>
</details>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
Result
B
I
U
Theme
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.