1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Tailwind CSS入門 Day16】詳細モーダルを作る

1
Last updated at Posted at 2026-05-26

目次

はじめに

この記事は、Tailwind CSSで管理画面UIを1ステップずつ作る学習記録です。
過去記事は末尾の「シリーズ記事」にまとめています。

今日作るもの

Day16では、作品一覧の「詳細」ボタンをクリックすると表示される詳細モーダルを作ります。

Alpine.jsの x-data@clickx-show を使い、ボタン操作でモーダルを開閉できるようにします。

モーダルは通常画面より前面に表示したいので、fixedinset-0z-50 を使って重なり順も確認します。

STEP 1:Day16用HTMLファイルを作る

Day16では、Day15で作った管理画面レイアウトを元にして、作品の詳細モーダルを追加します。
そのため、Day15の完成形をコピーして進めます。

cp day15-hamburger-menu.html day16-detail-modal.html

エクスプローラーでコピーしても大丈夫です。

現在の構成に、Day16用ファイルが追加される形です。

tailwind-learning/
├── day01-heading.html
├── day02-card-base.html
├── day03-image-card.html
├── day04-card-text.html
├── day05-card-buttons.html
├── day06-card-complete.html
├── day07-button-colors.html
├── day08-admin-header.html
├── day09-pc-sidebar.html
├── day10-pc-admin-layout.html
├── day11-item-table.html
├── day12-table-style.html
├── day13-responsive-layout.html
├── day14-alpine-basic.html
├── day15-hamburger-menu.html
├── day16-detail-modal.html
└── images/
    └── sample-poster.png

STEP 2:タイトルをDay16用に直す

day16-detail-modal.html<title> を、Day16用に変更します。

修正前

<title>Day 15 ハンバーガーメニューを作る</title>

修正後

<title>Day 16 詳細モーダルを作る</title>

このSTEPでは、ブラウザタブに表示されるタイトルだけ を変更します。

画面に表示されているヘッダー、ハンバーガーメニュー、サイドバー、テーブル、スマホ用カード部分はまだ触りません。

STEP 3:詳細ボタンにクリック処理を追加する

STEP2では、<title> をDay16用に変更しました。

次は、作品一覧の 詳細ボタン をクリックしたときに、モーダルを開く処理を追加します。

このSTEPでは、まずPC用テーブルの「詳細」ボタンにクリック処理を追加します。

スマホ用カードにも「詳細」ボタンがありますが、学習の流れを分かりやすくするため、本文ではPC用テーブルを中心に進めます。

完成コードでは、スマホ用カード側の「詳細」ボタンにも同じ処理を追加します。

修正前

<button class="px-2 py-1 text-xs border border-gray-300 text-gray-700 rounded hover:bg-gray-200">
    詳細
</button>

修正後

<button
    @click="modalOpen = true"
    class="px-2 py-1 text-xs border border-gray-300 text-gray-700 rounded hover:bg-gray-200"
>
    詳細
</button>

今回追加するもの

追加するもの 内容
@click="modalOpen = true" 詳細ボタンを押したときにモーダルを開く

修正箇所

PC用テーブルには、作品データが3件あります。

そのため、PC用テーブル内の「詳細」ボタン 3か所 に、同じ @click="modalOpen = true" を追加します。

PC用テーブル 1件目の詳細ボタン
PC用テーブル 2件目の詳細ボタン
PC用テーブル 3件目の詳細ボタン

スマホ用カードにも詳細ボタンがありますが、このSTEPではPC用テーブルを中心に確認します。

完成コードでは、スマホ用カード側の詳細ボタンにも同じクリック処理を追加します。

補足:スマホ用カード側の詳細ボタンについて

本文では、PC用テーブルの詳細ボタンを中心に説明しています。

ただし、完成コードではスマホ用カードからも詳細モーダルを開けるようにするため、スマホ用カード側の「詳細」ボタンにも同じ処理を追加します。

@click="modalOpen = true"

今回のポイント

@click="modalOpen = true" を追加することで、詳細ボタンをクリックしたときに modalOpen の値を true にできます。

modalOpen: false → モーダルを閉じている状態
modalOpen: true  → モーダルを開いている状態

ただし、今の時点ではまだ modalOpen を用意していません。

そのため、このSTEPだけではまだ正しく動きません。
次のSTEPで、x-datamodalOpen: false を追加して、モーダルの開閉状態を用意します。

