dialog elementで Modal作ってますか? SvelteでModalを作ってみた
dialog element について
<dialog> は alert window や モダル、ダイアログなどの様な画面上でユーザーにアクションを促す様なコンポネントを表示したい時に使用されます。
よくある実装は close or open を status として持って <div> の表示を制御する方法が多く見受けられますが、それは <dialog> の存在がまだ薄いからな様な気がしてます。
今回せっかくなので最近人気上昇中の Svelte で簡単に実装してみました。
MDN: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
Svelte での実装すると
REPL: https://svelte.dev/repl/ab996f113bd4418db6a2aa3c1721559b?version=4.2.8
<script>
export let dialog;
</script>
<dialog bind:this={dialog} on:close>
<slot />
</dialog>
<script>
import Modal from "./Modal.svelte"
let dialog;
const openModal = () => {
dialog.showModal();
}
const closeModal = () => {
dialog.close();
}
</script>
<button on:click={openModal}>Open modal</button>
<Modal bind:dialog >
<h1>Hello from Modal!!</h1>
<button on:click={closeModal}>Close</button>
</Modal>
Output
A modal と non-modal dialog とは
dialog には a modal と non-modal dialog の2種類のモードタイプがあります。
A modal はユーザーにアクションを行わせるために、黒色のオーバーレイなどで操作していたコンテンツを操作無効にしてモダル内のみのアクションに集中させるモダル。
Non-modal dialog はモダルが開いた状態でも今まで使ってたコンテンツも操作が可能なダイアログ。
open attribute は非推奨
<dialog open />
または .show()
で開閉をすると dialog は non-modal となる。その場合背景の overlay は表示されなくなるので 非推奨となっている。
その代わりに用意されてるAPIとして .showModal()
と .close()
を使用すると modal として dialog が使用でき、overlay が表示される様になる。
背景は ::backdrop でスタイリング
背景の overlay は ::backdrop
にスタイルを当てることで変更することができる。
::backdrop {
background-image: linear-gradient(
45deg,
magenta,
rebeccapurple,
dodgerblue,
green
);
opacity: 0.75;
}
こんな感じにすると虹色の背景も作れる。
下記のように @starting-style
でアニメーションも可能
dialog::backdrop {
background-color: rgb(0 0 0 / 0);
transition:
display 0.7s allow-discrete,
overlay 0.7s allow-discrete,
background-color 0.7s;
}
dialog[open]::backdrop {
background-color: rgb(0 0 0 / 0.25);
}
@starting-style {
dialog[open]::backdrop {
background-color: rgb(0 0 0 / 0);
}
}
method="dialog" で form を close することもできる
下記の2通りのやり方で .close()
を呼ばなくても開いている dialog をとじることができる。
# Pattern 1 - form action method
<dialog open>
<p>Greetings, one and all!</p>
<form method="dialog">
<button>OK</button>
</form>
</dialog>
# Pattern 2 - formmethod
<button formmethod="dialog">Close</button>
dialogは#top-layer に 追加される
Modal mode での dialog は #top-layer と呼ばれる <html>
の兄弟要素に配置されるので html のどの要素よりも上に表示されます。
気をつけないといけないのが他の toast など layer の上に表示されたいものよりも上のレイヤーで表示されることに注意してください。