Using tag details is a simple way to build a collapse with no javascript needed.
HTML Studies
Detail Tag
This is closed by default
Example paragraph content
When opened, the attribute open is inserted in details tag
This is open by default
Example paragraph content
Everything outside summary tag will collpase
<details>
<summary>
<strong>This is closed by default</strong>
</summary>
<p>Example paragraph content</p>
<p>When opened, the attribute <strong>open</strong> is added in <strong>detail tag</strong></p>
</details>
<details open>
<summary>
<strong>This is open by default</strong>
</summary>
<p>Example paragraph content</p>
<p>Everything outside <strong>summary tag</strong> will collapse<</p>
</details>
Batman is
.details-customized {
> summary {
&:first-of-type {
list-style-image: url(../../assets/sections/details/batman-serious.png);
}
strong {
font-size: 2rem;
&:after {
content: "watching";
}
}
}
&[open] {
> summary {
&:first-of-type {
list-style-image: url(../../assets/sections/details/batman-grimace.png);
}
strong:after {
content: "... ... what!";
}
}
}
}
Dialog (Modal)
HTML now provides a incredible way to create modals using dialog tag. Everything inside dialog is hidden by default and became acessible throught javascript.
When opened, Dialog is referenced inside documents top layer outside HTML, staying on top of all elements, regardless of z-index used.
Dialog tag has also native acessibility features, like preventing focus on elements outside and can be closed using ESC key without javascript.
Dialog has also incredible Javascript event features, like on open, on close and on toggle. See documentation
<button onclick="openRawDialog()">Open Dialog</button>
<dialog id="rawDialog">
<h1>Dialog Modal</h1>
<p>This is a native HTML Dialog</p>
...
<button onclick="closeRawDialog()">Close</button>
</dialog>
let rawDialog = document.querySelector('#rawDialog');
function openRawDialog() {
rawDialog.showModal();
}
function closeRawDialog() {
rawDialog.close();
}
<button onclick="openCustomDialog()">Open Custom Dialog</button>
<dialog id="customDialog">
<div class="dialog-header">
<h1>Custom Dialog Modal</h1>
</div>
<div class="dialog-body">
...
</div>
<div class="dialog-footer">
<button onclick="closeCustomDialog()">Close</button>
</div>
</dialog>
#customDialog[open] {
--margin-block-start: 12rem;
--margin-block-end: 3rem;
--margin-inline: 10rem;
&::backdrop {
background-color: darkslateblue;
opacity: 0.5;
}
display: flex;
flex-direction: column;
width: min(80rem, 100%);
max-height: calc(100% - var(--margin-block-start) - var(--margin-block-end));
border: 2px solid var(--green-dark);
border-radius: 1rem;
margin-block-start: var(--margin-block-start);
margin-block-end: var(--margin-block-end);
padding: 0 2rem;
min-height: 35dvh;
.dialog-header,
.dialog-body,
.dialog-footer {
padding: 2rem 0;
}
.dialog-header {
border-bottom: 1px solid var(--green);
h1 {
margin: 0;
font-size: 2.4rem;
font-weight: 400;
}
}
.dialog-body {
flex: 1;
}
.dialog-footer {
border-top: 1px solid var(--green);
text-align: end;
}
}
html:has(dialog[open]) {
overflow: hidden;
}
Popover
HTML Popover has some similarities with Dialog tag. It opens in document top layer over any element. Also can be closed with ESC key with the bonus to be also closed with Click Outside, by default.
Benefits: Any element can become a popover using popover attribute. And can be opened/closed through HTML atrributes.
Difficulties: You have to use Javascript to position it.
Popover has also incredible Javascript event features, just like Dialog. See documentation
This is a Default Popover
Like a Dialog, popover open in document top layer, standing over any element.
Different from Dialog, popover dont prevent tab to access elements outside popover, but has the native click outside and default ESC key to be closed.
<button popovertarget="rawPopover">Open Popover</button>
<div id="rawPopover">
...
</div>
This is a Custom Popover
Like a Dialog, popover can be fully customized, including its backdrop.
If you want to know how to position a popover relative to an element, like the button that opens popover, you will have to use Javascript. I almost build this example here, but it will become no more necessary, because the new CSS Anchor feature is coming, and will be possible to create a popover like this using only HTML and CSS.
I show how to do it here, in CSS Anchor section, but you will need Chrome Canary to see.
<button popovertarget="customPopover">Open Custom Popover</button>
<div id="customPopover">
...
</div>
#customPopover:popover-open {
width: clamp(0%, 60rem, 90%);
padding: 2rem;
border: 4px solid var(--green-dark);
&::backdrop {
backdrop-filter: blur(3px);
opacity: 0.7;
}
}