STEP 4:x-dataでモーダルの開閉状態を用意する

STEP3では、詳細ボタンに @click="modalOpen = true" を追加しました。

次は、Alpine.jsで モーダルが開いているかどうか を管理する状態を用意します。

Day15ですでに、ハンバーガーメニュー用に bodyx-data="{ menuOpen: false }" を追加しています。
今回はそこに、詳細モーダル用の modalOpen: false を追加します。

修正前

<body
    x-data="{ menuOpen: false }"
    class="bg-gray-100"
>

修正後

<body
    x-data="{ menuOpen: false, modalOpen: false }"
    class="bg-gray-100"
>

今回追加するもの

追加するもの 内容
modalOpen: false 最初は詳細モーダルを閉じた状態にする

今回のポイント

modalOpen は、詳細モーダルの表示状態を管理するための変数です。

@click="modalOpen = true"

と組み合わせることで、詳細ボタンを押したときに modalOpentrue にできます。

このSTEPでは、まだモーダル本体は表示されません。
次のSTEPで、x-show="modalOpen" を使ってモーダル背景を表示します。

STEP 5:モーダル背景を追加する

STEP4では、bodyx-datamodalOpen: false を追加しました。

次は、modalOpentrue のときだけ表示される モーダル背景 を追加します。

このSTEPでは、まず画面全体を覆う半透明の背景だけを作ります。
モーダル本体は次のSTEPで追加します。

追加する場所

スマホ用メニューの下、main の前に追加します。

修正前

<!-- スマホ用メニュー -->
<div
    x-show="menuOpen"
    class="fixed top-0 right-0 z-40 w-64 h-screen bg-gray-700 text-white p-6 md:hidden shadow-lg"
>
    ...
</div>

<main class="flex flex-col md:flex-row items-start">

修正後

<!-- スマホ用メニュー -->
<div
    x-show="menuOpen"
    class="fixed top-0 right-0 z-40 w-64 h-screen bg-gray-700 text-white p-6 md:hidden shadow-lg"
>
    ...
</div>

<!-- モーダル背景 -->
<div
    x-show="modalOpen"
    class="fixed inset-0 z-50 bg-black/50"
>
</div>

<main class="flex flex-col md:flex-row items-start">

今回追加するもの

追加するもの 内容
x-show="modalOpen" modalOpentrue のときだけモーダル背景を表示する

今回追加するclass

class 内容
fixed 画面上に固定表示する
inset-0 上下左右すべてを 0 にして画面全体に広げる
z-50 ハンバーガーメニューより前面に表示する
bg-black/50 黒背景を50%の透明度で表示する

今回のポイント

fixed inset-0 を使うことで、モーダル背景を画面全体に広げられます。

modalOpen: false → モーダル背景を非表示
modalOpen: true  → モーダル背景を表示

Day15のハンバーガーメニューは z-40 にしました。

今回のモーダル背景は z-50 にすることで、ハンバーガーメニューより前面に表示されます。

このSTEPでは、まだ背景だけなので、詳細情報を表示する箱は出ません。
次のSTEPで、モーダル本体を追加します。

STEP 6:モーダル本体を追加する

STEP5では、modalOpentrue のときに表示されるモーダル背景を追加しました。

次は、そのモーダル背景の中に、作品の詳細情報を表示する白い箱を追加します。

この白い箱が、画面中央に表示される モーダル本体 です。

修正前

<!-- モーダル背景 -->
<div
    x-show="modalOpen"
    class="fixed inset-0 z-50 bg-black/50"
>
</div>

<main class="flex flex-col md:flex-row items-start">

修正後

<!-- 詳細モーダル -->
<div
    x-show="modalOpen"
    class="fixed inset-0 z-50 bg-black/50 flex items-center justify-center p-4"
>
    <div class="bg-white rounded-lg shadow-lg w-full max-w-md p-6">
        <h3 class="text-lg font-bold">
            サンプル映画タイトル
        </h3>

        <div class="mt-4 space-y-2 text-sm text-gray-700">
            <p>
                平均評価:4.2
            </p>

            <p>
                レビュー数:12件
            </p>

            <p>
                ここに作品の詳細情報を表示します。
            </p>
        </div>
    </div>
</div>

<main class="flex flex-col md:flex-row items-start">

