CSS / Tailwind コピペで使える Tips 集【中級者向け実践パターン】

CSS Tailwind コピペしてすぐ使えるパターンを一冊にまとめました。実務経験があるけれど「あのレイアウトどう書くんだっけ」と毎回調べている方に向けた、引き出しを増やすための Tips 集です。

レイアウト定番パターン

水平・垂直センタリング

最も頻出の「画面中央に置く」パターンは Flexbox か Grid で一発です。

/* Flexbox */
.center-flex {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Grid(1行で書ける) */
.center-grid {
  display: grid;
  place-items: center;
}

Tailwind では次のクラスで同じことができます。

<!-- Flexbox -->
<div class="flex items-center justify-center">...</div>

<!-- Grid -->
<div class="grid place-items-center">...</div>

定番グリッドレイアウト

レスポンシブなカードグリッドは auto-fill + minmax で列数を自動計算させるのが鉄板です。

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.5rem;
}

Tailwind v3 以降では任意値で同等のレイアウトを作れます。

<div class="grid gap-6 [grid-template-columns:repeat(auto-fill,minmax(280px,1fr))]">
  ...
</div>

スティッキーフッター

コンテンツが少なくてもフッターを画面下部に固定するパターンです。

body {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

main {
  flex: 1;
}
<!-- Tailwind -->
<body class="flex flex-col min-h-dvh">
  <header>...</header>
  <main class="flex-1">...</main>
  <footer>...</footer>
</body>

サイドバー付き 2 カラムレイアウト

サイドバーは幅固定、メインは残りを埋める古典的パターン。

.layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 2rem;
}
<div class="grid gap-8 [grid-template-columns:240px_1fr]">
  <aside>...</aside>
  <main>...</main>
</div>

CSS カスタムプロパティ(変数)活用

デザイントークンをまとめて管理

色・スペーシング・タイポグラフィを変数化しておくと、テーマ変更が :root の書き換えだけで済みます。

:root {
  --color-primary: #3b82f6;
  --color-primary-hover: #2563eb;
  --color-surface: #ffffff;
  --color-text: #1e293b;

  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 2rem;

  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 16px;

  --shadow-card: 0 1px 3px rgb(0 0 0 / 0.12), 0 1px 2px rgb(0 0 0 / 0.08);
}

[data-theme="dark"] {
  --color-surface: #0f172a;
  --color-text: #f1f5f9;
}

Tailwind と CSS 変数を組み合わせる

Tailwind の @layer base でトークンを定義し、任意値クラスから参照します。

/* globals.css */
@layer base {
  :root {
    --brand: 59 130 246;
  }
}
<!-- bg に透明度も付けられる -->
<div class="bg-[rgb(var(--brand)/0.1)] text-[rgb(var(--brand))]">...</div>

コンポーネントスコープの変数

コンポーネント単位で変数をスコープするとスタイルの衝突を防げます。

.card {
  --card-padding: var(--space-md);
  --card-radius: var(--radius-md);

  padding: var(--card-padding);
  border-radius: var(--card-radius);
  box-shadow: var(--shadow-card);
}

.card--compact {
  --card-padding: var(--space-sm);
}

アニメーション・トランジション

フェードイン(View Transitions API 対応)

@keyframes fade-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

.fade-in {
  animation: fade-in 0.3s ease-out both;
}

Tailwind では animate- + 任意値で書けます。ただし複雑なキーフレームは globals.css に定義してクラスで呼び出す方が読みやすいです。

/* globals.css */
@layer utilities {
  .animate-fade-in {
    animation: fade-in 0.3s ease-out both;
  }
}

ホバー時のスムーズトランジション

.btn {
  transition: background-color 150ms ease, box-shadow 150ms ease, transform 150ms ease;
}

.btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgb(0 0 0 / 0.15);
}

.btn:active {
  transform: translateY(0);
}

Tailwind:

<button class="transition-all duration-150 ease-out hover:-translate-y-px hover:shadow-md active:translate-y-0">
  クリック
</button>

スケルトンローディング

@keyframes shimmer {
  from { background-position: -200% 0; }
  to   { background-position:  200% 0; }
}

.skeleton {
  background: linear-gradient(
    90deg,
    #e2e8f0 25%,
    #f1f5f9 50%,
    #e2e8f0 75%
  );
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: var(--radius-sm);
}
<div class="skeleton h-4 w-full rounded"></div>
<div class="skeleton h-4 w-3/4 rounded mt-2"></div>

Tailwind の便利クラス組み合わせ

テキストの省略(1 行 / 複数行)

<!-- 1行で省略 -->
<p class="truncate">長いテキストが省略されます...</p>

<!-- 2行で省略(line-clamp) -->
<p class="line-clamp-2">2行を超えた場合に省略されます...</p>

<!-- 3行で省略 -->
<p class="line-clamp-3">...</p>

アスペクト比固定のメディアコンテナ

<!-- 16:9 -->
<div class="aspect-video w-full overflow-hidden rounded-lg">
  <img src="..." class="h-full w-full object-cover" alt="" />
</div>

<!-- 正方形サムネイル -->
<div class="aspect-square w-16 overflow-hidden rounded-full">
  <img src="..." class="h-full w-full object-cover" alt="" />
</div>

フォーカスリングのアクセシビリティ対応

<button class="focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2">
  ボタン
</button>

マウス操作ではリングを非表示、キーボード操作では表示する :focus-visible ベースのパターンです。

グラスモーフィズムカード

