We’ve mentioned before just how great the <details>
and <summary>
elements are. They’re great for quickly making accordions that are accessible to touch, mouse, and keyboard input:
<details>
and <summary>
can even be used to play/pause gifs! Click the pause button in the top right of this image to see it in action:
Neat, eh? But what else can these elements do? For a long while, I’ve only thought about details
as a way to make accordions. But the other day I started thinking about it a little bit, and the first thing I realized was maybe we could make better footnotes with them.
Here’s we typically make footnotes today with just HTML:
Clicking a link in a paragraph it pushes you to the bottom of the page where the description of the footnote is. And we do that by linking to the ID of elements back and forth. But! There are jQuery plugins like BigFoot out there that let you have footnotes inline.
Here’s that same example with the BigFoot script and jQuery applied to it:
Neat huh? BigFoot takes our accessible markup, removes all that link stuff, and throws it right inline as a little button and tooltip thing.
But what if we could use <details>
and <summary>
to replace this jQuery and plain ol’ HTML for our footnotes? Well, sadly, we can’t. If you try to place either of these elements within a <p>
tag, browsers render those elements outside the <p>
element:
Blah! This is annoying but I sorta get why it works like this. It would be great if we could replace the complexity of all these links and the crappy experience of hopping up and down the page. But we can’t.
Well, if we can’t do that, then what else can we use <details>
and <summary>
for? This had me thinking… what about tooltips? Well, yes! We can absolutely do that. Let’s say that we have some markup like this that expands the date shown:
Pretty standard, we’ve seen this before. But now let’s get to the styling which is the interesting bit. First up, we need to tackle the <details>
element:
details {
border-radius: 3px;
cursor: pointer;
display: inline-block;
position: relative;
transition: 0.15s background linear;
}
details:hover,
details:focus {
background: #d4d1ec;
}
This lets us absolutely position the information within our details element but it also lets the tooltip feel a bit more like a button on click with the background. Next, we can undo the default arrow for the summary
element by doing this:
summary {
background: url("https://assets.codepen.io/14179/Info.svg") 11px 11.5px no-repeat;
list-style: none;
padding: 10px;
padding-left: 33px;
}
And finally, we need to absolutely position the paragraph that we have within the details
element. And make a tiny little triangle that points up to the rest of the tooltip:
details p {
cursor: auto;
background: #eee;
padding: 15px;
width: 250px;
position: absolute;
left: 0;
top: 35px;
border-radius: 4px;
right: 0;
}
// Tiny triangle that points up
details p:before {
content: "";
border-bottom: 12px solid #eee;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
height: 0;
left: 10px;
position: absolute;
top: -10px;
width: 0;
}
Which leads to something like this. Make sure to click the tooltip to see the description appear beneath it:
One nice thing we can do here to polish things up a tiny little bit is to add an animation when the tooltip is open:
details[open] p {
animation: animateDown 0.2s linear forwards;
}
@keyframes animateDown {
0% {
opacity: 0;
transform: translatey(-15px);
}
100% {
opacity: 1;
transform: translatey(0);
}
}
And there you have it! If you click the tooltip it’ll pop open and if you tab and click space then it’ll open up, too.
But we can take this a little further. Something we probably don’t want is a bunch of these tooltips opening up all over the place. If we’re using tooltips heavily then that could get super clumsy and visually distracting. What we need to do is close the tooltip when we click outside of it. And we can do that with some light JavaScript:
const tooltip = document.querySelector(".tooltip");
document.addEventListener("click", function (e) {
var insideTooltip = tooltip.contains(e.target);
if (!insideTooltip) {
tooltip.removeAttribute("open");
}
});
Now when you click off the tooltip it’ll close it. Neato!
The <details>
and <summary>
elements can’t do everything but they can certainly do a lot of handy things — and I reckon that there’s a lot more this combination of elements can do. We just have to go find them. In fact, here are some more great posts on the topic.
Setting
list-style: none;
on<summary>
won’t remove default rectangle in Chrome (at least as of Chrome 87).In order to achieve it you should use non-standard
::-webkit-details-marker
pseudo-element:In principle, the
<details>
-tag can be used whenever we need true/false-state, like the “checkbox”-hack, but we probably shouldn’t!I recently used it to play/pause an animation – just for fun:
I’ve used it for “Toggle Tips” too:
https://codepen.io/stoumann/full/abZXxPx
As you indirectly mention in the article, the
[open]
-state can only be animated usinganimation
, nottransition
, so:details[open] p
will not do anything if using atransition
.I wonder if you or anyone else here knows why?!
The little triangle still shows in the tooltip example on android Chrome.
Love the tooltip idea! I’ve been using details for dropdown menus, which are similar. I also use a little CSS Trick (no-JS!) for closing them when you click outside the menu. I think I picked that up from inspecting the menus on GitHub? It uses generated content on the summary to create a full-window click target:
You also need to adjust z-index relative to the content of the menu.
While I like the visual representation of the tooltip on click, isn’t it a bad idea to add the need for an extra click rather than just show the information on hover?
Hovering over the “3 days ago” text is (to me at least) a strong indicator that the user requests that specific data anyways, why not just show it then?
Note: I acknowledge that this specific mechanic could be used for showing more elaborate content in other situations so I’m not diminishing the idea itself. I just think it’s a rather bad use case here :-)
For the tooltip example, in Chrome and Safari, the animation only plays the first time you open it. Afterwards, it goes back to just popping in and out. It does seem to work correctly in Firefox.
Is there some animation setting to fix this?