{"id":7019,"date":"2025-08-26T19:15:23","date_gmt":"2025-08-27T00:15:23","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=7019"},"modified":"2025-08-26T19:15:24","modified_gmt":"2025-08-27T00:15:24","slug":"opening-a-details-element-from-the-url","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/opening-a-details-element-from-the-url\/","title":{"rendered":"Opening a Details Element from the URL"},"content":{"rendered":"\n<p>Say you&#8217;ve got a page with a bunch of <code>&lt;details&gt;<\/code> elements on it. <\/p>\n\n\n\n<p>Your goal is to be able to send someone to that page with <em>one particular details element open.<\/em><\/p>\n\n\n\n<p>I was doing just this recently, and my first thought was to do it server-side. If the URL was like <code>website.com\/#faq-1<\/code> I&#8217;d see if <code>faq-1<\/code> matches an ID of the details element and I&#8217;d put the open attribute on it like <code>&lt;details id=\"faq-1\" open><\/code>. But no, you don&#8217;t get to have the <code>#hash<\/code> as part of the URL server side (for whatever reason \ud83e\udd37\u200d\u2640\ufe0f). <\/p>\n\n\n\n<p>Then I started writing JavaScript to do it, where you definitely can access the hash (<code>window.location.hash<\/code>). I&#8217;d just <code>querySelector<\/code> for the hash and if I found a matching details element, I&#8217;d open it up.<\/p>\n\n\n\n<p>Then I was reminded you don&#8217;t need to do this at all. What you need is (drumroll)&#8230; HTML. <\/p>\n\n\n\n<p>The trick is hash-linking to an element <em>inside<\/em> the <code>&lt;details><\/code>. So like:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">details<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">summary<\/span>&gt;<\/span>What was Rosebud in Citizen Kane?<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">summary<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"faq-1\"<\/span>&gt;<\/span>A sled.<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">details<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now, if you hash-link to <code>#faq-1<\/code>, the browser will know that it <em>has<\/em> to open that <code>&lt;details><\/code> in order for it to be seen, so it does. You don&#8217;t normally <em>need<\/em> a <code>&lt;div><\/code> wrapper or anything inside the <code>details<\/code> element, but we&#8217;re doing it here as it&#8217;s obviously handy.<\/p>\n\n\n\n<p>Here&#8217;s a demo of a page that is set up in this way:<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_0198e89f-8650-7d35-8384-959dbdbaf2e1\" src=\"\/\/codepen.io\/editor\/anon\/embed\/0198e89f-8650-7d35-8384-959dbdbaf2e1?height=450&amp;theme-id=1&amp;slug-hash=0198e89f-8650-7d35-8384-959dbdbaf2e1&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed 0198e89f-8650-7d35-8384-959dbdbaf2e1\" title=\"CodePen Embed 0198e89f-8650-7d35-8384-959dbdbaf2e1\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>It&#8217;s probably more interesting to just <a href=\"https:\/\/es-d-4410775920250828-0198e89f-8650-7d35-8384-959dbdbaf2e1.codepen.dev\/#faq-13-content\">visit this hash-link URL<\/a> and see it open right up and work.<\/p>\n\n\n\n<p>This came up for me while working on <a href=\"https:\/\/blog.codepen.io\/docs\/pens\/blocks\/all-blocks\/#babel-details-default-config-code\">this documentation page<\/a> where I wanted to be able to link to specific things that were otherwise &#8220;buried&#8221; in details elements. <\/p>\n\n\n\n<p>As a bit of an enhancement, you might want to consider CSS like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-pseudo\">:target<\/span> {\n  <span class=\"hljs-attribute\">background<\/span>: yellow;\n  <span class=\"hljs-attribute\">scroll-margin-block-start<\/span>: <span class=\"hljs-number\">4rem<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>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.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If the #hash in the URL matches the ID of an element *inside* a <\/p>\n<details> element, it&#8217;ll open. No other fancy code required.<\/p>\n","protected":false},"author":1,"featured_media":7039,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[7,211,31,110],"class_list":["post-7019","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-css","tag-details","tag-html","tag-urls"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/08\/details-open.jpg?fit=2100%2C1074&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/7019","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=7019"}],"version-history":[{"count":4,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/7019\/revisions"}],"predecessor-version":[{"id":7040,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/7019\/revisions\/7040"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/7039"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=7019"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=7019"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=7019"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}