Modal(モーダル)
Modal は、ボタンを押すと画面の上に重なって開く小さな画面(モーダル)を作る UI コンポーネントです。開き方・閉じ方と指定できるものをまとめます。
Modal は、ボタンを押すと、いま見ている画面の上に重なって開く窓(モーダル)を作るコンポーネントです。HTML の dialog 要素(ダイアログ。開いたり閉じたりできる窓のための要素)を使います。
どんなときに使う?#
- 確認のメッセージや、くわしい説明を、ページを移らずに見せたいとき
- スマートフォンで、横から出てくるメニュー(ドロワーメニュー)を作りたいとき
ページの中でその場に開け閉めしたいだけなら、Details(開け閉めできる囲み) や Accordion(アコーディオン) が向いています。
使い方#
開くボタンと、dialog 要素の2つを用意します。ボタンの data-modal-open と、dialog の id に同じ名前を書くと、そのボタンで開くようになります。閉じるボタンには data-modal-close に同じ名前を書きます。
表示例
<button class="-bd -px:15 -py:5 -bdrs:10 b--modal_openBtn set--plain -hov:-o" type="button" aria-haspopup="dialog" data-modal-open="demo-modal-1">モーダルを開く</button>
<dialog class="b--modal set--plain -p:30" id="demo-modal-1" aria-labelledby="demo-modal-1-title">
<div class="b--modal_inner l--stack -pos:relative -max-sz:m -mx:auto -p:35 -bdrs:30 -bxsh:30">
<button class="b--modal_closeBtn set--plain -hov:-o -pos:absolute -t:0 -r:0 -z:1 -fz:xl -p:10 -m:10" type="button" data-modal-close="demo-modal-1" autofocus>×<span class="u--srOnly">閉じる</span></button>
<div class="b--modal_body l--stack u--trimAll -g:30">
<h2 class="-fz:l -fw:bold" id="demo-modal-1-title">見出し</h2>
<p>ここに中身を書きます。右上の × で閉じます。</p>
</div>
</div>
</dialog>
部品ごとのクラスは次のとおりです。
| クラス | 役目 |
|---|---|
b--modal |
dialog 要素に付ける。画面いっぱいに広がり、うしろを暗く・ぼかす |
b--modal_inner |
窓の部分。背景色(--base)が付く |
b--modal_body |
窓の中身を入れる部分 |
b--modal_openBtn |
開くボタン |
b--modal_closeBtn |
閉じるボタン |
動かすには、@lism-css/ui の CSS(dist/style.css)と、動きのスクリプト(dist/scripts/modal.js)の両方を読み込みます。
気をつけること#
b--modal は dialog 要素で動いています。-d:flex などで display(表示のしかた)の値を変えないでください。
- うしろの暗い部分は、
dialog自身を画面いっぱいの大きさにして色を塗ったものです。ブラウザが用意する::backdrop(dialogのうしろの幕)は、動きを付けるとうまくいかないので使っていません dialogには名前を付けます。見出しがあれば、そのidをaria-labelledbyに書きます。見出しが無ければ、aria-label="メニュー"のように名前そのものを書きます。こうすると、読み上げソフト(スクリーンリーダー)が「何の窓か」を伝えられます
専用の変数#
| 変数 | 決めること | 初期値 |
|---|---|---|
--modal-duration |
開け閉めのアニメーションの時間 | 0.3s |
--duration |
実際に使われる時間(--modal-duration から決まる) |
var(--modal-duration, 0.3s) |
--backdrop-bg |
うしろの幕の色 | rgb(0 0 0 / 0.5) |
--modal-blur |
うしろのぼかし | blur(4px) |
--offset |
閉じているときの窓の位置のずれ(開くときにここから動く) | 0 0 |
--offset を -100px 0 にすると、窓が左から滑り込むように開きます。動きを減らす設定(prefers-reduced-motion)の画面では、アニメーションは止まります。
中身が長いとき#
b--modal_body に -ov-y:auto(縦にはみ出したらスクロールする)を付けると、中身だけがスクロールします。いつも見せておきたい見出しやボタンは、b--modal_body の前後に置きます。
表示例
<button class="-bd -px:15 -py:5 -bdrs:10 b--modal_openBtn set--plain -hov:-o" type="button" aria-haspopup="dialog" data-modal-open="demo-modal-2">長いモーダルを開く</button>
<dialog class="b--modal set--plain is--container -px:30 -py:50" id="demo-modal-2" aria-labelledby="demo-modal-2-title">
<div class="b--modal_inner l--stack -max-sz:s -mx:auto -bdrs:20 -bxsh:40">
<div class="l--flex -ai:center -jc:between -py:15 -bd-b">
<h2 class="-fz:l -fw:bold -hl:s -ms:30" id="demo-modal-2-title">見出し</h2>
<button class="b--modal_closeBtn set--plain -hov:-o -fz:xl -p:10 -mx:15" type="button" data-modal-close="demo-modal-2" autofocus>×<span class="u--srOnly">閉じる</span></button>
</div>
<div class="b--modal_body l--flow -px:30 -py:20 -ov-y:auto">
<p>中身の文章です。</p>
<div class="l--box -ar:16/9 -bgc:base-2 -bd"></div>
<p>中身の文章です。</p>
<div class="l--box -ar:16/9 -bgc:base-2 -bd"></div>
<p>中身の文章です。</p>
<div class="l--box -ar:16/9 -bgc:base-2 -bd"></div>
<p>最後の文章です。</p>
</div>
<div class="l--flex -jc:end -px:30 -py:15 -bd-t">
<button class="b--modal_closeBtn set--plain -hov:-o -bgc:text -c:base -hl:s -px:15 -py:10 -bd:none -bdrs:10" type="button" data-modal-close="demo-modal-2">キャンセル</button>
</div>
</div>
</dialog>
横から出るメニューを作る#
窓を左に寄せて高さをいっぱいにし、--offset で左からずらすと、ドロワーメニューになります。中のリンクがページ内のリンク(# で始まるもの)なら、押すとその場所へ移り、モーダルも閉じます。
表示例
<button class="b--modal_openBtn set--plain -hov:-o -g:5 -fz:s -bd -px:15 -py:5" type="button" aria-haspopup="dialog" data-modal-open="demo-modal-3">MENU</button>
<dialog class="b--modal set--plain" id="demo-modal-3" aria-label="メニュー">
<div class="b--modal_inner l--stack -max-w -h:100% -bxsh:40" style="--offset:-100px 0;--max-w:24rem">
<div class="l--flex -bd-b -ai:center -jc:between -p:20">
<span class="-fw:bold">MENU</span>
<button class="b--modal_closeBtn set--plain -hov:-o -fz:xl -p:5" type="button" data-modal-close="demo-modal-3" autofocus>×<span class="u--srOnly">閉じる</span></button>
</div>
<div class="b--modal_body -ov-y:auto">
<nav aria-label="メインメニュー">
<ul class="b--navMenu -bd-b" style="--item-p:1em">
<li class="b--navMenu_item"><a class="b--navMenu_link -hov:-bgc" href="#">メニュー1</a></li>
<li class="b--navMenu_item"><a class="b--navMenu_link -hov:-bgc" href="#">メニュー2</a></li>
<li class="b--navMenu_item"><a class="b--navMenu_link -hov:-bgc" href="#">メニュー3</a></li>
</ul>
</nav>
</div>
</div>
</dialog>
メニューの一覧は NavMenu(ナビゲーションの一覧) で作っています。
しくみ#
b--modal が付ける CSS のうち、おもなものです。
.b--modal {
--duration: var(--modal-duration, 0.3s);
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
background: var(--backdrop-bg, rgb(0 0 0 / 0.5));
backdrop-filter: var(--modal-blur, blur(4px));
transition-duration: var(--duration);
transition-property: opacity;
}
.b--modal[open] {
display: flex;
flex-direction: column;
justify-content: center;
}
.b--modal:not([data-is-open]) {
opacity: 0;
}
開いているあいだだけ、スクリプトが data-is-open を付けます。付いていないときは透明(opacity: 0)で、窓は --offset の分ずれています。
React・Astro で書く場合#
@lism-css/ui から Modal を読み込みます。Astro では @lism-css/ui/astro/Modal から読み込みます。
import { Modal } from '@lism-css/ui/react/Modal';
<Modal.OpenBtn modalId="modal-01">開く</Modal.OpenBtn>
<Modal.Root id="modal-01" aria-labelledby="modal-01-title" p="30">
<Modal.Inner layout="stack" max-sz="m" mx="auto" p="35" bdrs="30">
<Modal.CloseBtn modalId="modal-01" srText="閉じる" />
<Modal.Body layout="stack" g="30">
<h2 id="modal-01-title">見出し</h2>
<p>中身</p>
</Modal.Body>
</Modal.Inner>
</Modal.Root>
使える部品は <Modal.Root>・<Modal.Inner>・<Modal.Body>・<Modal.OpenBtn>・<Modal.CloseBtn> の5つです。
| Props | 決めること |
|---|---|
id |
モーダルの名前。<Modal.Root> に必ず付ける |
duration |
<Modal.Root> 用。開け閉めの時間(--duration になる) |
layout |
<Modal.Inner> 用。窓の並べ方(stack など) |
offset |
<Modal.Inner> 用。閉じているときの位置のずれ(--offset になる) |
modalId |
<Modal.OpenBtn> は data-modal-open、<Modal.CloseBtn> は data-modal-close になる |
icon |
<Modal.CloseBtn> 用。中身を渡さないときのアイコン(初期値 x) |
srText |
<Modal.CloseBtn> 用。読み上げ用の文字(初期値 Close) |
srText の初期値は英語の Close です。日本語のサイトでは srText="閉じる" と指定しておくのがおすすめです。
関連するページ#
- NavMenu(ナビゲーションの一覧):モーダルの中のメニュー
- Popover(クリックで開く小窓):画面全体をふさがない小窓
- UI コンポーネントの使い方:読み込み方
公式ドキュメント
2026年10月5日時点の内容(lism-css 1.0.1・@lism-css/ui 0.40.1)をもとに、やさしい日本語でまとめています。