Lism Tips

Modal(モーダル)

Modal は、ボタンを押すと画面の上に重なって開く小さな画面(モーダル)を作る UI コンポーネントです。開き方・閉じ方と指定できるものをまとめます。

Modal は、ボタンを押すと、いま見ている画面の上に重なって開く窓(モーダル)を作るコンポーネントです。HTML の dialog 要素(ダイアログ。開いたり閉じたりできる窓のための要素)を使います。

どんなときに使う?#

  • 確認のメッセージや、くわしい説明を、ページを移らずに見せたいとき
  • スマートフォンで、横から出てくるメニュー(ドロワーメニュー)を作りたいとき

ページの中でその場に開け閉めしたいだけなら、Details(開け閉めできる囲み) や Accordion(アコーディオン) が向いています。

使い方#

開くボタンと、dialog 要素の2つを用意します。ボタンの data-modal-open と、dialog の id に同じ名前を書くと、そのボタンで開くようになります。閉じるボタンには data-modal-close に同じ名前を書きます。

表示例

見出し

ここに中身を書きます。右上の × で閉じます。

html
<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 の前後に置きます。

表示例

見出し

中身の文章です。

中身の文章です。

中身の文章です。

最後の文章です。

html
<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 で左からずらすと、ドロワーメニューになります。中のリンクがページ内のリンク(# で始まるもの)なら、押すとその場所へ移り、モーダルも閉じます。

表示例

html
<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 のうち、おもなものです。

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 から読み込みます。

jsx
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="閉じる" と指定しておくのがおすすめです。

関連するページ#

公式ドキュメント

2026年10月5日時点の内容(lism-css 1.0.1・@lism-css/ui 0.40.1)をもとに、やさしい日本語でまとめています。

ページの一覧