Say you’ve got a page with a bunch of <details>
elements on it.
Your goal is to be able to send someone to that page with one particular details element open.
I was doing just this recently, and my first thought was to do it server-side. If the URL was like website.com/#faq-1
I’d see if faq-1
matches an ID of the details element and I’d put the open attribute on it like <details id="faq-1" open>
. But no, you don’t get to have the #hash
as part of the URL server side (for whatever reason 🤷♀️).
Then I started writing JavaScript to do it, where you definitely can access the hash (window.location.hash
). I’d just querySelector
for the hash and if I found a matching details element, I’d open it up.
Then I was reminded you don’t need to do this at all. What you need is (drumroll)… HTML.
The trick is hash-linking to an element inside the <details>
. So like:
<details>
<summary>What was Rosebud in Citizen Kane?</summary>
<div id="faq-1">A sled.</div>
</details>
Code language: HTML, XML (xml)
Now, if you hash-link to #faq-1
, the browser will know that it has to open that <details>
in order for it to be seen, so it does. You don’t normally need a <div>
wrapper or anything inside the details
element, but we’re doing it here as it’s obviously handy.
Here’s a demo of a page that is set up in this way:
It’s probably more interesting to just visit this hash-link URL and see it open right up and work.
This came up for me while working on this documentation page where I wanted to be able to link to specific things that were otherwise “buried” in details elements.
As a bit of an enhancement, you might want to consider CSS like this:
:target {
background: yellow;
scroll-margin-block-start: 4rem;
}
Code language: CSS (css)
That will apply some styling to the element that matches the hash in the URL, as well as push it away from the top edge of the browser window a little bit. In this case, it helps make sure the FAQ question is actually visible, not just the answer.