目次
- はじめに
- 今日作るもの
- STEP 1:Day17用HTMLファイルを作る
- STEP 2:タイトルをDay17用に直す
- STEP 3:削除ボタンにクリック処理を追加する
- STEP 4:x-dataで削除確認モーダルの状態を用意する
- STEP 5:削除確認モーダルの背景を追加する
- STEP 6:削除確認モーダル本体を追加する
- STEP 7:×ボタンとキャンセルボタンでモーダルを閉じる
- STEP 8:削除実行ボタンの見た目を整える
- 完成コード
- 今回追加したもの
- 使ったTailwind CSSのclass
- 表示確認
- 今日分かったこと
- 次回やること
- シリーズ記事
はじめに
この記事は、Tailwind CSSで管理画面UIを1ステップずつ作る学習記録です。
過去記事は末尾の「シリーズ記事」にまとめています。
今日作るもの
Day17では、作品一覧の「削除」ボタンをクリックすると表示される削除確認モーダルを作ります。
Day16で作った詳細モーダルと同じように、Alpine.jsの x-data、@click、x-show を使って表示・非表示を切り替えます。
削除は取り消しにくい操作なので、すぐに削除するのではなく、確認モーダルを表示してから操作できるUIにします。
STEP 1:Day17用HTMLファイルを作る
まず、Day17用のHTMLファイルを作成します。
Day17では、Day16で作った詳細モーダルの流れを元にして、削除確認モーダル を追加します。
そのため、Day16の完成形をコピーして進めます。
cp day16-detail-modal.html day17-delete-confirm-modal.html
エクスプローラーでコピーしても大丈夫です。
現在の構成に、Day17用ファイルが追加される形です。
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
├── day17-delete-confirm-modal.html
└── images/
└── sample-poster.png
STEP 2:タイトルをDay17用に直す
day17-delete-confirm-modal.html の <title> を、Day17用に変更します。
修正前
<title>Day 16 詳細モーダルを作る</title>
修正後
<title>Day 17 削除確認モーダルを作る</title>
このSTEPでは、ブラウザタブに表示されるタイトルだけ を変更します。
画面に表示されているヘッダー、ハンバーガーメニュー、詳細モーダル、サイドバー、テーブル、スマホ用カード部分はまだ触りません。
STEP 3:削除ボタンにクリック処理を追加する
STEP2では、<title> をDay17用に変更しました。
次は、作品一覧の 削除ボタン をクリックしたときに、削除確認モーダルを開く処理を追加します。
このSTEPでは、まずPC用テーブルの「削除」ボタンにクリック処理を追加します。
スマホ用カードにも「削除」ボタンがありますが、学習の流れを分かりやすくするため、本文ではPC用テーブルを中心に進めます。
完成コードでは、スマホ用カード側の「削除」ボタンにも同じ処理を追加します。
修正前
<button class="px-2 py-1 text-xs border border-red-500 text-red-600 rounded hover:bg-red-100">
削除
</button>
修正後
<button
@click="deleteModalOpen = true"
class="px-2 py-1 text-xs border border-red-500 text-red-600 rounded hover:bg-red-100"
>
削除
</button>
今回追加するもの
| 追加するもの | 内容 |
|---|---|
@click="deleteModalOpen = true" |
削除ボタンを押したときに削除確認モーダルを開く |
修正箇所
PC用テーブルには、作品データが3件あります。
そのため、PC用テーブル内の「削除」ボタン 3か所 に、同じ @click="deleteModalOpen = true" を追加します。
PC用テーブル 1件目の削除ボタン
PC用テーブル 2件目の削除ボタン
PC用テーブル 3件目の削除ボタン
補足:スマホ用カード側の削除ボタンについて
本文では、PC用テーブルの削除ボタンを中心に説明しています。
ただし、完成コードではスマホ用カードからも削除確認モーダルを開けるようにするため、スマホ用カード側の「削除」ボタンにも同じ処理を追加します。
@click="deleteModalOpen = true"
今回のポイント
@click="deleteModalOpen = true" を追加することで、削除ボタンをクリックしたときに deleteModalOpen の値を true にできます。
deleteModalOpen: false → 削除確認モーダルを閉じている状態
deleteModalOpen: true → 削除確認モーダルを開いている状態
ただし、今の時点ではまだ deleteModalOpen を用意していません。
そのため、このSTEPだけではまだ正しく動きません。
次のSTEPで、x-data に deleteModalOpen: false を追加して、削除確認モーダルの開閉状態を用意します。
STEP 4:x-dataで削除確認モーダルの状態を用意する
STEP3では、削除ボタンに @click="deleteModalOpen = true" を追加しました。
次は、Alpine.jsで 削除確認モーダルが開いているかどうか を管理する状態を用意します。
Day17は、Day16の詳細モーダルを元に進めています。
すでに body には、以下の状態があります。
- menuOpen
- modalOpen
今回は、そこに削除確認モーダル用の deleteModalOpen: false を追加します。
修正前
<body
x-data="{ menuOpen: false, modalOpen: false }"
class="bg-gray-100"
>
修正後
<body
x-data="{ menuOpen: false, modalOpen: false, deleteModalOpen: false }"
class="bg-gray-100"
>
今回追加するもの
| 追加するもの | 内容 |
|---|---|
deleteModalOpen: false |
最初は削除確認モーダルを閉じた状態にする |
今回のポイント
deleteModalOpen は、削除確認モーダルの表示状態を管理するための変数です。
deleteModalOpen: false → 削除確認モーダルを閉じている状態
deleteModalOpen: true → 削除確認モーダルを開いている状態
STEP3で追加した、
@click="deleteModalOpen = true"
と組み合わせることで、削除ボタンを押したときに deleteModalOpen を true にできます。
このSTEPでは、まだ削除確認モーダル本体は表示されません。
次のSTEPで、x-show="deleteModalOpen" を使って削除確認モーダルの背景を表示します。
STEP 5:削除確認モーダルの背景を追加する
STEP4では、body の x-data に deleteModalOpen: false を追加しました。
次は、deleteModalOpen が true のときだけ表示される 削除確認モーダルの背景 を追加します。
このSTEPでは、まず画面全体を覆う半透明の背景だけを作ります。
モーダル本体は次のSTEPで追加します。
追加する場所
詳細モーダルの下、main の前に追加します。
修正前
<!-- 詳細モーダル -->
<div
x-show="modalOpen"
class="fixed inset-0 z-50 bg-black/50 flex items-center justify-center p-4"
>
...
</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>
<!-- 削除確認モーダル背景 -->
<div
x-show="deleteModalOpen"
class="fixed inset-0 z-50 bg-black/50"
>
</div>
<main class="flex flex-col md:flex-row items-start">
今回追加するもの
| 追加するもの | 内容 |
|---|---|
x-show="deleteModalOpen" |
deleteModalOpen が true のときだけ削除確認モーダル背景を表示する |
今回追加するclass
| class | 内容 |
|---|---|
fixed |
画面上に固定表示する |
inset-0 |
上下左右すべてを 0 にして画面全体に広げる |
z-50 |
通常画面やハンバーガーメニューより前面に表示する |
bg-black/50 |
黒背景を50%の透明度で表示する |
今回のポイント
fixed inset-0 を使うことで、削除確認モーダルの背景を画面全体に広げられます。
deleteModalOpen: false → 削除確認モーダル背景を非表示
deleteModalOpen: true → 削除確認モーダル背景を表示
このSTEPでは、まだ背景だけなので、確認メッセージや削除実行ボタンは表示されません。
次のSTEPで、削除確認モーダル本体を追加します。
STEP 6:削除確認モーダル本体を追加する
STEP5では、deleteModalOpen が true のときに表示される削除確認モーダルの背景を追加しました。
次は、その背景の中に、削除前の確認メッセージを表示する白い箱を追加します。
この白い箱が、画面中央に表示される 削除確認モーダル本体 です。
修正前
<!-- 削除確認モーダル背景 -->
<div
x-show="deleteModalOpen"
class="fixed inset-0 z-50 bg-black/50"
>
</div>
<main class="flex flex-col md:flex-row items-start">
修正後
<!-- 削除確認モーダル -->
<div
x-show="deleteModalOpen"
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">
<h3 class="text-lg font-bold text-red-600">
作品を削除しますか?
</h3>
<p class="mt-4 text-sm text-gray-700">
この操作は取り消せません。削除してよろしいですか?
</p>
</div>
</div>
<main class="flex flex-col md:flex-row items-start">
今回追加するclass
| class | 内容 |
|---|---|
flex |
モーダル本体を配置しやすくする |
items-center |
モーダル本体を縦方向の中央に配置する |
justify-center |
モーダル本体を横方向の中央に配置する |
p-4 |
画面端とモーダルの間に余白を付ける |
bg-white |
モーダル本体の背景を白にする |
rounded-lg |
モーダル本体の角を丸くする |
shadow-lg |
モーダル本体に影を付ける |
w-full |
スマホ幅でも横幅を使いやすくする |
max-w-md |
モーダル本体の最大幅を決める |
border |
モーダル本体に枠線を付ける |
text-red-600 |
削除確認の見出しを赤色にする |
今回のポイント
削除は元に戻しにくい操作なので、通常の詳細モーダルよりも 注意が必要な操作 と分かる見た目にします。
詳細モーダル:通常の確認
削除確認モーダル:危険操作の確認
そのため、見出しには text-red-600 を使って、削除操作であることが伝わるようにします。
STEP 7:×ボタンとキャンセルボタンでモーダルを閉じる
STEP6では、削除確認モーダル本体を追加しました。
次は、モーダル内に ×ボタン と キャンセルボタン を追加します。
削除確認モーダルでは、すぐに削除するのではなく、右上の「×ボタン」または「キャンセル」から閉じられるようにします。
修正前
<div class="bg-white rounded-lg shadow-lg w-full max-w-md p-6 border">
<h3 class="text-lg font-bold text-red-600">
作品を削除しますか?
</h3>
<p class="mt-4 text-sm text-gray-700">
この操作は取り消せません。削除してよろしいですか?
</p>
</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 text-red-600">
作品を削除しますか?
</h3>
<button
@click="deleteModalOpen = false"
class="text-2xl text-gray-500 hover:text-gray-800"
>
×
</button>
</div>
<p class="mt-4 text-sm text-gray-700">
この操作は取り消せません。削除してよろしいですか?
</p>
<div class="mt-6 flex justify-end gap-2">
<button
@click="deleteModalOpen = false"
class="px-3 py-1.5 text-sm border border-gray-300 text-gray-700 rounded hover:bg-gray-200"
>
キャンセル
</button>
</div>
</div>
今回追加するもの
| 追加するもの | 内容 |
|---|---|
@click="deleteModalOpen = false" |
キャンセルボタンを押したときに削除確認モーダルを閉じる |
今回追加するclass
| class | 内容 |
|---|---|
mt-6 |
ボタンエリアの上に余白を付ける |
justify-end |
ボタンを右寄せにする |
gap-2 |
ボタン同士の間隔を空ける |
px-3 |
ボタンの左右に余白を付ける |
py-1.5 |
ボタンの上下に余白を付ける |
border-gray-300 |
ボタンの枠線を薄いグレーにする |
hover:bg-gray-200 |
hover時に薄いグレー背景にする |
今回のポイント
@click="deleteModalOpen = false" を付けることで、右上の「×」ボタンと「キャンセル」ボタンのどちらからでも削除確認モーダルを閉じられます。
deleteModalOpen: true
↓
×ボタン、またはキャンセルボタンを押す
↓
deleteModalOpen: false
↓
削除確認モーダルが閉じる
削除確認モーダルでは、閉じる操作と削除する操作を分けておくと分かりやすくなります。
このSTEPでは、まだ「削除する」ボタンは追加しません。
次のSTEPで、赤系の削除実行ボタンを追加します。
STEP 8:削除実行ボタンの見た目を整える
STEP7では、右上の「×ボタン」と「キャンセル」ボタンで、削除確認モーダルを閉じられるようにしました。
次は、赤系の 削除するボタン を追加します。
削除は危険操作なので、通常のボタンとは違い、赤系の色で分かりやすくします。
修正前
<div class="mt-6 flex justify-end gap-2">
<button
@click="deleteModalOpen = 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="mt-6 flex justify-end gap-2">
<button
@click="deleteModalOpen = false"
class="px-3 py-1.5 text-sm border border-gray-300 text-gray-700 rounded hover:bg-gray-200"
>
キャンセル
</button>
<button
class="px-3 py-1.5 text-sm border border-red-500 text-red-600 rounded hover:bg-red-100"
>
削除する
</button>
</div>
今回追加するclass
| class | 内容 |
|---|---|
border-red-500 |
削除ボタンの枠線を赤系にする |
text-red-600 |
削除ボタンの文字色を赤系にする |
hover:bg-red-100 |
hover時に薄い赤背景にする |
今回のポイント
削除確認モーダルでは、閉じる操作 と 削除する操作 を分けて表示します。
×ボタン:削除せず閉じる
キャンセル:削除せず閉じる
削除する:削除操作
今回は学習用の静的HTMLなので、「削除する」ボタンを押しても実際の削除処理は行いません。
実際のWebアプリでは、このボタンに削除処理やフォーム送信処理をつなげます。
これで、Day17の削除確認モーダルは完成です。
完成コード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Day 17 削除確認モーダルを作る</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, deleteModalOpen: 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>
<!-- 削除確認モーダル -->
<div
x-show="deleteModalOpen"
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 text-red-600">
作品を削除しますか?
</h3>
<button
@click="deleteModalOpen = false"
class="text-2xl text-gray-500 hover:text-gray-800"
>
×
</button>
</div>
<p class="mt-4 text-sm text-gray-700">
この操作は取り消せません。削除してよろしいですか?
</p>
<div class="mt-6 flex justify-end gap-2">
<button
@click="deleteModalOpen = false"
class="px-3 py-1.5 text-sm border border-gray-300 text-gray-700 rounded hover:bg-gray-200"
>
キャンセル
</button>
<button
class="px-3 py-1.5 text-sm border border-red-500 text-red-600 rounded hover:bg-red-100"
>
削除する
</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
@click="deleteModalOpen = true"
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
@click="deleteModalOpen = true"
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
@click="deleteModalOpen = true"
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
@click="deleteModalOpen = true"
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
@click="deleteModalOpen = true"
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
@click="deleteModalOpen = true"
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="deleteModalOpen = true" |
削除ボタンを押したときに削除確認モーダルを開く |
deleteModalOpen: false |
最初は削除確認モーダルを閉じた状態にする |
x-show="deleteModalOpen" |
deleteModalOpen が true のときだけ削除確認モーダルを表示する |
@click="deleteModalOpen = 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-red-600 |
削除確認の見出しや削除ボタンの文字色を赤系にする |
border-red-500 |
削除ボタンの枠線を赤系にする |
hover:bg-red-100 |
hover時に薄い赤背景にする |
表示確認
以下の点をブラウザで確認しました。
- 削除ボタンをクリックすると削除確認モーダルが表示される
- モーダル背景が画面全体に表示される
- モーダル本体が中央に表示される
- 見出しが赤色になり、削除操作であることが分かりやすい
- 右上の「×」ボタンをクリックするとモーダルが閉じる
- 「キャンセル」ボタンをクリックするとモーダルが閉じる
- 「削除する」ボタンが赤系の見た目になっている
- PC表示でも削除確認モーダルが表示される
- スマホ表示でも削除確認モーダルが表示される
PC表示
スマホ表示
今日分かったこと
Day17では、削除ボタンをクリックすると表示される削除確認モーダルを作りました。
deleteModalOpen: false で削除確認モーダルの開閉状態を用意し、@click="deleteModalOpen = true" でモーダルを開けることが分かりました。
また、x-show="deleteModalOpen" を使うことで、削除確認モーダルを必要なときだけ表示できました。
削除確認モーダルでは、右上の「×」ボタンと「キャンセル」ボタンのどちらからでも閉じられるようにしました。
削除は取り消しにくい操作なので、見出しや「削除する」ボタンを赤系にすることで、危険操作であることが分かりやすくなりました。
PC用テーブルとスマホ用カードの両方に同じ @click を追加することで、どちらの表示でも削除確認モーダルを開けるようになりました。
次回やること
シリーズ記事
- 【Tailwind CSS入門 Day1】管理画面の見出しを作る
- 【Tailwind CSS入門 Day2】カードUIの土台を作る
- 【Tailwind CSS入門 Day3】画像付きカードを作る
- 【Tailwind CSS入門 Day4】作品情報の文字を整える
- 【Tailwind CSS入門 Day5】管理画面風のボタンを作る
- 【Tailwind CSS入門 Day6】作品カードUIを完成させる
- 【Tailwind CSS入門 Day7】管理画面風ボタンを色分けする
- 【Tailwind CSS入門 Day8】管理画面ヘッダーを作る
- 【Tailwind CSS入門 Day9】PC用サイドバーを作る
- 【Tailwind CSS入門 Day10】PC管理画面レイアウトを作る
- 【Tailwind CSS入門 Day11】作品一覧テーブルを作る
- 【Tailwind CSS入門 Day12】テーブルの見た目を整える
- 【Tailwind CSS入門 Day13】レスポンシブ表示に切り替える
- 【Tailwind CSS入門 Day14】Alpine.jsの基礎を学ぶ
- 【Tailwind CSS入門 Day15】ハンバーガーメニューを作る
- 【Tailwind CSS入門 Day16】詳細モーダルを作る
- 【Tailwind CSS入門 Day17】削除確認モーダルを作る ← 今回