今回変更するポイント

STEP5では、背景だけを表示していました。

<div
    x-show="modalOpen"
    class="fixed inset-0 z-50 bg-black/50"
>
</div>

今回は、その中に白いモーダル本体を入れます。

<div class="bg-white rounded-lg shadow-lg w-full max-w-md p-6">
    <!-- モーダル本体 -->
</div>

今回追加するclass

class 内容
flex モーダル本体を配置しやすくする
items-center モーダル本体を縦方向の中央に配置する
justify-center モーダル本体を横方向の中央に配置する
p-4 画面端とモーダルの間に余白を付ける
bg-white モーダル本体の背景を白にする
max-w-md モーダル本体の最大幅を決める
shadow-lg モーダル本体に影を付ける
space-y-2 詳細情報の行間を空ける

今回のポイント

fixed inset-0 で画面全体に広げた背景に、flex items-center justify-center を追加すると、モーダル本体を画面中央に配置できます。

背景:fixed inset-0 z-50 bg-black/50
本体:bg-white rounded-lg shadow-lg

このSTEPでは、まだ閉じるボタンはありません。

次のSTEPで、モーダル内に閉じるボタンを追加します。

STEP 7:閉じるボタンでモーダルを閉じる

STEP6では、モーダル背景とモーダル本体を追加しました。

次は、モーダル内に 閉じるボタン を追加します。

modalOpenfalse にすることで、モーダルを閉じられるようにします。

修正前

<div class="bg-white rounded-lg shadow-lg w-full max-w-md p-6">
    <h3 class="text-lg font-bold">
        サンプル映画タイトル
    </h3>

    <div class="mt-4 space-y-2 text-sm text-gray-700">
        <p>
            平均評価:4.2
        </p>

        <p>
            レビュー数:12件
        </p>

        <p>
            ここに作品の詳細情報を表示します。
        </p>
    </div>
</div>

修正後

<div class="bg-white rounded-lg shadow-lg w-full max-w-md p-6">
    <div class="flex justify-between items-center">
        <h3 class="text-lg font-bold">
            サンプル映画タイトル
        </h3>

        <button
            @click="modalOpen = false"
            class="text-2xl text-gray-500 hover:text-gray-800"
        >
            ×
        </button>
    </div>

    <div class="mt-4 space-y-2 text-sm text-gray-700">
        <p>
            平均評価:4.2
        </p>

        <p>
            レビュー数:12件
        </p>

        <p>
            ここに作品の詳細情報を表示します。
        </p>
    </div>
</div>

今回追加するもの

追加するもの 内容
@click="modalOpen = false" 閉じるボタンを押したときにモーダルを閉じる

今回追加するclass

class 内容
justify-between タイトルと閉じるボタンを左右に配置する
items-center タイトルと閉じるボタンを縦方向の中央に揃える
text-2xl 閉じるボタンの文字サイズを大きくする
text-gray-500 閉じるボタンの文字色をグレーにする
hover:text-gray-800 hover時に閉じるボタンの文字色を濃くする

今回のポイント

@click="modalOpen = false" を付けることで、閉じるボタンを押したときにモーダルを非表示にできます。

modalOpen: true
↓
閉じるボタンを押す
↓
modalOpen: false
↓
モーダルが閉じる

このSTEPで、詳細ボタンを押してモーダルを開き、× ボタンで閉じる流れができました。

次のSTEPでは、モーダルの見た目をもう少し整えます。

STEP 8:モーダルの見た目を整える

STEP7までで、詳細ボタンを押すとモーダルが表示され、閉じるボタンで閉じられるようになりました。

最後に、モーダルの見た目を少し整えます。

今回は、モーダル本体に枠線や余白、下部の閉じるボタンを追加して、管理画面の詳細表示らしくします。

修正前

<div class="bg-white rounded-lg shadow-lg w-full max-w-md p-6">
    <div class="flex justify-between items-center">
        <h3 class="text-lg font-bold">
            サンプル映画タイトル
        </h3>

        <button
            @click="modalOpen = false"
            class="text-2xl text-gray-500 hover:text-gray-800"
        >
            ×
        </button>
    </div>

    <div class="mt-4 space-y-2 text-sm text-gray-700">
        <p>
            平均評価:4.2
        </p>

        <p>
            レビュー数:12件
        </p>

        <p>
            ここに作品の詳細情報を表示します。
        </p>
    </div>
