<dialog>: ëí ìì ìì
Baseline
Widely available
*
This feature is well established and works across many devices and browser versions. Itâs been available across browsers since â¨2022ë 3ìâ©.
* Some parts of this feature may have varying levels of support.
<dialog> HTML ììë ëª¨ë¬ ëë ë¹ëª¨ë¬ ëí ììë ë«ì ì ìë ì림창, ê²ì¬ê¸°, íì 창과 ê°ì ìí¸ìì© ê°ë¥í ì»´í¬ëí¸ë¥¼ ëíë
ëë¤.
HTML <dialog> ììë ëª¨ë¬ ë° ë¹ëª¨ë¬ ëí ìì를 ë§ëë ë° ì¬ì©ë©ëë¤. ëª¨ë¬ ëí ììë íì´ì§ì ëë¨¸ì§ ë¶ë¶ê³¼ ìí¸ìì©ì ì¤ë¨ìí¤ë ë°ë©´, ë¹ëª¨ë¬ ëí ììë íì´ì§ì ëë¨¸ì§ ë¶ë¶ê³¼ ìí¸ìì©ì íì©í©ëë¤.
<dialog> ìì를 íìíë ¤ë©´ JavaScript를 ì¬ì©í´ì¼ í©ëë¤. ëª¨ë¬ ëí ìì를 íìíë ¤ë©´ .showModal() ë©ìë를 ì¬ì©íê³ , ë¹ëª¨ë¬ ëí ìì를 íìíë ¤ë©´ .show() ë©ìë를 ì¬ì©í©ëë¤. ëí ììë .close() ë©ìë를 ì¬ì©íê±°ë <dialog> ìì ë´ì ì¤ì²©ë <form>ì ì ì¶í ë dialog ë©ìë를 ì´ì©íì¬ ë«ì ì ììµëë¤. ëª¨ë¬ ëí ììë Esc í¤ë¥¼ ëë¬ ë«ì ìë ììµëë¤.
í¹ì±
ì´ ììë ì ì í¹ì±ì í¬í¨í©ëë¤.
ê²½ê³ :
ì´ tabindex í¹ì±ì <dialog> ììì ì¬ì©íë©´ ì ë©ëë¤. ì¬ì© ì¼ëì ì°¸ê³ íì¸ì.
closedby-
<dialog>ìì를 ë«ë ë° ì¬ì©í ì ìë ì¬ì©ì ìì ì íì ì§ì í©ëë¤. ì´ í¹ì±ì ëí ìì를 ë«ì ì ìë ì¸ ê°ì§ ë°©ë²ì 구ë¶í©ëë¤.- ê°í¸ ë«ê¸° ì¬ì©ì ìì
. ì¬ì©ìê° ëí ìì ì¸ë¶ë¥¼ í´ë¦íê±°ë íí ë
<dialog>ê° ë«íëë¤. ì´ë "ìë" ìí íì¤ë²ì "ê°í¸ ë«ê¸°" ëìê³¼ ëì¼í©ëë¤. - íë«í¼ë³ ì¬ì©ì ìì . ë°ì¤í¬í± íë«í¼ìì Esc í¤ë¥¼ ë르거ë 모ë°ì¼ íë«í¼ìì "ë¤ë¡ ê°ê¸°" ëë "ë«ê¸°" ì ì¤ì²ì ê°ì ëìì ëë¤.
- ê°ë°ìê° ì§ì í ë©ì»¤ëì¦.
HTMLDialogElement.close()를 í¸ì¶íëclickí¸ë¤ë¬ê° ìë<button>ëë<form>ì ì¶ê³¼ ê°ì ë©ì»¤ëì¦ì ëë¤.
ê°ë¥í ê°ì ë¤ìê³¼ ê°ìµëë¤.
any-
ì¸ ê°ì§ ë°©ë² ì¤ ì´ë¤ ë°©ë²ì¼ë¡ë ëí ìì를 ë«ì ì ììµëë¤.
closerequest-
íë«í¼ë³ ì¬ì©ì ëì ëë ê°ë°ìê° ì§ì í ë©ì»¤ëì¦ì¼ë¡ ëí ìì를 ë«ì ì ììµëë¤.
none-
ê°ë°ìê° ì§ì í ë©ì»¤ëì¦ì¼ë¡ë§ ëí ìì를 ë«ì ì ììµëë¤.
<dialog>ììì ì í¨íclosedbyê°ì´ ì§ì ëì§ ìì ê²½ì°,showModal()ì ì¬ì©íì¬ ì´ìë¤ë©´"closerequest"ê°ì²ë¼ ëìí©ëë¤.- ê·¸ë ì§ ìì¼ë©´
"none"ê°ì²ë¼ ëìí©ëë¤.
- ê°í¸ ë«ê¸° ì¬ì©ì ìì
. ì¬ì©ìê° ëí ìì ì¸ë¶ë¥¼ í´ë¦íê±°ë íí ë
open-
ëí ììê° íì±íëì´ ìí¸ ìì©í ì ììì ëíë ëë¤.
opení¹ì±ì´ ì¤ì ëì§ ìì¼ë©´ ëí ììê° ì¬ì©ììê² íìëì§ ììµëë¤. ëí ìì를 ë ëë§íë ¤ë©´opení¹ì± ëì.show()ëë.showModal()ë©ìë를 ì¬ì©íë ê²ì´ ì¢ìµëë¤.opení¹ì±ì ì¬ì©íì¬<dialog>를 ì´ë©´ ë¹ëª¨ë¬ ìíê° ë©ëë¤.ì°¸ê³ : ì´
opení¹ì±ì ì¡´ì¬ ì¬ë¶ë¥¼ í ê¸íì¬ ë¹ëª¨ë¬ ëí ììì ì´ë¦¼ ë° ë«í ìí를 ì íí ì ìì§ë§, ì´ ì ê·¼ ë°©ìì ê¶ì¥ëì§ ììµëë¤. ìì¸í ë´ì©ìopenì 참조íì¸ì.
ì¬ì© ì¼ë
- HTML
<form>ììëmethod="dialog"í¹ì±ì´ ìê±°ë ìì ì ì¶ ë²í¼ìformmethod="dialog"ê° ì¤ì ë ê²½ì° ëí ìì를 ë«ë ë° ì¬ì©í ì ììµëë¤.<dialog>ë´ì<form>ì´dialogë©ìë를 íµí´ ì ì¶ëë©´ ëí ììê° ë«íê³ , í¼ ì»¨í¸ë¡¤ì ìíê° ì ì¥ëì§ë§ ì ì¶ëì§ë ìì¼ë©°,returnValueìì±ìë í´ë¦ë ë²í¼ì ê°ì´ ì¤ì ë©ëë¤. - CSS
::backdropìì¬ ìì를 ì¬ì©íì¬ ëª¨ë¬ ëí ììì ë°°ê²½ì ì¤íì¼ë§í ì ììµëë¤. ì´ ë°°ê²½ì ëí ìì를HTMLDialogElement.showModal()ë©ìë를 ì¬ì©íì¬ ëíë¼ ë<dialog>ìì ë¤ì íìë©ëë¤. ì를 ë¤ì´, ì´ ìì¬ ìì를 ì¬ì©íì¬ ëª¨ë¬ ëí ìì ë¤ì ìë ë¹íì± ì½í ì¸ ë¥¼ íë¦¬ê² íê±°ë, ì´ë¡ê² íê±°ë, ê°ë¦¬ë ë±ì ìì ì í ì ììµëë¤. - ëª¨ë¬ ëí ìì를 ì´ ë ì¬ì©ìê° ì¦ì ìí¸ ìì©í ê²ì¼ë¡ ììëë ììì
autofocusí¹ì±ì ì¶ê°í´ì¼ í©ëë¤. ë ì¦ê°ì ì¸ ìí¸ ìì©ì´ íìí ë¤ë¥¸ ììê° ìë ê²½ì°, ëí ìì ë´ì ë«ê¸° ë²í¼ìautofocus를 ì¶ê°íê±°ë, ì¬ì©ìê° ëí ìì ì체를 í´ë¦/íì±ííì¬ ë«ì ê²ì¼ë¡ ììëë ê²½ì°ìë ëí ììì ì§ì autofocus를 ì¶ê°íë ê²ì´ ì¢ìµëë¤. <dialog>ììë ìí¸ìì©íì§ ìê³ í¬ì»¤ì¤ë¥¼ ë°ì§ ìì¼ë¯ë¡tabindexìì±ì ì¶ê°íì§ ë§ì¸ì. ëí ìì ë´ ë«ê¸° ë²í¼ì í¬í¨í ì½í ì¸ ë í¬ì»¤ì¤ë¥¼ ë°ì ì ìê³ ìí¸ìì©í ì ììµëë¤.
ì ê·¼ì±
ëí ìì를 구íí ë, ì¬ì©ì í¬ì»¤ì¤ë¥¼ ì¤ì í기 ê°ì¥ ì ì í ìì¹ë¥¼ ê³ ë ¤íë ê²ì´ ì¤ìí©ëë¤. HTMLDialogElement.showModal()ì ì¬ì©íì¬ <dialog>를 ì´ ë ëí ìì ë´ë¶ìì í ììì 첫 ë²ì§¸ë¡ í¬ì»¤ì¤ ê°ë¥í ììì í¬ì»¤ì¤ê° ìëì¼ë¡ ì¤ì ë©ëë¤. autofocus í¹ì±ì ì¬ì©íì¬ ì´ê¸° í¬ì»¤ì¤ë¥¼ ëª
ìì ì¼ë¡ ì§ì íë©´ ê° ëí ìììì ê°ì¥ ì ì í ììì ì´ê¸° í¬ì»¤ì¤ê° ì¤ì ëëë¡ í ì ììµëë¤. ëí ìì ë´ìì ì´ê¸° í¬ì»¤ì¤ë¥¼ ì´ëì ì¤ì í ì§ ëª
ííì§ ìì ê²½ì°, í¹í ëí ììì ë´ì©ì´ í¸ì¶ ìì ì ëì ì¼ë¡ ë ëë§ëë ìí©ììë <dialog> ìì ìì²´ê° ì´ê¸° í¬ì»¤ì¤ ë°°ì¹ì ê°ì¥ ì ì í ìì¹ê° ë ì ììµëë¤.
ì¬ì©ìê° ëí ìì를 ë«ì ì ìë ë©ì»¤ëì¦ì ì ê³µí´ì¼ í©ëë¤. 모ë ì¬ì©ìê° ëí ìì를 ë«ì ì ìëë¡ ë³´ì¥íë ê°ì¥ ê°ë ¥í ë°©ë²ì íì¸, ì·¨ì ëë ë«ê¸° ë²í¼ê³¼ ê°ì ëª ìì ë²í¼ì í¬í¨íë ê²ì ëë¤.
기본ì ì¼ë¡ showModal() ë©ìëë¡ í¸ì¶ë ëí ììë Esc í¤ë¥¼ ëë¬ ë«ì ì ììµëë¤. ë¹ëª¨ë¬ ëí ììë 기본ì ì¼ë¡ Esc í¤ë¡ ë«íì§ ìì¼ë©°, ë¹ëª¨ë¬ ëí ììì 목ì ì ë°ë¼ìë ì´ë¬í ëìì´ íìíì§ ìì ì ììµëë¤. í¤ë³´ë ì¬ì©ìë Esc í¤ê° ëª¨ë¬ ëí ìì를 ë«ì ê²ì¼ë¡ ììíë¯ë¡, ì´ ëìì´ êµ¬íëê³ ì ì§ëëë¡ í´ì¼ í©ëë¤. ì¬ë¬ ëª¨ë¬ ëí ììê° ì´ë ¤ ìë ê²½ì° Esc í¤ë¥¼ ë르면 ë§ì§ë§ì¼ë¡ íìë ëí ììë§ ë«ìì¼ í©ëë¤. <dialog>를 ì¬ì©íë©´ ì´ ëìì ë¸ë¼ì°ì ìì ì ê³µë©ëë¤.
ë¤ë¥¸ ìì를 ì¬ì©íì¬ ëí ìì를 ë§ë¤ ì ìì§ë§, 기본 <dialog> ììë ì¬ì©ì±ê³¼ ì ê·¼ì± ê¸°ë¥ì ë´ì¥íê³ ìì¼ë¯ë¡ ë¤ë¥¸ ììë¡ ë¹ì·í 기ë¥ì 구íí ëë ì´ë¬í í¹ì±ë¤ì ì§ì 구íí´ì¼ í©ëë¤. ì¬ì©ìê° ì§ì ëí ìì를 구ííë ê²½ì°, 모ë ììëë 기본 ëìì´ ì§ìëëì§ íì¸íê³ ì ì í ë ì´ë¸ ì§ì ê¶ì¥ ì¬íì ì¤ìí´ì¼ í©ëë¤.
<dialog> ììë ARIA role="dialog" í¹ì±ì ì¬ì©íë ì¬ì©ì 구í ëí ììì ì ì¬í ë°©ìì¼ë¡ ë¸ë¼ì°ì ìì ì²ë¦¬ë©ëë¤. showModal() ë©ìëë¡ í¸ì¶ë <dialog> ììë ì묵ì ì¼ë¡ aria-modal="true"를 ê°ì§ê³ ìë ë°ë©´, show() ë©ìëë¡ í¸ì¶ëê±°ë open í¹ì±ì ì¬ì©íì¬ íìëê±°ë <dialog>ì 기본 display를 ë³ê²½íì¬ íìëë <dialog> ììë [aria-modal="false"]ë¡ ë
¸ì¶ë©ëë¤. ëª¨ë¬ ëí ìì를 구íí ë <dialog> ë° ê·¸ ì½í
ì¸ ë¥¼ ì ì¸í 모ë ê²ì inert í¹ì±ì ì¬ì©íì¬ ë¹íì±íëì´ì¼ í©ëë¤. <dialog>ì HTMLDialogElement.showModal() ë©ìë를 ì¬ì©íë©´ ì´ ëìì ë¸ë¼ì°ì ìì ì ê³µë©ëë¤.
ìì
>HTMLë§ì¼ë¡ ëí ìì ë§ë¤ê¸°
ì´ ìì ë HTMLë§ì ì¬ì©íì¬ ë¹ëª¨ë¬ ëí ìì를 ë§ëë ë°©ë²ì ë³´ì¬ì¤ëë¤. <dialog> ììì ë¶ë¦¬ì¸ open í¹ì±ì¼ë¡ ì¸í´ íì´ì§ê° ë¡ëë ë ëí ììê° ì´ë¦° ìíë¡ ëíë©ëë¤. <form> ììì method í¹ì±ì´ "dialog"ë¡ ì¤ì ëì´ ì기 ë문ì "íì¸" ë²í¼ì í´ë¦íë©´ ëí ììê° ë«íëë¤. ì´ ê²½ì° JavaScriptë íìíì§ ììµëë¤.
<dialog open>
<p>ìë
íì¸ì, ì¬ë¬ë¶!</p>
<form method="dialog">
<button>íì¸</button>
</form>
</dialog>
ê²°ê³¼
ì°¸ê³ : 결과물ì ì´ê¸°ííë ¤ë©´ íì´ì§ë¥¼ ìë¡ê³ 침 íì¸ì.
ì´ ëí ììë open í¹ì±ì´ ì기 ë문ì ì²ìì ì´ë ¤ ììµëë¤. open í¹ì±ì ì¬ì©íì¬ íìëë ëí ììë ë¹ëª¨ë¬ì
ëë¤. "íì¸"ì í´ë¦í í ëí ììê° ë«íê³ ê²°ê³¼ì°½ì ë¹ì´ììµëë¤. ëí ììê° ë«íë©´ ë¤ì ì´ ì ìë ë°©ë²ì´ ì ê³µëì§ ììµëë¤. ì´ë¬í ì´ì ë¡ ë¹ëª¨ë¬ ëí ìì를 íìíë ë° ì í¸ëë ë°©ë²ì HTMLDialogElement.show() ë©ìë를 ì¬ì©íë ê²ì
ëë¤. ë¶ë¦¬ì¸ open í¹ì±ì ì¶ê°íê±°ë ì ê±°íì¬ ëí ììì íì를 ì íí ì ìì§ë§, ì´ë ê¶ì¥ëë ë°©ë²ì´ ìëëë¤.
ëª¨ë¬ ëí ìì ë§ë¤ê¸°
ì´ ìì ë gradient ë°°ê²½ì´ ìë ëª¨ë¬ ëí ìì를 ë³´ì¬ì¤ëë¤. .showModal() ë©ìëë "ëí ìì íì" ë²í¼ì´ í´ë¦ë ë ëª¨ë¬ ëí ìì를 ì½ëë¤. ëí ììë Esc í¤ë¥¼ ë르거ë ëí ìì ë´ì "ë«ê¸°" ë²í¼ì´ í´ë¦ë ë close() ë©ìë를 íµí´ ë«ì ì ììµëë¤.
ëí ììê° ì´ë¦¬ë©´ ë¸ë¼ì°ì ë ëí ìì ë´ìì í¬ì»¤ì¤ë¥¼ ë°ì ì ìë 첫 ë²ì§¸ ììì 기본ì ì¼ë¡ í¬ì»¤ì¤ë¥¼ ì¤ëë¤. ì´ ìì ììë autofocus í¹ì±ì´ "ë«ê¸°" ë²í¼ì ì ì©ëì´ ëí ììê° ì´ë¦´ ë í¬ì»¤ì¤ë¥¼ ë°ìµëë¤. ì´ë ëí ììê° ì´ë¦° ì§íì ì¬ì©ìê° ìí¸ ìì©í ê²ì¼ë¡ ììëë ììì´ê¸° ë문ì
ëë¤.
HTML
<dialog>
<button autofocus>ë«ê¸°</button>
<p>ì´ ëª¨ë¬ ëí ììë ë©ì§ ë°°ê²½ì ê°ì§ê³ ììµëë¤!</p>
</dialog>
<button>ëí ìì íì</button>
CSS
::backdrop ìì¬ ìì를 ì¬ì©íì¬ ëí ììì ë°°ê²½ì ì¤íì¼ë§í ì ììµëë¤.
::backdrop {
background-image: linear-gradient(
45deg,
magenta,
rebeccapurple,
dodgerblue,
green
);
opacity: 0.75;
}
JavaScript
ëí ììë .showModal() ë©ìë를 ì¬ì©íì¬ ëª¨ë¬ ë°©ìì¼ë¡ ì´ë¦¬ê³ .close() ëë .requestClose() ë©ìë를 ì¬ì©íì¬ ë«íëë¤.
const dialog = document.querySelector("dialog");
const showButton = document.querySelector("dialog + button");
const closeButton = document.querySelector("dialog button");
// "ëí ìì íì" ë²í¼ì´ ëª¨ë¬ ë°©ìì¼ë¡ ëí ìì를 ì½ëë¤
showButton.addEventListener("click", () => {
dialog.showModal();
});
// "ë«ê¸°" ë²í¼ì´ ëí ìì를 ë«ìµëë¤
closeButton.addEventListener("click", () => {
dialog.close();
});
ê²°ê³¼
ëª¨ë¬ ëí ììê° íìëë©´ íë©´ì ì¡´ì¬íë ë¤ë¥¸ ëí ììë³´ë¤ ìì ëíë©ëë¤. ëª¨ë¬ ëí ìì ì¸ë¶ì 모ë ê²ì ë¹íì± ìíì´ë©° ëí ìì ì¸ë¶ì ìí¸ ìì©ì´ ì°¨ë¨ë©ëë¤. ëí ììê° ì´ë ¤ ìì ë ëí ìì ì체를 ì ì¸íê³ ë 문ììì ìí¸ ìì©ì´ ë¶ê°ë¥íë¤ë ì ì ì ìíì¸ì. "ëí ìì íì" ë²í¼ì ëí ììì ë¶í¬ëª í ë°°ê²½ì ëë¶ë¶ ê°ë ¤ì ¸ ìì¼ë©° ë¹íì± ìíì ëë¤.
ëí ìììì ë°í ê° ì²ë¦¬í기
ì´ ìì ë <dialog> ììì returnValueì í¼ì ì¬ì©íì¬ ëª¨ë¬ ëí ìì를 ë«ë ë°©ë²ì ë³´ì¬ì¤ëë¤. 기본ì ì¼ë¡ returnValueë ë¹ ë¬¸ìì´ì´ì§ë§, <dialog> ìì ë´ì í¼ì ì ì¶íë ë²í¼ì´ ìë ê²½ì°ìë í´ë¹ ë²í¼ì ê°ì´ ë°íë©ëë¤.
ì´ ìì ë "ëí ìì íì" ë²í¼ì´ í´ë¦ë ë ëª¨ë¬ ëí ìì를 ì½ëë¤. ëí ìììë <select>ì <button> ìì ë ê°ë¡ ì´ë£¨ì´ì§ ììì´ í¬í¨ëì´ ìì¼ë©°, ë²í¼ë¤ì 기본ì ì¼ë¡ type="submit"ì
ëë¤. ì´ë²¤í¸ 리ì¤ëë ì í ìµì
ì´ ë³ê²½ë ëë§ë¤ "íì¸" ë²í¼ì ê°ì ì
ë°ì´í¸í©ëë¤. "íì¸" ë²í¼ì ëë¬ ëí ìì를 ë«ì¼ë©´ ë²í¼ì íì¬ ê°ì´ ë°í ê°ì
ëë¤. "ì·¨ì" ë²í¼ì ëë¬ ëí ìì를 ë«ì¼ë©´ returnValueë cancelì
ëë¤.
ëí ììê° ë«íë©´ "ëí ìì íì" ë²í¼ ìëì ë°í ê°ì´ íìë©ëë¤. ëí ììê° Esc í¤ë¥¼ ëë¬ ë«íë©´ returnValueê° ì
ë°ì´í¸ëì§ ìê³ close ì´ë²¤í¸ê° ë°ìíì§ ìì¼ë¯ë¡ <output>ì í
ì¤í¸ë ì
ë°ì´í¸ëì§ ììµëë¤.
HTML
<!-- í¼ì´ í¬í¨ë ëª¨ë¬ ëí ìì -->
<dialog id="favDialog">
<form>
<p>
<label>
ì¢ìíë ë물:
<select>
<option value="default">ì íí기â¦</option>
<option>ì¨ëª½í¤</option>
<option>ë ìíë¤</option>
<option>거미ììì´</option>
</select>
</label>
</p>
<div>
<button value="cancel" formmethod="dialog">ì·¨ì</button>
<button id="confirmBtn" value="default">íì¸</button>
</div>
</form>
</dialog>
<p>
<button id="showDialog">ëí ìì íì</button>
</p>
<output></output>
JavaScript
const showButton = document.getElementById("showDialog");
const favDialog = document.getElementById("favDialog");
const outputBox = document.querySelector("output");
const selectEl = favDialog.querySelector("select");
const confirmBtn = favDialog.querySelector("#confirmBtn");
// "ëí ìì íì" ë²í¼ì´ <dialog>를 ëª¨ë¬ ë°©ìì¼ë¡ ì½ëë¤
showButton.addEventListener("click", () => {
favDialog.showModal();
});
// "ì·¨ì" ë²í¼ì [formmethod="dialog"]ì´ê¸° ë문ì ì ì¶íì§ ìê³ ëí ìì를 ë«ì close ì´ë²¤í¸ë¥¼ í¸ë¦¬ê±°í©ëë¤.
favDialog.addEventListener("close", (e) => {
outputBox.value =
favDialog.returnValue === "default"
? "ë°í ê°ì´ ììµëë¤."
: `ë°í ê°: ${favDialog.returnValue}.`; // ë¹ ë¬¸ìì´ ëì "default"를 íì¸í´ì¼ í©ëë¤
});
// "íì¸" ë²í¼ì 기본 ëìì¸ í¼ì ì ì¶íë ê²ì ë°©ì§íê³ , `close()` ë©ìëë¡ ëí ìì를 ë«ì "close" ì´ë²¤í¸ë¥¼ í¸ë¦¬ê±°í©ëë¤.
confirmBtn.addEventListener("click", (event) => {
event.preventDefault(); // ê°ì§ í¼ì ì ì¶íì§ ììµëë¤
favDialog.close(selectEl.value); // ì¬ê¸°ì ì
ë í¸ ë°ì¤ ê°ì ë³´ë´ì¼ í©ëë¤.
});
ê²°ê³¼
ìì ìì ë ëª¨ë¬ ëí ìì를 ë«ë ë¤ì ì¸ ê°ì§ ë°©ë²ì ë³´ì¬ì¤ëë¤.
dialogë©ìë를 ì¬ì©íì¬ ëí ìì ë´ì í¼ì ì ì¶í´ ë«ë ë°©ë²(HTMLë§ì¼ë¡ ëí ìì ë§ë¤ê¸°ìì ë³¼ ì ìì).- Esc í¤ë¥¼ ëë¬ ë«ë ë°©ë².
HTMLDialogElement.close()ë©ìë를 í¸ì¶íì¬ ë«ë ë°©ë²(ëª¨ë¬ ìì ìì ë³¼ ì ìì). ì´ ìì ìì "ì·¨ì" ë²í¼ìdialogí¼ ë©ìë를 íµí´ ëí ìì를 ë«ê³ "íì¸" ë²í¼ìHTMLDialogElement.close()ë©ìë를 íµí´ ëí ìì를 ë«ìµëë¤.
"ì·¨ì" ë²í¼ìë formmethod="dialog" í¹ì±ì´ í¬í¨ëì´ ìì´ <form>ì 기본 GET ë©ìë를 ì¬ì ìí©ëë¤. í¼ì ë©ìëê° dialogì¸ ê²½ì° í¼ì ìíê° ì ì¥ëì§ë§ ì ì¶ëì§ ìê³ ëí ììê° ë«íëë¤.
actionì´ ìì¼ë©´ 기본 GET ë©ìë를 íµí´ í¼ì ì ì¶íë©´ íì´ì§ê° ë¤ì ë¡ëë©ëë¤. ì°ë¦¬ë JavaScript를 ì¬ì©íì¬ event.preventDefault()ì HTMLDialogElement.close() ë©ìë를 ê°ê° ì¬ì©íì¬ ì ì¶ì ë°©ì§íê³ ëí ìì를 ë«ìµëë¤.
모ë dialog ìì ë´ì ë«ê¸° ë©ì»¤ëì¦ì ì ê³µíë ê²ì´ ì¤ìí©ëë¤. Esc í¤ë 기본ì ì¼ë¡ ë¹ëª¨ë¬ ëí ìì를 ë«ì§ ìì¼ë©°, 모ë ì¬ì©ìê° ë¬¼ë¦¬ì í¤ë³´ë를 ì´ì©í ì ìë¤ê³ ê°ì í´ìë ì ë©ëë¤ (ì: í¤ë³´ë ìì´ í°ì¹ì¤í¬ë¦° ì¥ì¹ë§ ì¬ì©íë ê²½ì°).
íì í¼ ì ë ¥ì´ ìë ëí ìì ë«ê¸°
ëí ìì ë´ì í¼ì íì ì
ë ¥ì´ ìë ê²½ì°, ì¬ì©ìë íì ì
ë ¥ì ê°ì ì ê³µí íìë§ ëí ìì를 ë«ì ì ììµëë¤. ì´ë° ëí ìì를 ë«ì¼ë ¤ë©´ ë«ê¸° ë²í¼ì formnovalidate í¹ì±ì ì¬ì©íê±°ë ë«ê¸° ë²í¼ì í´ë¦í ë ëí ìì ê°ì²´ì close() ë©ìë를 í¸ì¶íì¸ì.
<dialog id="dialog">
<form method="dialog">
<p>
<label>
ì¢ìíë ë물:
<input type="text" required />
</label>
</p>
<div>
<input type="submit" id="normal-close" value="ì¼ë° ë«ê¸°" />
<input
type="submit"
id="novalidate-close"
value="ê²ì¦ ìì´ ë«ê¸°"
formnovalidate />
<input type="submit" id="js-close" value="JS ë«ê¸°" />
</div>
</form>
</dialog>
<p>
<button id="show-dialog">ëí ìì íì</button>
</p>
<output></output>
JavaScript
const showBtn = document.getElementById("show-dialog");
const dialog = document.getElementById("dialog");
const jsCloseBtn = dialog.querySelector("#js-close");
showBtn.addEventListener("click", () => {
dialog.showModal();
});
jsCloseBtn.addEventListener("click", (e) => {
e.preventDefault();
dialog.close();
});
ê²°ê³¼
ê²°ê³¼ìì ë³¼ ì ìë¯ì´ ì¼ë° ë«ê¸° ë²í¼ì¼ë¡ë ëí ìì를 ë«ì ì ììµëë¤. ê·¸ë¬ë ì·¨ì ë²í¼ì formnovalidate í¹ì±ì ì¬ì©íì¬ í¼ ì í¨ì± ê²ì¬ë¥¼ ì°ííë©´ ëí ìì를 ë«ì ì ììµëë¤. íë¡ê·¸ëë° ë°©ìì¼ë¡ dialog.close()를 ì¬ì©í´ë ì´ë¬í ëí ìì를 ë«ì ì ììµëë¤.
ë¤ìí closedby ëì ë¹êµ
ì´ ìì ë closedby í¹ì±ì ìë¡ ë¤ë¥¸ ê° ê°ì ëì ì°¨ì´ë¥¼ ë³´ì¬ì¤ëë¤.
HTML
<button> ìì ì¸ ê°ì <dialog> ìì ì¸ ê°ë¥¼ ì ê³µí©ëë¤. ë²í¼ë§ë¤ closedby í¹ì± ì¸ ê°ì§ ê° none, closerequest, any ì¤ íëì ëìì ë³´ì¬ì£¼ë ëí ìì를 ì´ëë¡ íë¡ê·¸ëë°ëììµëë¤. 모ë <dialog> ìììë ëí ìì를 ë«ë <button> ììê° í¬í¨ëì´ ììµëë¤.
<p><code><dialog></code> ì íì ì ííì¸ì:</p>
<div id="controls">
<button id="none-btn"><code>closedby="none"</code></button>
<button id="closerequest-btn">
<code>closedby="closerequest"</code>
</button>
<button id="any-btn"><code>closedby="any"</code></button>
</div>
<dialog closedby="none">
<h2><code>closedby="none"</code></h2>
<p>
í¹ì ì ê³µë ë©ì»¤ëì¦ë§ì ì¬ì©íì¬ ë«ì ì ìì¼ë©°, ì´ ê²½ì°ìë ìë "ë«ê¸°"
ë²í¼ì ë르ë ê²ì
ëë¤.
</p>
<button class="close">ë«ê¸°</button>
</dialog>
<dialog closedby="closerequest">
<h2><code>closedby="closerequest"</code></h2>
<p>"ë«ê¸°" ë²í¼ ëë Esc í¤ë¥¼ ì¬ì©íì¬ ë«ì ì ììµëë¤.</p>
<button class="close">ë«ê¸°</button>
</dialog>
<dialog closedby="any">
<h2><code>closedby="any"</code></h2>
<p>
"ë«ê¸°" ë²í¼, Esc í¤ ëë ëí ìì ì¸ë¶ë¥¼ í´ë¦íì¬ ë«ì ì ììµëë¤. "ê°í¸
ë«ê¸°" ëìì
ëë¤.
</p>
<button class="close">ë«ê¸°</button>
</dialog>
JavaScript
ì¬ê¸°ìë ë©ì¸ 컨í¸ë¡¤ì <button> ìì, <dialog> ìì ë° ëí ìì ë´ë¶ì "ë«ê¸°" <button> ìì를 참조í기 ìí´ ë¤ìí ë³ì를 í ë¹í©ëë¤. 먼ì addEventListener를 ì¬ì©íì¬ ê° ì»¨í¸ë¡¤ ë²í¼ì click ì´ë²¤í¸ 리ì¤ë를 í ë¹í©ëë¤. ì´ ì´ë²¤í¸ í¸ë¤ë¬ í¨ìë showModal()ì íµí´ ê´ë ¨ <dialog> ìì를 ì½ëë¤. ê·¸ë° ë¤ì "ë«ê¸°" <button> 참조를 ë°ë³µíì¬ close()를 íµí´ <dialog> ìì를 ë«ë click ì´ë²¤í¸ í¸ë¤ë¬ í¨ì를 ê°ê° ë²í¼ì í ë¹í©ëë¤.
const noneBtn = document.getElementById("none-btn");
const closerequestBtn = document.getElementById("closerequest-btn");
const anyBtn = document.getElementById("any-btn");
const noneDialog = document.querySelector("[closedby='none']");
const closerequestDialog = document.querySelector("[closedby='closerequest']");
const anyDialog = document.querySelector("[closedby='any']");
const closeBtns = document.querySelectorAll(".close");
noneBtn.addEventListener("click", () => {
noneDialog.showModal();
});
closerequestBtn.addEventListener("click", () => {
closerequestDialog.showModal();
});
anyBtn.addEventListener("click", () => {
anyDialog.showModal();
});
closeBtns.forEach((btn) => {
btn.addEventListener("click", () => {
btn.parentElement.close();
});
});
ê²°ê³¼
ë ëë§ë ê²°ê³¼ë ë¤ìê³¼ ê°ìµëë¤.
ê° ë²í¼ì í´ë¦íì¬ ëí ìì를 ì´ì´ë³´ì¸ì. 첫 ë²ì§¸ë "ë«ê¸°" ë²í¼ì í´ë¦í´ì¼ë§ ë«ì ì ììµëë¤. ë ë²ì§¸ë Esc í¤ì ê°ì ì¥ì¹ë³ ì¬ì©ì ìì ì íµí´ìë ë«ì ì ììµëë¤. ì¸ ë²ì§¸ë ìì í "ê°í¸ ë«ê¸°" ëìì ê°ì§ë¯ë¡ ëí ìì ì¸ë¶ë¥¼ í´ë¦íê±°ë ííì¬ ë«ì ìë ììµëë¤.
ëí ìì ì ëë©ì´ì
<dialog>ë ì¨ê²¨ì ¸ ìì ë display: none;ì¼ë¡ ì¤ì ëê³ ëíë ë display: block;ì¼ë¡ ì¤ì ëë©°, top layerì ì ê·¼ì± í¸ë¦¬ìì ì ê±°/ì¶ê°ë©ëë¤. ë°ë¼ì <dialog> ììì ì ëë©ì´ì
ì ì ì©íë ¤ë©´ display ìì±ì´ ì ëë©ì´ì
ì ì§ìí´ì¼ í©ëë¤. ì§ìíë ë¸ë¼ì°ì ë ë¶ì°ì ì ëë©ì´ì
ì íì ë³íì íµí´ display ìì±ì ì ëë©ì´ì
í¨ê³¼ë¥¼ ì¤ëë¤. 구체ì ì¼ë¡, ë¸ë¼ì°ì ë noneê³¼ display ì ë¤ë¥¸ ê° ì¬ì´ë¥¼ ì ííì¬ ì ëë©ì´ì
ì´ ì§íëë ì ì²´ ê¸°ê° ëì ì½í
ì¸ ê° ë³´ì´ëë¡ ì²ë¦¬í©ëë¤.
ì를 ë¤ë©´,
display를noneììblock(ëë ë¤ë¥¸ ë³´ì´ëdisplayê°)ì¼ë¡ ì ëë©ì´ì ì ì ì©í ë, ì ëë©ì´ì ìì ìì ì¸0%ìì ê°ì´blockì¼ë¡ ì íëì´ ì ëë©ì´ì ì ì²´ ê¸°ê° ëì ììê° ë³´ì´ê² ë©ëë¤.display를block(ëë ë¤ë¥¸ ë³´ì´ëdisplayê°)ììnoneì¼ë¡ ì ëë©ì´ì ì ì ì©í ë, ì ëë©ì´ì ì¢ ë£ ìì ì¸100%ìì ê°ì´noneì¼ë¡ ì íëì´ ì ëë©ì´ì ì ì²´ ê¸°ê° ëì ììê° ë³´ì´ê² ë©ëë¤.
ì°¸ê³ :
ì´ CSS ì íì ì¬ì©íì¬ ì ëë©ì´ì
ì ì ì©í ëë ìì ëìì íì±íí기 ìí´ transition-behavior: allow-discrete 를 ì¤ì í´ì¼ í©ëë¤. ì´ ëìì CSS ì ëë©ì´ì
ì¼ë¡ ì ëë©ì´ì
ì ì ì©í ë 기본ì ì¼ë¡ ì¬ì©í ì ìì¼ë¯ë¡ ë³ëì ì¶ê° ìì
ì´ íìíì§ ììµëë¤.
ëí ìì ìì ì íí기
CSS ì íì¼ë¡ <dialog>ì ì ëë©ì´ì
ì ì ì©í ë ë¤ì 기ë¥ì´ íìí©ëë¤.
@starting-style@ê·ì¹-
<dialog>ê° ì´ë¦´ ëë§ë¤ ì í í¨ê³¼ë¥¼ ì ì©íê³ ì¶ì ìì±ë¤ì ìì ê°ì ì§ì í©ëë¤. ì´ë ììì¹ ëª»í ëìì ë°©ì§í기 ìí´ íìí©ëë¤. 기본ì ì¼ë¡ CSS ì íì ì´ë¯¸ íë©´ì íìë ìììì ìì±ì´ í ê°ìì ë¤ë¥¸ ê°ì¼ë¡ ë³ê²½ë ëë§ ë°ìí©ëë¤. ììê° ì²ì ì¤íì¼ì ì ì©ë°ì ëëdisplayìì±ì´noneìì ë¤ë¥¸ ê°ì¼ë¡ ë°ë ëë í¸ë¦¬ê±°ëì§ ììµëë¤. displayìì±-
ì í 목ë¡ì
display를 ì¶ê°íì¬ ëí ììê° ì í ê¸°ê° ëìdisplay: block(ëë ëí ììê° ì´ë¦° ìíì ì¤ì ë ë¤ë¥¸ ë³´ì´ëdisplayê°)ì¼ë¡ ì ì§ëì´ ë¤ë¥¸ ì í í¨ê³¼ê° ì ëë¡ ë³´ì ëë¤. overlayìì±-
ì í 목ë¡ì
overlay를 í¬í¨íì¬ ì íì´ ìë£ë ëê¹ì§ ìì ë ì´ì´ìì<dialog>ì 거를 ì§ì°íì¬ ì í í¨ê³¼ê° ì ëë¡ ë³´ì ëë¤. transition-behaviorìì±-
displayìoverlayì í(ëëtransitionë¨ì¶í)ìtransition-behavior: allow-discrete를 ì¤ì íì¬ ê¸°ë³¸ì ì¼ë¡ ì ëë©ì´ì ì´ ë¶ê°ë¥í ì´ ë ìì±ì ë¶ì°ì ì íì ì ì©í ì ììµëë¤.
ë¤ìì ì´ê²ì´ ì´ë»ê² ëìíëì§ ë³´ì¬ì£¼ë ê°ë¨í ìì ì ëë¤.
HTML
HTMLìë <dialog> ììì ëí ìì를 íìíë ë²í¼ì´ í¬í¨ëì´ ììµëë¤. ëí <dialog> ìììë ëí ìì ì체를 ë«ì ì ìë ë¤ë¥¸ ë²í¼ì´ í¬í¨ëì´ ììµëë¤.
<dialog id="dialog">
ì¬ê¸°ì ë´ì©
<button class="close">ë«ê¸°</button>
</dialog>
<button class="show">ëª¨ë¬ ëíë´ê¸°</button>
CSS
CSSìë opacityì transform ìì±ì ì í ìì ì¤íì¼ì ì ìíë @starting-style ë¸ë¡ê³¼ dialog:open ìíì ëí ì í ì¢
ë£ ì¤íì¼, ê·¸ë¦¬ê³ <dialog>ê° ëíë í ë¤ì ì íí 기본 dialog ìíì 기본 ì¤íì¼ì´ í¬í¨ëì´ ììµëë¤. <dialog>ì transition 목ë¡ìë ì´ë¬í ìì±ë¿ë§ ìëë¼ display ë° overlay ìì±ë í¬í¨ëë©°, ê°ê°ìë allow-discreteê° ì¤ì ëì´ ììµëë¤.
ëí <dialog> ë¤ì ëíëë ::backdropì background-color ìì±ì ëí ìì ì¤íì¼ ê°ì ì¤ì íì¬ <dialog>ê° ì´ë¦´ ë ì´ëìì§ë ë©ì§ ì ëë©ì´ì
ì ì ê³µí©ëë¤. dialog:open::backdrop ì íìë ëí ììê° ì´ë ¤ ìì ëë§ <dialog> ììì ë°°ê²½ì ì íí©ëë¤.
/* ëí ììì ì´ë¦° ìí */
dialog:open {
opacity: 1;
transform: scaleY(1);
}
/* ëí ììì ë«í ìí */
dialog {
opacity: 0;
transform: scaleY(0);
transition:
opacity 0.7s ease-out,
transform 0.7s ease-out,
overlay 0.7s ease-out allow-discrete,
display 0.7s ease-out allow-discrete;
/* ë¤ìê³¼ ëì¼
transition: all 0.7s allow-discrete; */
}
/* ì´ê¸° ì ìí */
/* ì´ì dialog:open ê·ì¹ê³¼ í¹ì´ì±ì´ ê°ì¼ë¯ë¡ í¨ê³¼ë¥¼ ë°ííë ¤ë©´
dialog:open ê·ì¹ ë¤ìì ìì´ì¼ í¨ */
@starting-style {
dialog:open {
opacity: 0;
transform: scaleY(0);
}
}
/* ëí ìì 모ë¬ì´ ìì ë ì´ì´ë¡ ì¹ê²©ë ë ::backdrop ì í */
dialog::backdrop {
background-color: rgb(0 0 0 / 0%);
transition:
display 0.7s allow-discrete,
overlay 0.7s allow-discrete,
background-color 0.7s;
/* ë¤ìê³¼ ëì¼
transition: all 0.7s allow-discrete; */
}
dialog:open::backdrop {
background-color: rgb(0 0 0 / 25%);
}
/* ì´ starting-style ê·ì¹ì ìì ì íì ìì ì¤ì²©ë ì ìì.
ì¤ì²© ì íìë ìì¬ ìì를 ëíë¼ ì ì기 ë문. */
@starting-style {
dialog:open::backdrop {
background-color: rgb(0 0 0 / 0%);
}
}
ì°¸ê³ :
ì´ :open ìì¬ í´ëì¤ë¥¼ ì§ìíì§ ìë ë¸ë¼ì°ì ììë dialog[open] í¹ì± ì íì를 ì¬ì©íì¬ ì´ë¦° ìíì <dialog> ìì를 ì¤íì¼ë§í ì ììµëë¤.
JavaScript
JavaScriptë í´ë¦ë ë <dialog>를 ë³´ì´ê±°ë ë«ë ì´ê¸° ë²í¼ê³¼ ë«ê¸° ë²í¼ì ì´ë²¤í¸ í¸ë¤ë¬ë¥¼ ì¶ê°í©ëë¤.
const dialogElem = document.getElementById("dialog");
const showBtn = document.querySelector(".show");
const closeBtn = document.querySelector(".close");
showBtn.addEventListener("click", () => {
dialogElem.showModal();
});
closeBtn.addEventListener("click", () => {
dialogElem.close();
});
ê²°ê³¼
ì½ëë ë¤ìê³¼ ê°ì´ ë ëë§ë©ëë¤.
ì°¸ê³ :
ì´ <dialog>ë íìë ëë§ë¤ display: noneìì display: blockì¼ë¡ ë³ê²½ëë¯ë¡, ëí ììë ì íì´ ììë ëë§ë¤ @starting-style ì¤íì¼ìì dialog:open ì¤íì¼ë¡ ì íë©ëë¤. <dialog>ê° ë«íë©´ dialog:open ìíìì 기본 dialog ìíë¡ ì íë©ëë¤.
ì´ë¬í ê²½ì°ìë ì§ì ë° í´ì¥ ì ì¤íì¼ ì íì´ ë¤ë¥¼ ì ììµëë¤. ìì ì¤íì¼ ì ì© ìì ìì° ìì 를 참조íì¸ì.
ëí ìì í¤íë ì ì ëë©ì´ì
CSS í¤íë ì ì ëë©ì´ì
ì¼ë¡ <dialog>ì ì ëë©ì´ì
ì ì ì©í ëë ì íê³¼ ë¤ë¥¸ ëª ê°ì§ ì°¨ì´ì ì ì ìí´ì¼ í©ëë¤.
@starting-styleì ì ê³µíì§ ììµëë¤.- í¤íë ìì
displayê°ì í¬í¨í©ëë¤. ì´ë ì ëë©ì´ì ì ì²´ ê¸°ê° ëì ì ì©ëëdisplayê°ì´ ëë©°,noneì´ ìë ë¤ë¥¸displayê°ì´ ëíë기 ì ê¹ì§ ì ì§ë©ëë¤. - ë¶ì°ì ì ëë©ì´ì
ì ëª
ìì ì¼ë¡ íì±íí íìê° ììµëë¤. í¤íë ì ë´ìì
allow-discreteì ëë±í ê²ì ììµëë¤. - í¤íë ì ë´ì
overlay를 ì¤ì í íìë ììµëë¤.displayì ëë©ì´ì ì´ íìë ìíìì ì¨ê²¨ì§ ìíë¡ì<dialog>ì ëë©ì´ì ì ì²ë¦¬í©ëë¤.
ìì 를 ì´í´ë³´ê³ ì´ë»ê² ë³´ì´ëì§ íì¸í´ ë³´ê² ìµëë¤.
HTML
먼ì HTMLìë <dialog> ììì ëí ìì를 íìíë ë²í¼ì´ í¬í¨ëì´ ììµëë¤. ëí <dialog> ìììë ëí ìì ì체를 ë«ì ì ìë ë¤ë¥¸ ë²í¼ì´ í¬í¨ëì´ ììµëë¤.
<dialog id="dialog">
ì¬ê¸°ì ë´ì©
<button class="close">ë«ê¸°</button>
</dialog>
<button class="show">ëª¨ë¬ ëíë´ê¸°</button>
CSS
CSSë <dialog>ì ë«í ìíì ì´ë¦° ìí ì¬ì´ì ì í í¨ê³¼ë¥¼ ìí í¤íë ìê³¼ <dialog> ë°°ê²½ì íì´ëì¸ ì ëë©ì´ì
ì ì ìí©ëë¤. <dialog> ì ëë©ì´ì
ì display ìì±ë í¨ê» ë³íìì¼ ì¤ì ìê°ì í¨ê³¼ê° ì ëë©ì´ì
ì ì²´ ê¸°ê° ëì ì ì§ëëë¡ í©ëë¤. <dialog>ê° ë«íë©´ ë°°ê²½ì´ ì¦ì DOMìì ì ê±°ëë¯ë¡ ë°°ê²½ì íì´ë ìì ì ëë©ì´ì
ì ì ì©íì§ ëª»í©ëë¤.
dialog {
animation: fade-out 0.7s ease-out;
}
dialog:open {
animation: fade-in 0.7s ease-out;
}
dialog:open::backdrop {
animation: backdrop-fade-in 0.7s ease-out forwards;
}
/* ì ëë©ì´ì
í¤íë ì */
@keyframes fade-in {
0% {
opacity: 0;
transform: scaleY(0);
display: none;
}
100% {
opacity: 1;
transform: scaleY(1);
display: block;
}
}
@keyframes fade-out {
0% {
opacity: 1;
transform: scaleY(1);
display: block;
}
100% {
opacity: 0;
transform: scaleY(0);
display: none;
}
}
@keyframes backdrop-fade-in {
0% {
background-color: rgb(0 0 0 / 0%);
}
100% {
background-color: rgb(0 0 0 / 25%);
}
}
body,
button {
font-family: system-ui;
}
JavaScript
ë§ì§ë§ì¼ë¡ JavaScriptë <dialog> ì´ê¸° ë° ë«ê¸°ë¥¼ íì±íí기 ìí´ ë²í¼ì ì´ë²¤í¸ í¸ë¤ë¬ë¥¼ ì¶ê°í©ëë¤.
const dialogElem = document.getElementById("dialog");
const showBtn = document.querySelector(".show");
const closeBtn = document.querySelector(".close");
showBtn.addEventListener("click", () => {
dialogElem.showModal();
});
closeBtn.addEventListener("click", () => {
dialogElem.close();
});
Result
ì½ëë ë¤ìê³¼ ê°ì´ ë ëë§ë©ëë¤.
기ì ìì½
| ì½í ì¸ ì¹´í ê³ ë¦¬ | íë¡ì° ì½í ì¸ , 구í ë£¨í¸ |
|---|---|
| ê°ë¥í ì½í ì¸ | íë¡ì° ì½í ì¸ |
| íê·¸ ìëµ | ë¶ê°ë¥, ììê³¼ ëì í그를 ì¶ê°íë ê²ì íìì ëë¤. |
| ê°ë¥í ë¶ëª¨ ìì | íë¡ì° ì½í ì¸ ë¥¼ íì©íë 모ë ìì |
| ììì ARIA ìí | dialog |
| ê°ë¥í ARIA ìí | alertdialog |
| DOM ì¸í°íì´ì¤ | HTMLDialogElement |
ëª ì¸ì
| Specification |
|---|
| HTML > # the-dialog-element > |
ë¸ë¼ì°ì í¸íì±
ê°ì´ 보기
HTMLDialogElementì¸í°íì´ì¤closeHTMLDialogElementì¸í°íì´ì¤ì ì´ë²¤í¸cancelHTMLDialogElementì¸í°íì´ì¤ì ì´ë²¤í¸openHTMLDialogElementì¸í°íì´ì¤ì ìì±- HTML ìì를 ìí
inertì ì í¹ì± ::backdropCSS ìì¬ ìì- íìµ ììì Web forms