前回は、AstroにTailwind CSSとそのプラグインである「typography」を追加しました。

今回はTailwindを使って、サイトに以下のデザインを追加していくことにします。
- 2カラム化(メイン記事 + サイドバー)
- レスポンシブデザイン対応(スマホ・PCでの表示切り替え)
2カラムの導入方法
Tailwindでは「CSS Grid(グリッド)」という機能を使うことで、CSSファイルをわざわざ編集しなくても、HTML(Astroファイル)にクラスをいくつか書き足すだけで、この両方を簡単に実装することができます。
すべてのページの土台となっている src/layouts/BaseLayout.astro を編集して、サイト全体を2カラムにします。
コードの概略は以下のようになります。
{/* コンテンツ領域のコンテナ設定 */}
<div class="max-w-6xl mx-auto px-4 py-8">
{/* グリッドの適用 */}
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
{/* 左側:メインコンテンツ(全体の2/3の幅) */}
<main class="md:col-span-2">
<slot />
</main>
{/* 右側:サイドバー(全体の1/3の幅) */}
<aside class="md:col-span-1">
<section>
サイドバーパーツ1
</section>
<section>
サイドバーパーツ2
</section>
</aside>
</div>
</div>
上記のコードで使われているTailwindのクラスには、それぞれ以下のような重要な役割があります。
コンテンツ領域のコンテナ設定
コンテンツをページの中央に寄せて、読みやすい最大幅や余白を設定します。
以下の組み合わせは、様々なサイトでよく使われる王道の設定です。
- max-w-6xl
-
「最大幅」の制限です。
画面が広くても、コンテンツの横幅は最大 72rem(約 1152px)までに留めます。 - mx-auto
-
「水平方向の中央寄せ」です。
「m」はマージン(外側の余白)、「x」はX軸(左右)を表し、左右の外側の余白を自動(auto)で均等に割り当てて、箱を画面の中央に配置します。 - px-4
-
「内側・左右の余白」です。
「p」はパディング(内側の余白)、「x」はX軸(左右)を表し、内側の左右に 1rem(16px)の隙間を空けます。主にスマホ表示の際に、文字が画面の端に張り付くのを防ぎます。 - py-8
-
「内側・上下の余白」です。
「p」はパディング、「y」はY軸(上下)を表し、内側の上下に 2rem(32px)の隙間を空けて窮屈さをなくします。
グリッドの適用
- grid
- ここからグリッド(格子状のレイアウト)を使うぞ、という宣言です。
- grid-cols-1
- 基本(スマホで見ている時など)は、画面を「1列」にします。
- md:grid-cols-3
- 「md:」はMedium(768px)以上の画面幅のときだけという意味で、「grid-cols-3」は画面を「3列」に分割します。
- gap-8
- 要素と要素の間のスペース(隙間)を 8(32px)空けます。
メインコンテンツとサイドバーの割り当て
画面を3分割できたので、あとはメインとサイドバーにどう割り当てるかを指定します。
メインコンテンツ(md:col-span-2)
「md:」768px以上の画面幅のときだけ、「col-span-2」3列のうち2列分を使用するという指定です。
サイドバー(md:col-span-1)
「md:」768px以上の画面幅のときだけ、「col-span-1」3列のうち1列分を使用するという指定です。
このように、Tailwindでは 「md:」を使用するだけで、簡単にスマホ対応のレスポンシブデザインを実現することができます!!
実際のコード(完成形)
最後に、プロフィールやカテゴリーなどのパーツを配置した、実際の BaseLayout.astro の設定例です。
---
import BaseHead from '../components/BaseHead.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
import '../styles/global.css';
// サイト全体のデフォルト設定(基本の看板と予備の説明文)
const siteName = "Game Life";
const defaultDescription = "ゲームに関するブログです。";
// 各ページから渡される固有のデータを受け取る
const { pageTitle, pageDescription } = Astro.props;
// タイトルの合体
// pageTitleが渡されていれば「ページ名 | サイト名」にし、無ければ「サイト名」のみにする
const finalTitle = pageTitle ? `${pageTitle} | ${siteName}` : siteName;
// 説明文の代役
// pageDescriptionが渡されていればそれを使い、無ければデフォルトを使う
const finalDescription = pageDescription || defaultDescription;
---
{/* main領域のコンテナ設定 */}
<div class="max-w-6xl mx-auto px-4 py-8">
{/* グリッドの適用 */}
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
{/* 左側:メインコンテンツ(全体の2/3の幅) */}
<main class="md:col-span-2">
<slot />
</main>
{/* 右側:サイドバー(全体の1/3の幅) */}
<aside class="md:col-span-1">
<div class="space-y-8">
{/* サイドバー内のパーツ例:プロフィール */}
<section class="bg-slate-50 p-6 rounded-xl shadow-sm border border-slate-200">
<h3 class="text-lg font-bold border-b-2 border-blue-500 pb-2 mb-4">プロフィール</h3>
<p class="text-sm text-slate-600 leading-relaxed">
ここにプロフィールの文章が入ります。
</p>
</section>
{/* サイドバー内のパーツ例:カテゴリー */}
<section class="bg-slate-50 p-6 rounded-xl shadow-sm border border-slate-200">
<h3 class="text-lg font-bold border-b-2 border-blue-500 pb-2 mb-4">カテゴリー</h3>
<ul class="text-sm space-y-2 text-blue-600">
<li><a href="#" class="hover:underline">ブログ</a></li>
<li><a href="#" class="hover:underline">ゲーム</a></li>
</ul>
</section>
</div>
</aside>
</div>
</div>
<Footer />
</body>
</html>
2カラム化適用後の画面
2カラム化適用後の画面は以下のとおりです
画面が狭い場合は、サイドメニューは画面の下部に移動します。




コメント