</div>

修正後

<div class="bg-white rounded-lg shadow-lg w-full max-w-md p-6 border">
    <div class="flex justify-between items-center">
        <h3 class="text-lg font-bold">
            サンプル映画タイトル
        </h3>

        <button
            @click="modalOpen = false"
            class="text-2xl text-gray-500 hover:text-gray-800"
        >
            ×
        </button>
    </div>

    <div class="mt-4 space-y-2 text-sm text-gray-700">
        <p>
            平均評価:4.2
        </p>

        <p>
            レビュー数:12件
        </p>

        <p>
            ここに作品の詳細情報を表示します。
        </p>
    </div>

    <div class="mt-6 text-right">
        <button
            @click="modalOpen = false"
            class="px-3 py-1.5 text-sm border border-gray-300 text-gray-700 rounded hover:bg-gray-200"
        >
            閉じる
        </button>
    </div>
</div>

今回追加するclass

class 内容
border モーダル本体に枠線を付ける
mt-6 閉じるボタンの上に余白を付ける
text-right 閉じるボタンを右寄せにする
px-3 ボタンの左右に余白を付ける
py-1.5 ボタンの上下に余白を付ける
border-gray-300 ボタンの枠線を薄いグレーにする
hover:bg-gray-200 hover時に薄いグレー背景にする

今回のポイント

モーダル右上の × ボタンだけでも閉じられますが、下部にも「閉じる」ボタンを置くと、操作が分かりやすくなります。

右上の ×:すぐ閉じる操作
下部の閉じる:内容を確認したあと閉じる操作

これで、Day16の詳細モーダルは完成です。

完成コード

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Day 16 詳細モーダルを作る</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
</head>
<body
    x-data="{ menuOpen: false, modalOpen: false }"
    class="bg-gray-100"
