目次
- はじめに
- 今日作るもの
- STEP 1:Day14用HTMLファイルを作る
- STEP 2:タイトルをDay14用に直す
- STEP 3:Alpine.jsを読み込む
- STEP 4:x-dataで状態を用意する
- STEP 5:クリックで状態を切り替える
- STEP 6:x-showで表示・非表示を切り替える
- STEP 7:表示確認用のメッセージを整える
- 完成コード
- 今回追加したもの
- 使ったTailwind CSSのclass
- 表示確認
- 今日分かったこと
- 次回やること
- シリーズ記事
はじめに
この記事は、Tailwind CSSで管理画面UIを1ステップずつ作る学習記録です。
過去記事は末尾の「シリーズ記事」にまとめています。
今日作るもの
Day14では、Day15のハンバーガーメニュー作成に向けて、Alpine.jsの基本を確認します。
今回は、ボタンをクリックするとメッセージの表示・非表示が切り替わる小さなサンプルを作ります。
x-data、@click、x-show を使い、HTMLに状態と動きを追加する流れを学びます。
STEP 1:Day14用HTMLファイルを作る
まず、Day14用のHTMLファイルを作成します。
Day14では、Day15のハンバーガーメニュー作成に向けて、Alpine.jsの基本を確認します。
Day13の完成形を元にして進めたいので、Day13ファイルをコピーします。
cp day13-responsive-layout.html day14-alpine-basic.html
エクスプローラーでコピーしても大丈夫です。
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
└── images/
└── sample-poster.png
STEP 2:タイトルをDay14用に直す
day14-alpine-basic.html の <title> を、Day14用に変更します。
修正前
<title>Day 13 レスポンシブ表示に切り替える</title>
修正後
<title>Day 14 Alpine.jsの基礎を学ぶ</title>
このSTEPでは、ブラウザタブに表示されるタイトルだけ を変更します。
画面に表示されているヘッダー、サイドバー、メインエリア、テーブル、スマホ用カード部分はまだ触りません。
STEP 3:Alpine.jsを読み込む
次に、day14-alpine-basic.html で Alpine.js を使えるようにします。
Alpine.js は、Tailwind CSS と同じように CDN から読み込めます。
公式ドキュメントでは、<head> 内に defer 付きの script タグを追加する方法が紹介されています。
修正前
<script src="https://cdn.tailwindcss.com"></script>
修正後
<script src="https://cdn.tailwindcss.com"></script>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
今回追加するもの
| 追加するもの | 内容 |
|---|---|
| Alpine.js CDN | Alpine.jsをHTML内で使えるようにする |
defer |
HTMLの読み込みを邪魔しないように、あとからJavaScriptを実行する |
今回のポイント
Alpine.jsを使うには、まずJavaScriptファイルを読み込む必要があります。
今回は学習用なので、ビルド環境は使わず、CDNで読み込みます。
defer を付けることで、HTMLの読み込みが終わってからAlpine.jsが実行されます。
STEP 4:x-dataで状態を用意する
Alpine.jsを読み込めたので、次は 状態を管理する場所 を作ります。
今回は、ボタンをクリックしたらメッセージを表示・非表示にするために、open という状態を用意します。
追加する場所
メインエリアの説明文の下に追加します。
修正前
<p class="text-sm text-gray-600 mt-1">
登録済み作品の確認・編集・削除を行います。
</p>
修正後
<p class="text-sm text-gray-600 mt-1">
登録済み作品の確認・編集・削除を行います。
</p>
<!-- Alpine.js動作確認エリア -->
<div
x-data="{ open: false }"
class="mt-6 bg-white border rounded-lg shadow-sm p-4"
>
<p class="font-bold">
Alpine.jsの動作確認
</p>
</div>
今回追加するもの
| 追加するもの | 内容 |
|---|---|
x-data |
Alpine.jsで使う状態を用意する |
open: false |
最初は閉じた状態にする |
今回のポイント
x-data は、Alpine.jsで状態を持たせたい範囲に付けます。
今回は、
x-data="{ open: false }"
と書くことで、open という状態を用意しています。
open: false → 閉じている状態
open: true → 開いている状態
このSTEPでは、まだクリック処理や表示切り替えは行いません。
まずは、Alpine.jsで使う状態を用意するところまで進めます。
STEP 5:クリックで状態を切り替える
STEP4では、x-data で open という状態を用意しました。
次は、ボタンをクリックしたときに open の値を切り替えます。
修正前
<!-- Alpine.js動作確認エリア -->
<div
x-data="{ open: false }"
class="mt-6 bg-white border rounded-lg shadow-sm p-4"
>
<p class="font-bold">
Alpine.jsの動作確認
</p>
</div>
修正後
<!-- Alpine.js動作確認エリア -->
<div
x-data="{ open: false }"
class="mt-6 bg-white border rounded-lg shadow-sm p-4"
>
<p class="font-bold">
Alpine.jsの動作確認
</p>
<button
@click="open = !open"
class="mt-3 px-3 py-1.5 text-sm border border-blue-500 text-blue-600 rounded hover:bg-blue-100"
>
表示を切り替える
</button>
</div>
今回追加するもの
| 追加するもの | 内容 |
|---|---|
@click |
クリックしたときの処理を書く |
open = !open |
open の true / false を切り替える |
今回追加するclass
| class | 内容 |
|---|---|
mt-3 |
ボタンの上に余白を付ける |
px-3 |
ボタンの左右に余白を付ける |
py-1.5 |
ボタンの上下に余白を付ける |
text-sm |
ボタン文字を少し小さくする |
border-blue-500 |
ボタンの枠線を青系にする |
text-blue-600 |
ボタン文字を青系にする |
hover:bg-blue-100 |
hover時に薄い青背景にする |
今回のポイント
@click="open = !open" を付けることで、ボタンをクリックするたびに open の値が切り替わります。
open が false のとき → true にする
open が true のとき → false にする
このSTEPでは、まだ表示・非表示は変わりません。
次のSTEPで x-show を使い、open の値に合わせてメッセージを表示・非表示にします。
STEP 6:x-showで表示・非表示を切り替える
STEP5では、ボタンをクリックしたときに open の値を切り替える処理を追加しました。
次は、x-show を使って、open が true のときだけメッセージを表示します。
修正前
<!-- Alpine.js動作確認エリア -->
<div
x-data="{ open: false }"
class="mt-6 bg-white border rounded-lg shadow-sm p-4"
>
<p class="font-bold">
Alpine.jsの動作確認
</p>
<button
@click="open = !open"
class="mt-3 px-3 py-1.5 text-sm border border-blue-500 text-blue-600 rounded hover:bg-blue-100"
>
表示を切り替える
</button>
</div>
修正後
<!-- Alpine.js動作確認エリア -->
<div
x-data="{ open: false }"
class="mt-6 bg-white border rounded-lg shadow-sm p-4"
>
<p class="font-bold">
Alpine.jsの動作確認
</p>
<button
@click="open = !open"
class="mt-3 px-3 py-1.5 text-sm border border-blue-500 text-blue-600 rounded hover:bg-blue-100"
>
表示を切り替える
</button>
<p
x-show="open"
class="mt-3 text-sm text-gray-700"
>
ボタンをクリックすると、このメッセージの表示・非表示が切り替わります。
</p>
</div>
今回追加するもの
| 追加するもの | 内容 |
|---|---|
x-show |
条件に応じて表示・非表示を切り替える |
x-show="open" |
open が true のときだけ表示する |
今回追加するclass
| class | 内容 |
|---|---|
mt-3 |
メッセージの上に余白を付ける |
text-sm |
メッセージの文字を少し小さくする |
text-gray-700 |
メッセージの文字色を濃いグレーにする |
今回のポイント
x-show="open" を付けることで、open の値に合わせて表示を切り替えられます。
open: false → 非表示
open: true → 表示
STEP5で追加した @click="open = !open" と組み合わせることで、ボタンを押すたびにメッセージの表示・非表示が切り替わります。
STEP 7:表示確認用のメッセージを整える
STEP6で、x-show を使ってメッセージの表示・非表示を切り替えられるようにしました。
最後に、表示されるメッセージを少しだけ見やすく整えます。
修正前
<p
x-show="open"
class="mt-3 text-sm text-gray-700"
>
ボタンをクリックすると、このメッセージの表示・非表示が切り替わります。
</p>
修正後
<p
x-show="open"
class="mt-3 text-sm text-gray-700 bg-blue-50 border border-blue-200 rounded p-3"
>
ボタンをクリックすると、このメッセージの表示・非表示が切り替わります。
</p>
今回追加するclass
| class | 内容 |
|---|---|
bg-blue-50 |
メッセージの背景を薄い青にする |
border-blue-200 |
メッセージの枠線を薄い青にする |
rounded |
メッセージの角を少し丸くする |
p-3 |
メッセージの内側に余白を付ける |
今回のポイント
x-show で表示されるメッセージに背景色、枠線、余白を付けることで、通常の文章ではなく 表示切り替えの確認エリア として分かりやすくなります。
ここまでで、Day14のAlpine.js基礎サンプルは完成です。
完成コード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Day 14 Alpine.jsの基礎を学ぶ</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 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>
<p class="text-sm">
管理者:遅咲きエンジニア
</p>
</header>
<main class="flex flex-col md:flex-row items-start">
<aside class="w-full 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>
<!-- Alpine.js動作確認エリア -->
<div
x-data="{ open: false }"
class="mt-6 bg-white border rounded-lg shadow-sm p-4"
>
<p class="font-bold">
Alpine.jsの動作確認
</p>
<button
@click="open = !open"
class="mt-3 px-3 py-1.5 text-sm border border-blue-500 text-blue-600 rounded hover:bg-blue-100"
>
表示を切り替える
</button>
<p
x-show="open"
class="mt-3 text-sm text-gray-700 bg-blue-50 border border-blue-200 rounded p-3"
>
ボタンをクリックすると、このメッセージの表示・非表示が切り替わります。
</p>
</div>
<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 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 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 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 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 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 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>
今回追加したもの
| 追加したもの | 内容 |
|---|---|
| Alpine.js CDN | Alpine.jsをHTML内で使えるようにする |
defer |
HTMLの読み込みを邪魔しないように、あとからJavaScriptを実行する |
x-data |
Alpine.jsで使う状態を用意する |
open: false |
open の初期値を false にする |
@click |
クリックしたときの処理を書く |
open = !open |
open の true / false を切り替える |
x-show |
条件に応じて表示・非表示を切り替える |
x-show="open" |
open が true のときだけ表示する |
使ったTailwind CSSのclass
| class | 内容 |
|---|---|
mt-3 |
ボタンやメッセージの上に余白を付ける |
px-3 |
ボタンの左右に余白を付ける |
py-1.5 |
ボタンの上下に余白を付ける |
text-sm |
ボタンやメッセージの文字を少し小さくする |
border |
ボタンやメッセージに枠線を付ける |
border-blue-500 |
ボタンの枠線を青系にする |
text-blue-600 |
ボタン文字を青系にする |
rounded |
ボタンやメッセージの角を少し丸くする |
hover:bg-blue-100 |
hover時に薄い青背景にする |
text-gray-700 |
メッセージの文字色を濃いグレーにする |
bg-blue-50 |
メッセージの背景を薄い青にする |
border-blue-200 |
メッセージの枠線を薄い青にする |
p-3 |
メッセージの内側に余白を付ける |
表示確認
以下の点をブラウザで確認しました。
- Alpine.js動作確認エリアが表示されている
- 初期表示では、確認メッセージが表示されていない
- 「表示を切り替える」ボタンが表示されている
- ボタンをクリックすると、確認メッセージが表示される
- もう一度ボタンをクリックすると、確認メッセージが非表示になる
- 表示されたメッセージに薄い青背景、枠線、余白が付いている
メッセージ非表示時
メッセージ表示時
今日分かったこと
Day14では、Alpine.jsを使って、クリックで表示・非表示を切り替える基本を学びました。
Alpine.jsを使うには、まずCDNでJavaScriptを読み込む必要があると分かりました。
x-data を使うと、HTML内に状態を持たせることができます。
今回は open: false を用意し、最初は閉じた状態にしました。
@click="open = !open" を使うことで、ボタンをクリックするたびに open の値を切り替えられました。
さらに x-show="open" を使うことで、open が true のときだけメッセージを表示できました。
Day14では、Day15のハンバーガーメニューに向けて、Alpine.jsで表示を切り替える基本の流れを確認できました。
次回やること
-【Tailwind CSS入門 Day15】ハンバーガーメニューを作る
シリーズ記事
- 【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の基礎を学ぶ ← 今回