<div class="backdrop-blur-md bg-white/10 border border-white/20 rounded-2xl p-6 shadow-xl">
  グラスモーフィズム
</div>

スクロールスナップ

<div class="flex overflow-x-auto snap-x snap-mandatory gap-4 pb-4">
  <div class="snap-start shrink-0 w-72 rounded-xl bg-slate-100 p-4">カード1</div>
  <div class="snap-start shrink-0 w-72 rounded-xl bg-slate-100 p-4">カード2</div>
  <div class="snap-start shrink-0 w-72 rounded-xl bg-slate-100 p-4">カード3</div>
</div>

:has() セレクタなど新しい CSS

:has() で親要素をスタイリング

これまで JavaScript が必要だった「子要素の状態で親を変える」操作が CSS だけで書けます。

/* チェックされたラベルを強調 */
label:has(input[type="checkbox"]:checked) {
  background-color: #eff6ff;
  border-color: #3b82f6;
  color: #1d4ed8;
}

/* 画像がない場合にプレースホルダーを表示 */
.card:not(:has(img)) .placeholder {
  display: block;
}

/* フォームにエラーがあれば送信ボタンをグレーアウト */
form:has(.error:not(:empty)) button[type="submit"] {
  opacity: 0.5;
  pointer-events: none;
}

:is() と :where() でセレクタを簡潔に

/* :is() — 詳細度はリスト内の最高値を引き継ぐ */
:is(h1, h2, h3, h4) {
  line-height: 1.3;
  font-weight: 700;
}

/* :where() — 詳細度は常に 0(上書きしやすい) */
:where(ul, ol) {
  list-style: none;
  padding: 0;
  margin: 0;
}

@layer でカスケードを明示管理

@layer reset, base, components, utilities;

@layer reset {
  *, *::before, *::after {
    box-sizing: border-box;
  }
}

@layer base {
  body {
    font-family: system-ui, sans-serif;
    color: var(--color-text);
  }
}

@layer components {
  .btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    border-radius: var(--radius-md);
    font-weight: 500;
    cursor: pointer;
  }
}

Container Queries

親コンテナの幅に応じてスタイルを変える、真のコンポーネント指向レスポンシブです。

.card-wrapper {
  container-type: inline-size;
  container-name: card;
}

@container card (min-width: 400px) {
  .card {
    display: flex;
    gap: 1rem;
  }

  .card__image {
    width: 160px;
    flex-shrink: 0;
  }
}

Tailwind v3.2 以降は @container プラグインが組み込まれています。

<div class="@container">
  <div class="flex flex-col @md:flex-row gap-4">
    <img class="w-full @md:w-40 shrink-0 rounded-lg object-cover" src="..." alt="" />
    <div>...</div>
  </div>
</div>

レスポンシブ対応の定番パターン

モバイルファーストのブレークポイント戦略

Tailwind のプレフィックスはすべて「以上」を意味します。必ずモバイル(プレフィックスなし)から書き始めましょう。

<!-- モバイル: 1列 / md: 2列 / lg: 3列 -->
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
  ...
</div>

<!-- モバイル: 非表示 / md: 表示 -->
<nav class="hidden md:flex items-center gap-4">...</nav>

<!-- モバイル: 表示 / md: 非表示(ハンバーガーメニュー) -->
<button class="md:hidden">...</button>

流体タイポグラフィ(clamp)

画面幅に合わせて文字サイズが滑らかに変化します。

.heading-fluid {
  font-size: clamp(1.5rem, 4vw, 3rem);
  line-height: 1.2;
}

.body-fluid {
  font-size: clamp(1rem, 2vw, 1.125rem);
}
<!-- Tailwind の任意値で同等に -->
<h1 class="text-[clamp(1.5rem,4vw,3rem)] leading-tight">...</h1>

レスポンシブ画像の基本

<picture>
  <source
    srcset="/images/hero-large.webp"
    media="(min-width: 768px)"
    type="image/webp"
  />
  <source
    srcset="/images/hero-small.webp"
    type="image/webp"
  />
  <img
    src="/images/hero-small.jpg"
    alt="ヒーロー画像"
    class="w-full h-auto"
    loading="eager"
    decoding="async"
  />
</picture>

Safe Area 対応(スマートフォンのノッチ・ホームバー)

.header {
  padding-top: env(safe-area-inset-top);
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

.footer {
  padding-bottom: env(safe-area-inset-bottom);
}
<!-- Tailwind の任意値で -->
<footer class="pb-[env(safe-area-inset-bottom)]">...</footer>

まとめ

実務でよく使う CSS / Tailwind のパターンを分野別にまとめました。

カテゴリTipsポイント
レイアウトplace-items-center / auto-fill minmaxグリッドとフレックスを使い分ける
レイアウトスティッキーフッターmin-h-dvh + flex-1 で完結
CSS 変数デザイントークン管理:root でまとめてテーマ切替を楽に
CSS 変数コンポーネントスコープ変数の上書きだけで見た目を変える
アニメーションフェードインanimation: ... both で初期状態も固定
アニメーションスケルトングラデーション + background-position
Tailwindline-clamp / truncate行数制限はユーティリティ一発
TailwindContainer Queries@container でコンポーネント指向に
新しい CSS:has()親要素のスタイリングを JS なしで
新しい CSS@layerカスケードの優先順位を明示管理
レスポンシブclamp() 流体タイポビューポート幅に比例してサイズ変化
レスポンシブSafe Areaenv() でノッチ・ホームバーに対応

どれもコピペして試せるスニペットです。自分のプロジェクトに合わせてカスタマイズしながら活用してください。