>
    <header class="bg-gray-900 text-white px-6 py-4 flex justify-between items-center">
        <h1 class="text-xl">
            Admin Dashboard
        </h1>

        <div class="flex items-center gap-4">
            <p class="text-sm hidden md:block">
                管理者:遅咲きエンジニア
            </p>

            <!-- ハンバーガーメニュー -->
            <button
                @click="menuOpen = !menuOpen"
                class="md:hidden text-2xl"
            ></button>
        </div>
    </header>

    <!-- スマホ用メニュー -->
    <div
        x-show="menuOpen"
        class="fixed top-0 right-0 z-40 w-64 h-screen bg-gray-700 text-white p-6 md:hidden shadow-lg"
    >
        <div class="flex justify-between items-center">
            <p class="font-bold">
                メニュー
            </p>

            <button
                @click="menuOpen = false"
                class="text-2xl"
            >
                ×
            </button>
        </div>

        <ul class="mt-6 space-y-3 text-sm">
            <li class="px-2 py-1 rounded hover:bg-gray-600">ダッシュボード</li>
            <li class="px-2 py-1 rounded hover:bg-gray-600">作品一覧</li>
            <li class="px-2 py-1 rounded hover:bg-gray-600">レビュー管理</li>
        </ul>
    </div>

    <!-- 詳細モーダル -->
    <div
        x-show="modalOpen"
        class="fixed inset-0 z-50 bg-black/50 flex items-center justify-center p-4"
    >
        <div class="bg-white rounded-lg shadow-lg w-full max-w-md p-6 border">
            <div class="flex justify-between items-center">
                <h3 class="text-lg font-bold">
                    サンプル映画タイトル
                </h3>

                <button
                    @click="modalOpen = false"
                    class="text-2xl text-gray-500 hover:text-gray-800"
                >
                    ×
                </button>
            </div>

            <div class="mt-4 space-y-2 text-sm text-gray-700">
                <p>
                    平均評価:4.2
                </p>

                <p>
                    レビュー数:12件
                </p>

                <p>
                    ここに作品の詳細情報を表示します。
                </p>
            </div>

            <div class="mt-6 text-right">
                <button
                    @click="modalOpen = false"
                    class="px-3 py-1.5 text-sm border border-gray-300 text-gray-700 rounded hover:bg-gray-200"
                >
                    閉じる
                </button>
            </div>
        </div>
    </div>

    <main class="flex flex-col md:flex-row items-start">
        <aside class="hidden md:block md:w-48 bg-gray-600 text-white p-4 md:min-h-screen">
            <!-- サイドバー -->
            <p class="font-bold">
                サイドバー
            </p>

            <ul class="mt-4 space-y-2 text-sm">
                <li class="px-2 py-1 rounded hover:bg-gray-500">ダッシュボード</li>
                <li class="px-2 py-1 rounded hover:bg-gray-500">作品一覧</li>
                <li class="px-2 py-1 rounded hover:bg-gray-500">レビュー管理</li>
            </ul>
        </aside>

        <div class="w-full flex-1 p-6 bg-gray-100 min-h-screen">
            <h2 class="text-lg font-bold">
                作品管理
            </h2>

            <p class="text-sm text-gray-600 mt-1">
                登録済み作品の確認・編集・削除を行います。
            </p>

            <div class="hidden md:block bg-white border rounded-lg shadow-sm mt-6">
                <table class="w-full text-sm">
                    <!-- PC用テーブル -->
                    <thead class="bg-gray-700 text-white">
                        <tr>
                            <th class="px-4 py-2 text-center">ID</th>
                            <th class="px-4 py-2 text-center">サムネイル</th>
                            <th class="px-4 py-2 text-center">タイトル</th>
                            <th class="px-4 py-2 text-center">平均評価</th>
                            <th class="px-4 py-2 text-center">レビュー数</th>
                            <th class="px-4 py-2 text-center">操作</th>
                        </tr>
                    </thead>

                    <tbody>
                        <!-- 作品データ -->
                        <tr class="border-b">
                            <td class="px-4 py-2">1</td>
                            <td class="px-4 py-2">
                                <img
                                    src="images/sample-poster.png"
                                    alt="サンプル画像"
                                    class="w-12 h-12 object-cover rounded border border-gray-300"
                                >
                            </td>
                            <td class="px-4 py-2">サンプル映画タイトル</td>
                            <td class="px-4 py-2">4.2</td>
                            <td class="px-4 py-2">12件</td>
                            <td class="px-4 py-2">
                                <div class="flex gap-2 justify-center">
                                    <button
                                        @click="modalOpen = true"
                                        class="px-2 py-1 text-xs border border-gray-300 text-gray-700 rounded hover:bg-gray-200"
                                    >
                                        詳細
                                    </button>

                                    <button class="px-2 py-1 text-xs border border-blue-500 text-blue-600 rounded hover:bg-blue-100">
                                        編集
                                    </button>

                                    <button class="px-2 py-1 text-xs border border-red-500 text-red-600 rounded hover:bg-red-100">
                                        削除
                                    </button>
                                </div>
                            </td>
                        </tr>

                        <tr class="border-b">
                            <td class="px-4 py-2">2</td>
                            <td class="px-4 py-2">
                                <img
                                    src="images/sample-poster.png"
                                    alt="サンプル画像"
                                    class="w-12 h-12 object-cover rounded border border-gray-300"
                                >
                            </td>
                            <td class="px-4 py-2">サンプル映画タイトル2</td>
                            <td class="px-4 py-2">3.8</td>
                            <td class="px-4 py-2">8件</td>
                            <td class="px-4 py-2">
                                <div class="flex gap-2 justify-center">
                                    <button
                                        @click="modalOpen = true"
                                        class="px-2 py-1 text-xs border border-gray-300 text-gray-700 rounded hover:bg-gray-200"
                                    >
                                        詳細
                                    </button>

                                    <button class="px-2 py-1 text-xs border border-blue-500 text-blue-600 rounded hover:bg-blue-100">
                                        編集
                                    </button>

                                    <button class="px-2 py-1 text-xs border border-red-500 text-red-600 rounded hover:bg-red-100">
                                        削除
                                    </button>
                                </div>
                            </td>
                        </tr>

                        <tr class="border-b">
                            <td class="px-4 py-2">3</td>
                            <td class="px-4 py-2">
                                <img
                                    src="images/sample-poster.png"
                                    alt="サンプル画像"
                                    class="w-12 h-12 object-cover rounded border border-gray-300"
                                >
                            </td>
                            <td class="px-4 py-2">サンプル映画タイトル3</td>
                            <td class="px-4 py-2">4.7</td>
                            <td class="px-4 py-2">20件</td>
                            <td class="px-4 py-2">
                                <div class="flex gap-2 justify-center">
                                    <button
                                        @click="modalOpen = true"
                                        class="px-2 py-1 text-xs border border-gray-300 text-gray-700 rounded hover:bg-gray-200"
                                    >
                                        詳細
                                    </button>

                                    <button class="px-2 py-1 text-xs border border-blue-500 text-blue-600 rounded hover:bg-blue-100">
                                        編集
                                    </button>

                                    <button class="px-2 py-1 text-xs border border-red-500 text-red-600 rounded hover:bg-red-100">
                                        削除
                                    </button>
                                </div>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <div class="md:hidden mt-6 space-y-4">
                <div class="bg-white border rounded-lg shadow-sm p-4">
                    <!-- スマホ用カード -->
                    <div class="flex gap-3">
                        <img
                            src="images/sample-poster.png"
                            alt="サンプル画像"
                            class="w-16 h-16 object-cover rounded border border-gray-300"
                        >

                        <div class="flex-1">
                            <p class="font-bold">
                                サンプル映画タイトル
                            </p>

                            <p class="text-sm text-gray-600 mt-1">
                                平均評価:4.2 / レビュー数:12件
                            </p>
                        </div>
                    </div>

                    <div class="flex gap-2 mt-3">
                        <button
                            @click="modalOpen = true"
                            class="px-2 py-1 text-xs border border-gray-300 text-gray-700 rounded hover:bg-gray-200"
                        >
                            詳細
                        </button>

                        <button class="px-2 py-1 text-xs border border-blue-500 text-blue-600 rounded hover:bg-blue-100">
                            編集
                        </button>

                        <button class="px-2 py-1 text-xs border border-red-500 text-red-600 rounded hover:bg-red-100">
                            削除
                        </button>
                    </div>
                </div>

                <div class="bg-white border rounded-lg shadow-sm p-4">
                    <!-- スマホ用カード -->
                    <div class="flex gap-3">
                        <img
                            src="images/sample-poster.png"
                            alt="サンプル画像"
                            class="w-16 h-16 object-cover rounded border border-gray-300"
                        >

                        <div class="flex-1">
                            <p class="font-bold">
                                サンプル映画タイトル2
                            </p>

                            <p class="text-sm text-gray-600 mt-1">
                                平均評価:3.8 / レビュー数:8件
                            </p>
                        </div>
                    </div>

                    <div class="flex gap-2 mt-3">
                        <button
                            @click="modalOpen = true"
                            class="px-2 py-1 text-xs border border-gray-300 text-gray-700 rounded hover:bg-gray-200"
                        >
                            詳細
                        </button>

                        <button class="px-2 py-1 text-xs border border-blue-500 text-blue-600 rounded hover:bg-blue-100">
                            編集
                        </button>

                        <button class="px-2 py-1 text-xs border border-red-500 text-red-600 rounded hover:bg-red-100">
                            削除
                        </button>
                    </div>
                </div>

                <div class="bg-white border rounded-lg shadow-sm p-4">
                    <!-- スマホ用カード -->
                    <div class="flex gap-3">
                        <img
                            src="images/sample-poster.png"
                            alt="サンプル画像"
                            class="w-16 h-16 object-cover rounded border border-gray-300"
                        >

                        <div class="flex-1">
                            <p class="font-bold">
                                サンプル映画タイトル3
                            </p>

                            <p class="text-sm text-gray-600 mt-1">
                                平均評価:4.7 / レビュー数:20件
                            </p>
                        </div>
                    </div>

                    <div class="flex gap-2 mt-3">
                        <button
                            @click="modalOpen = true"
                            class="px-2 py-1 text-xs border border-gray-300 text-gray-700 rounded hover:bg-gray-200"
                        >
                            詳細
                        </button>

                        <button class="px-2 py-1 text-xs border border-blue-500 text-blue-600 rounded hover:bg-blue-100">
                            編集
                        </button>

                        <button class="px-2 py-1 text-xs border border-red-500 text-red-600 rounded hover:bg-red-100">
                            削除
                        </button>
                    </div>
                </div>
            </div>

        </div>
    </main>
