modal ๊ณผ popover ๋ฅผ API ๋ก ์ ๊ณตํ๋ค๋ ๊ฒ์ ์ต๊ทผ์ ์์๋ค. ๊ทธ ์ ๊น์ง๋ ์ฝ๋๋ก ๊ตฌํ์ ํ์๋๋ฐ..

Dialog
developer.mozilla.org
<dialog> HTML dialog element - HTML | MDN
The <dialog> HTML element represents a modal or non-modal dialog box or other interactive component, such as a dismissible alert, inspector, or subwindow.
<button id="open-btn">์ค์ ์ด๊ธฐ</button>
<dialog id="settings-dialog">
<form method="dialog">
<h3>์ค์ </h3>
<p>๋ณ๊ฒฝ์ฌํญ์ ์ ์ฅํ์๊ฒ ์ต๋๊น?</p>
<button value="cancel">์ทจ์</button>
<button value="confirm">ํ์ธ</button>
</form>
</dialog>
<script>
const dialog = document.querySelector('#settings-dialog');
document.querySelector('#open-btn').addEventListener('click', () => {
dialog.showModal(); // Top Layer ๋ชจ๋ฌ ๋์ฐ๊ธฐ
});
</script>
<dialog> ๋ showModal()๊ณผ show() ๋ฅผ ํตํด ๋ชจ๋ฌ๊ณผ ๋น๋ชจ๋ฌ ์ํ๋ฅผ ๋ช
ํํ ๋ถ๋ฆฌํ๋ค. ๋ชจ๋ฌ๋ก ๋์ฐ๋ฉด ์ํธ์์ฉ์ด ๋๋ ๋๊น์ง ์ธ๋ถ ์
๋ ฅ์ด ์ฐจ๋จ๋๋ค.
| ๊ธฐ์ค | showModal() | show() |
|---|---|---|
| ๋ชจ๋ฌ ์ฌ๋ถ | ๋ชจ๋ฌ (์ธ๋ถ ํด๋ฆญ/์ ๋ ฅ ์ฐจ๋จ) | ๋น๋ชจ๋ฌ (์ธ๋ถ ํด๋ฆญ/์ ๋ ฅ ํ์ฉ) |
| ๋ ์ด์ด ์์น | ๋ธ๋ผ์ฐ์ ์ต์์ Top Layer | ์ผ๋ฐ DOM ๋ ์ด์ด |
| ๋ฐฐ๊ฒฝ ์์ | ::backdrop ์์ฌ ์์ ์ ๊ณต | ๋ฐฑ๋๋กญ ์์ |
| ํฌ์ปค์ค ์ด๋ | ๋ด๋ถ๋ก ํฌ์ปค์ค ์๋ ์ด๋ ๋ฐ ๊ฐ๋ | ํฌ์ปค์ค ์ด๋ ์์ |
<form method="dialog">๋ฅผ ๋ด๋ถ์ ์ฌ์ฉํ๋ฉด, ํผ ๋ด๋ถ์ ๋ฒํผ์ ๋๋ฅผ ๋ ์ฝ๋ ์์ฑ ์์ด๋ ๋ค์ด์ผ๋ก๊ทธ๊ฐ ์๋์ผ๋ก ๋ซํ๋ค. ๋ฒํผ์ value๊ฐ dialog.returnValue๋ก ์ ๋ฌ๋๋ ๊ตฌ์กฐ.
Dialog ๋ฐฐ๊ฒฝ ํด๋ฆญ ์ ๋ซ๊ธฐ
๋ชจ๋ฌ ๋ค์ด์ผ๋ก๊ทธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก Esc ํค๋ก ๋ซํ์ง๋ง, ๋ฐฐ๊ฒฝ ์ชฝ ::backdrop ์ ๋๋ ์ ๋ ์๋์ผ๋ก ๋ซํ์ง๋ ์๋๋ค. ๋ฐฐ๊ฒฝ ํด๋ฆญ ๋ซ๊ธฐ๋ฅผ ๊ตฌํํ๋ ค๋ฉด ๋ค์ด์ผ๋ก๊ทธ์ ํด๋ฆญ ์ด๋ฒคํธ์์ ๋ฐฐ๊ฒฝ ํด๋ฆญํ ๊ฑธ ์์ญ์ ๊ณ์ฐํด ํ๋ณํด์ผ ํ๋ค.
dialog.addEventListener('click', (event) => {
const rect = dialog.getBoundingClientRect();
const isClickOutside = (
event.clientX < rect.left ||
event.clientX > rect.right ||
event.clientY < rect.top ||
event.clientY > rect.bottom
);
if (isClickOutside) {
dialog.close();
}
});
Popover
developer.mozilla.org
Popover API - Web APIs | MDN
The Popover API provides developers with a standard, consistent, flexible mechanism for displaying popover content on top of other page content. Popover content can be controlled either using HTML attributes, or via JavaScript.
<!-- ๋ฒํผ์ popovertarget ์ง์ -->
<button popovertarget="profile-menu">ํ๋กํ ๋ฉ๋ด</button>
<!-- ํ์ค๋ฒ ๋์ ์์ -->
<div id="profile-menu" popover>
<button type="button">ํ๋กํ ์์ </button>
<button type="button">๋ก๊ทธ์์</button>
</div>
popover ์์ฑ์ ํ๊ทธ ์์๊ฐ ์๋๋ผ ์ด๋ค ์์์๋ ๋ถ์ผ ์ ์๋ ์ ์ญ ์์ฑ์ด๋ค. ๋ฒํผ์ popovertarget๊ณผ ์กฐํฉํ๋ฉด ์ฝ๋ ํ ์ค ์์ด๋ ๋๋กญ๋ค์ด์ด๋ ํดํ์ ๋์ธ ์ ์๋ค.
- ๊ธฐ๋ณธ ๋์์
popover="auto"๋ก ์ธ๋ถ ๋ฐ๊นฅ ์์ญ์ ํด๋ฆญํ๊ฑฐ๋Escํค๋ฅผ ๋๋ฅด๋ฉด ๋ธ๋ผ์ฐ์ ๊ฐ ์์์ ํ์ค๋ฒ๋ฅผ ๋ซ์์ค๋ค. - ์ฌ๋ฌ ํ์ค๋ฒ๋ฅผ ๋์์ ๋์ฐ๊ธฐ. ๋ฐ๊นฅ ํด๋ฆญ์ผ๋ก ๋ซํ์ง ์์์ผ ํ ๋.
popover="manual"๋ก ์ค์ - ๋ถ๋ชจ์
overflow: hidden์ด๋z-indexStacking Context ์ ๊ฐํ์ง ์๊ณ ํญ์ ์ต์์ ๋ ์ด์ด์ ๋จ๊ฒ ๋จ
Anchor Positioning
developer.mozilla.org
CSS anchor positioning - CSS | MDN
The CSS anchor positioning module defines features that allow you to tether elements together. Certain elements are defined as anchor elements; anchor-positioned elements can then have their size and position set based on the size and location of the anchor elements to which they are bound.
ํ์ค๋ฒ๋ฅผ ์ด ๋ ์ค์ํ ๊ฒ ํธ๋ฆฌ๊ฑฐ ๋ฐ๋ก ์๋์ ํ์ค๋ฒ๋ฅผ ์์น์ํค๋ ๊ฒ์ด์๋ค. Anchor Positioning์ ์ฌ์ฉํ๋ฉด ํ์ค๋ฒ ์์น๋ฅผ ์์ CSS๋ก ๊ธฐ์ค ๋ฒํผ์ ๊ณ ์ ํ ์ ์๋ค.
/* ๊ธฐ์ค ๋ฒํผ์ ์ต์ปค ์ด๋ฆ ๋ถ์ฌ */
#menu-button {
anchor-name: --menu-btn;
}
/* ํ์ค๋ฒ ์์๋ฅผ ๊ธฐ์ค ๋ฒํผ ์๋์ ๊ณ ์ */
#profile-menu {
position: fixed;
position-anchor: --menu-btn;
top: anchor(bottom);
left: anchor(left);
margin-top: 4px;
}
<button id="menu-button" popovertarget="profile-menu">๋ฉ๋ด</button>
<div id="profile-menu" popover>ํ์ค๋ฒ ๋ด์ฉ</div>
์ธ์ ์ข์์ก๋ค..