10
votes

I am trying to add additional toggleable section that user can show and hide.

My requirements:

  • supported on major browsers (Opera, Chrome, Edge, IE11, Firefox, Safari on Mac)
  • no javascript

And was thinking of using the <details> tag, however the code

<details>
  <summary>Toggle</summary>
  <p>Hideable</p>
</details>

does not work on the Edge / IE browsers.

Can I anyhow "make" it work, or is there anything else I can use for that task? Hacks are OK, as long as no javascript is present.

3
:target or :checked come to mind, if adding the necessary additional elements (a link for the former, or a checkbox + label for the latter) is not a problem. sitepoint.com/css3-vertical-accordion-using-target-selector, geoffgraham.me/css-only-accordion-using-the-checkbox-hack explain the basic principles behind both techniques.CBroe
@CBroe so cool, I wouldn't think of it. My guess is that you should publish it as an answer.wscourge

3 Answers

13
votes

You can add a polyfill once on a page to make all the <details/>s on the page work:

<!-- Inside the body -->
<script src="//cdn.jsdelivr.net/npm/details-polyfill@1/index.min.js" async></script>

I know this is a JS solution but it doesn't require writing any JS for each individual <details/>. It can be used with a text written in a WYSIWYG editor.

7
votes

This would be the suggested :checked method utilizing a hidden checkbox:

.toggler {
  display: none;
}

.toggler+.toggler-content {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: all .4s ease-in-out;
}

.toggler:checked+.toggler-content {
  max-height: 1000px;
  opacity: 1;
}
<div>
  <label for="toggler-id-1">Toggle</label>
  <input type="checkbox" id="toggler-id-1" class="toggler" />
  <div class="toggler-content">Hideable</div>
</div>

I would still prefer going with @Finesse's solution because it allows you to use the semantically correct HTML element for the purpose.

-3
votes

Copy the below script and put it in a js file and then import it or write it directly in tags. This worked for me.

!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()}(0,function(){var o="details",i="summary";(function(){var e=document.createElement(o);if(!("open"in e))return!1;e.innerHTML="<"+i+">a</"+i+">b",document.body.appendChild(e);var t=e.offsetHeight;e.open=!0;var n=t!=e.offsetHeight;return document.body.removeChild(e),n})()||(document.documentElement.className+=" no-details",window.addEventListener("click",function(e){if("summary"===e.target.nodeName.toLowerCase()){var t=e.target.parentNode;if(!t)return;t.getAttribute("open")?(t.open=!1,t.removeAttribute("open")):(t.open=!0,t.setAttribute("open","open"))}}),function(e,t){if(document.getElementById(e))return;var n=document.createElement("style");n.id=e,n.innerHTML=t,document.getElementsByTagName("head")[0].appendChild(n)}("details-polyfill-style","html.no-details "+o+":not([open]) > :not("+i+") { display: none; }\nhtml.no-details "+o+" > "+i+':before { content: "▶"; display: inline-block; font-size: .8em; width: 1.5em; }\nhtml.no-details '+o+"[open] > "+i+':before { content: "▼"; }'))});

If you don't want that arrows then just remove this part from end

+o+" > "+i+':before { content: "▶"; display: inline-block; font-size: .8em; width: 1.5em; }\nhtml.no-details '+o+"[open] > "+i+':before { content: "▼"; }'