</body>
</html>

今回追加したもの

追加したもの 内容
@click="modalOpen = true" 詳細ボタンを押したときにモーダルを開く
modalOpen: false 最初は詳細モーダルを閉じた状態にする
x-show="modalOpen" modalOpentrue のときだけモーダルを表示する
@click="modalOpen = false" 閉じるボタンを押したときにモーダルを閉じる

使ったTailwind CSSのclass

class 内容
fixed 画面上に固定表示する
inset-0 上下左右すべてを 0 にして画面全体に広げる
z-50 ハンバーガーメニューより前面に表示する
bg-black/50 黒背景を50%の透明度で表示する
flex モーダル本体を中央配置しやすくする
items-center 要素を縦方向の中央に揃える
justify-center モーダル本体を横方向の中央に配置する
p-4 画面端とモーダルの間に余白を付ける
bg-white モーダル本体の背景を白にする
rounded-lg モーダル本体の角を丸くする
shadow-lg モーダル本体に影を付ける
w-full スマホ幅でも横幅を使いやすくする
max-w-md モーダル本体の最大幅を決める
border モーダル本体やボタンに枠線を付ける
text-lg モーダルタイトルの文字を大きくする
font-bold モーダルタイトルを太字にする
justify-between タイトルと閉じるボタンを左右に配置する
text-2xl 閉じるボタンの文字サイズを大きくする
text-gray-500 閉じるボタンの文字色をグレーにする
hover:text-gray-800 hover時に閉じるボタンの文字色を濃くする
mt-4 詳細情報の上に余白を付ける
space-y-2 詳細情報の行間を空ける
text-sm 詳細情報や閉じるボタンの文字を少し小さくする
text-gray-700 詳細情報の文字色を濃いグレーにする
mt-6 下部の閉じるボタンの上に余白を付ける
text-right 下部の閉じるボタンを右寄せにする
px-3 ボタンの左右に余白を付ける
py-1.5 ボタンの上下に余白を付ける
border-gray-300 ボタンの枠線を薄いグレーにする
rounded ボタンの角を少し丸くする
hover:bg-gray-200 hover時に薄いグレー背景にする

