How they made controls at Github? Modal dialog
Kiran Mantha
Posted on January 5, 2022
- Episode1: Dropdown
- Episode2: Modal dialog
- Episode3: Hamburger menu
- Episode4: Popup
Recap
In previous episode we saw how to create a dropdown using details and summary tags.
Present
In this episode let's see how to create a modal dialog out of details and summary tags.
When we say modal dialog, it should contain 2 main things.
- an overlay
- a container to display content
let's start with html
<details role='dialog'>
<summary>click me to open a dialog</summary>
<div>I'm in a dialog. click outside to close me.</div>
</details>
when rendered, this displays in an accordion fashion. so let's style it to look like a dialog.
:root {
--border-color: #ccc;
--spacing: 1rem;
--primary: #fff;
}
details[role='dialog'] {
display: inline-block;
summary {
cursor: pointer;
border: 1px solid var(--border-color);
padding: 10px;
}
summary + div {
position: fixed;
top: 0;
left: 50%;
transform: translateX(-50%);
margin: calc(var(--spacing) * 2) auto;
width: 500px;
background-color: var(--primary);
z-index: 2;
padding: var(--spacing);
}
}
all is good. The dialog says click outside to close me
. heck but where is the overlay?? π
you know the secret sauce for this in last episodeββ
tadaaaaa
&[open] summary {
&::before {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
display: block;
cursor: default;
content: ' ';
background-color: rgba(0, 0, 0, 0.5);
}
}
yeahh got it?? but small change. In last episode, the background-color
of summary
tag is transparent but here in order to give user a sense of overlay we slapped color to background.
Now let's see the entire css:
:root {
--border-color: #ccc;
--spacing: 1rem;
--primary: #fff;
}
details[role='dialog'] {
display: inline-block;
summary {
cursor: pointer;
border: 1px solid var(--border-color);
padding: 10px;
}
&[open] summary {
&::before {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
display: block;
cursor: default;
content: ' ';
background-color: rgba(0, 0, 0, 0.5);
}
}
summary + div {
position: fixed;
top: 0;
left: 50%;
transform: translateX(-50%);
margin: calc(var(--spacing) * 2) auto;
width: 500px;
background-color: var(--primary);
z-index: 2;
padding: var(--spacing);
}
}
That's it. see how simple it is to create a modal dialog?? But this implementation got its own caveats:
- you can't stop closing the dialog when user clicks outside. So if you intend to use it, then use it for info dialogs where you just display some static content.
Protips
Tip:1
when you say modal dialog, you need some handlers to do some actions after dialog opens and after it is closed. Don't worry i got you covered. Details
tag has ontoggle
event which helps us in such scenerios.
detailsTag.addEventListener('toggle', () => {
if(detailsTag.open) {
// do operation when dialog opens
} else {
// do operation when dialog closed
}
})
Tip:2
let's say you need to disable backdrop click to close the dialog. In that case, add a data attribute data-disableBackdropClick
to summary tag and add a little more css to summary tag when dialog has open
attribute. this is how the html and css looks:
<details id='backdropDetails' role="dialog">
<summary data-disableBackdropClick="true">click to open a dialog</summary>
<div>
i'm in a dialog. i cannot be closed by clicking outside and need javascript to close me.
<button id='modalCloseButton'>close me</button>
</div>
</details>
....
&[open] summary[data-disableBackdropClick="true"] {
pointer-events: none;
}
....
that's it. now try to click outside the modal. it won't close. Now how to close this dialog. At last we need some javascript to get this done.
const closeButton = document.getElementById('modalCloseButton'),
backdropDetails = document.getElementById('backdropDetails');
closeButton.onclick = function () {
backdropDetails.open = false;
};
yayyyy. now whenever you click on that button, the modal will close but it will not close when you click outside of modal.
Asusual you can find the working example here.
See you in next episode. Thanks..
Kiran π
Posted on January 5, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.