表示確認

以下の点をブラウザで確認しました。

  • 詳細ボタンをクリックするとモーダルが表示される
  • モーダル背景が画面全体に表示される
  • モーダル本体が中央に表示される
  • 右上の「×」ボタンをクリックするとモーダルが閉じる
  • 下部の「閉じる」ボタンをクリックするとモーダルが閉じる
  • スマホ表示でも詳細モーダルが表示される
  • PC表示でも詳細モーダルが表示される
  • ハンバーガーメニューよりモーダルが前面に表示される

スマホ表示

day16-mobile-detail-modal.png

PC表示

day16-pc-detail-modal.png

補足:z-indexの優先順位について

モーダルは、ユーザーに今操作してほしい内容を前面に出すUIです。

そのため、ハンバーガーメニューや通常の画面よりも、モーダルを前面に表示する必要があります。

実務では、z-index をその場の思いつきで大きくするのではなく、画面内の重なり順をあらかじめ決めておくことが多いです。

例えば、今回の管理画面UIでは以下のように考えます。

レイヤー 用途
指定なし 通常コンテンツ
z-30 固定ヘッダー
z-40 スマホ用ハンバーガーメニュー
z-50 モーダル背景・モーダル本体
z-[60] 以上 トースト通知や重要アラート

z-index: 9999 のように極端に大きい値を使うと、あとから別のUIを重ねたいときに管理しづらくなります。

今回は、Day15で作ったハンバーガーメニューよりも、詳細モーダルを前面に出したいので、モーダルには z-50 を使います。

今日分かったこと

Day16では、詳細ボタンをクリックすると表示される詳細モーダルを作りました。

modalOpen: false でモーダルの開閉状態を用意し、@click="modalOpen = true" でモーダルを開けることが分かりました。

また、x-show="modalOpen" を使うことで、modalOpentrue のときだけモーダルを表示できました。

モーダル背景には fixed inset-0 bg-black/50 を使い、画面全体を半透明の背景で覆いました。

モーダル本体は flex items-center justify-center を使うことで、画面中央に配置できました。

Day15のハンバーガーメニューは z-40、Day16の詳細モーダルは z-50 にすることで、モーダルをより前面に表示できました。

PC用テーブルとスマホ用カードの両方に同じ @click を追加することで、どちらの表示でも詳細モーダルを開けるようになりました。

次回やること

【Tailwind CSS入門 Day17】削除確認モーダルを作る

シリーズ記事

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?