mcpField
T
tailwindcss-responsive-darkmode

tailwindcss-responsive-darkmode

github.com/josiahsiegelデザイン・UI59476 回インストール19 週間前に更新
リポジトリ

tailwindcss-responsive-darkmode について

Tailwind CSS 開発者向けに、レスポンシブ設計とダークモードを扱うリファレンススキルです。モバイルファーストのブレークポイント、コンテナクエリ、複数のテーマ切り替え方式をまとめています。

主な機能

  1. 01モバイルファーストのブレークポイントとレイアウト
  2. 02カスタムおよびコンテナクエリのブレークポイント
  3. 03システム、セレクター、属性によるテーマ方式
  4. 04ダークモードの色と変数
  5. 05アクセシビリティとレスポンシブ設計の実践

活用シーン

  1. 01画面幅に応じたページレイアウトの設計
  2. 02再利用コンポーネントのコンテナサイズ対応
  3. 03手動またはシステム連動のダークテーマ実装

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill tailwindcss-responsive-darkmode

インストール後、Claude Code で/tailwindcss-responsive-darkmodeを入力して読み込まれたか確認します。

同梱ファイルreferences/advanced-responsive-patterns.md

詳細

Tailwind CSS のレスポンシブデザインとダークモード(2025/2026)

レスポンシブデザイン

モバイルファーストのアプローチ(2025/2026 年の業界標準)

Tailwind はモバイルファーストのブレークポイントシステムを採用しています。世界のウェブトラフィックの 60%以上がモバイル端末からのものであり、Google のモバイルファーストインデックスもあるため、このアプローチは不可欠です。

重要な原則:プレフィックスのないユーティリティは、すべての画面サイズに適用されます。ブレークポイントのプレフィックスは、指定したサイズ以上で適用されます。


<div class="text-sm md:text-base lg:text-lg">...</div>


<div class="lg:text-lg md:text-base text-sm">...</div>
デフォルトのブレークポイント
プレフィックス最小幅一般的なデバイスCSS メディアクエリ
(なし)0pxすべてのモバイルフォンすべてのサイズ
sm:640px (40rem)大型フォン、小型タブレット@media (min-width: 640px)
md:768px (48rem)タブレット(縦向き)@media (min-width: 768px)
lg:1024px (64rem)タブレット(横向き)、ノート PC@media (min-width: 1024px)
xl:1280px (80rem)デスクトップ@media (min-width: 1280px)
2xl:1536px (96rem)大型デスクトップ@media (min-width: 1536px)
2025/2026 年のデバイス対応範囲

テスト対象となる一般的なデバイスサイズ:

  • 320px:旧型 iPhone、サポート対象の最小サイズ
  • 375px:最新の iPhone 標準モデル(モバイルの約 17%)
  • 390-430px:最新の大型フォン(モバイルの約 35%)
  • 768px:iPad 縦向き
  • 1024px:iPad 横向き、ノート PC
  • 1280px:標準的なノート PC/デスクトップ
  • 1440px:大型デスクトップ
  • 1920px:フル HD ディスプレイ
カスタムブレークポイント
@theme {
  /* Add custom breakpoints for specific content needs */
  --breakpoint-xs: 20rem;   /* 320px - very small devices */
  --breakpoint-3xl: 100rem; /* 1600px */
  --breakpoint-4xl: 120rem; /* 1920px - full HD */

  /* Override existing breakpoints based on YOUR content */
  --breakpoint-sm: 36rem;   /* 576px - when content needs space */
  --breakpoint-lg: 62rem;   /* 992px - common content width */
}

使用方法:

<div class="grid xs:grid-cols-2 3xl:grid-cols-6">
  
</div>
コンテンツ主導のブレークポイント(2025 年のベストプラクティス)

デバイスを対象にするのではなく、コンテンツに応じてブレークポイントを決めましょう。

@theme {
  /* Based on content needs, not device specs */
  --breakpoint-prose: 65ch;  /* Optimal reading width */
  --breakpoint-content: 75rem; /* Main content max */
}

さまざまな幅でデザインをテストし、レイアウトが崩れる箇所にブレークポイントを追加します。

レスポンシブの例
レスポンシブグリッド
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
</div>
レスポンシブタイポグラフィ
<h1 class="text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-bold">
  Responsive Heading
</h1>

<p class="text-sm md:text-base lg:text-lg leading-relaxed">
  Responsive paragraph text
</p>
レスポンシブな間隔
<section class="py-8 md:py-12 lg:py-16 px-4 md:px-8 lg:px-12">
  <div class="max-w-4xl mx-auto">
    Content with responsive padding
  </div>
</section>
レスポンシブナビゲーション
<nav class="flex flex-col md:flex-row items-center justify-between">
  <div class="hidden md:flex gap-4">
    
  </div>
  <button class="md:hidden">
    
  </button>
</nav>
画面サイズに応じた表示/非表示

<div class="hidden md:block">Desktop only</div>


<div class="block md:hidden">Mobile only</div>


<span class="sm:hidden">XS</span>
<span class="hidden sm:inline md:hidden">SM</span>
<span class="hidden md:inline lg:hidden">MD</span>
<span class="hidden lg:inline xl:hidden">LG</span>
<span class="hidden xl:inline 2xl:hidden">XL</span>
<span class="hidden 2xl:inline">2XL</span>
コンテナクエリ(v4)— 2025 年の画期的な機能

コンテナクエリを使うと、ビューポートサイズに依存しない、コンポーネント単位のレスポンシブ対応が可能になります。2025 年に再利用可能なコンポーネントを作るうえで不可欠です。

@plugin "@tailwindcss/container-queries";

<div class="@container">
  <div class="flex flex-col @md:flex-row @lg:gap-8">
    
  </div>
</div>


<div class="@container/card">
  <div class="@lg/card:grid-cols-2 grid grid-cols-1">
    
  </div>
</div>
コンテナクエリのブレークポイント
クラス最小幅用途
@xs20rem (320px)小型ウィジェット
@sm24rem (384px)コンパクトなカード
@md28rem (448px)標準的なカード
@lg32rem (512px)幅広のカード
@xl36rem (576px)全幅のコンポーネント
@2xl42rem (672px)大型コンテナ
@3xl48rem (768px)ページセクション
コンテナクエリとビューポートクエリの使い分け
コンテナクエリビューポートクエリ
再利用可能なコンポーネントページ単位のレイアウト
さまざまなコンテキストで使われるカードナビゲーションバー
サイドバーのウィジェットヒーローセクション
CMS/埋め込みコンテンツ全幅のセクション
最大幅ブレークポイント

特定のサイズを下回る画面を対象にします。


<div class="md:hidden">Small screens only</div>


<div class="[@media(max-width:600px)]:text-sm">
  Custom max-width
</div>

ダークモード

戦略:メディア(デフォルト)

ダークモードは prefers-color-scheme を使用して、ユーザーの OS 設定に従います。

@import "tailwindcss";
/* No additional configuration needed */
<div class="bg-white dark:bg-gray-900">
  <h1 class="text-gray-900 dark:text-white">Title</h1>
  <p class="text-gray-600 dark:text-gray-300">Content</p>
</div>
戦略:セレクター(手動切り替え)

CSS クラスでダークモードを制御します。

@import "tailwindcss";

@custom-variant dark (&:where(.dark, .dark *));

<html class="dark">
  <body>
    <div class="bg-white dark:bg-gray-900">
      Content
    </div>
  </body>
</html>
JavaScript による切り替え
// Simple toggle
function toggleDarkMode() {
  document.documentElement.classList.toggle('dark');
}

// With localStorage persistence
function initDarkMode() {
  const isDark = localStorage.getItem('darkMode') === 'true' ||
    (!localStorage.getItem('darkMode') &&
     window.matchMedia('(prefers-color-scheme: dark)').matches);

  document.documentElement.classList.toggle('dark', isDark);
}

function toggleDarkMode() {
  const isDark = document.documentElement.classList.toggle('dark');
  localStorage.setItem('darkMode', isDark);
}

// Initialize on page load
initDarkMode();
3 段階の切り替え(ライト/ダーク/システム)
const themes = ['light', 'dark', 'system'];

function setTheme(theme) {
  localStorage.setItem('theme', theme);
  applyTheme();
}

function applyTheme() {
  const theme = localStorage.getItem('theme') || 'system';
  const isDark = theme === 'dark' ||
    (theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);

  document.documentElement.classList.toggle('dark', isDark);
}

// Listen for system preference changes
window.matchMedia('(prefers-color-scheme: dark)')
  .addEventListener('change', () => {
    if (localStorage.getItem('theme') === 'system') {
      applyTheme();
    }
  });

applyTheme();
データ属性を使う方法
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
<html data-theme="dark">
  <body>
    <div class="bg-white dark:bg-gray-900">Content</div>
  </body>
</html>
Next.js でのダークモード(next-themes)
npm install next-themes
// app/providers.tsx
'use client';

import { ThemeProvider } from 'next-themes';

export function Providers({ children }) {
  return (
    <ThemeProvider attribute="class" defaultTheme="system">
      {children}
    </ThemeProvider>
  );
}
// app/layout.tsx
import { Providers } from './providers';

export default function RootLayout({ children }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}
// components/ThemeToggle.tsx
'use client';

import { useTheme } from 'next-themes';

export function ThemeToggle() {
  const { theme, setTheme } = useTheme();

  return (
    <button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
      Toggle Theme
    </button>
  );
}
ダークモードのカラーパレット

<p class="text-gray-900 dark:text-gray-100">Primary text</p>
<p class="text-gray-600 dark:text-gray-400">Secondary text</p>
<p class="text-gray-400 dark:text-gray-500">Muted text</p>


<div class="bg-white dark:bg-gray-900">Page background</div>
<div class="bg-gray-50 dark:bg-gray-800">Card background</div>
<div class="bg-gray-100 dark:bg-gray-700">Elevated background</div>


<div class="border border-gray-200 dark:border-gray-700">Bordered element</div>


<button class="bg-blue-500 hover:bg-blue-600 dark:bg-blue-600 dark:hover:bg-blue-700">
  Button
</button>
CSS 変数を使ったダークモード
@theme {
  /* Light mode colors (default) */
  --color-bg-primary: oklch(1 0 0);
  --color-bg-secondary: oklch(0.98 0 0);
  --color-text-primary: oklch(0.15 0 0);
  --color-text-secondary: oklch(0.4 0 0);
}

/* Dark mode overrides */
@media (prefers-color-scheme: dark) {
  :root {
    --color-bg-primary: oklch(0.15 0 0);
    --color-bg-secondary: oklch(0.2 0 0);
    --color-text-primary: oklch(0.95 0 0);
    --color-text-secondary: oklch(0.7 0 0);
  }
}
<div class="bg-[var(--color-bg-primary)] text-[var(--color-text-primary)]">
  Semantic colors
</div>
Typography プラグインのダークモード
<article class="prose dark:prose-invert">
  
</article>

レスポンシブデザインとダークモードの組み合わせ


<div class="
  grid grid-cols-1 md:grid-cols-2
  bg-white dark:bg-gray-900
  p-4 md:p-8
  text-gray-900 dark:text-white
">
  <div class="hidden dark:md:block">
    Only visible on md+ screens in dark mode
  </div>
</div>

ベストプラクティス(2025/2026)

1. モバイルから始めて、その後拡張する

<div class="text-sm md:text-base lg:text-lg">


<div class="lg:text-lg md:text-base text-sm">
2. タッチ操作に適したインタラクティブ要素

WCAG 2.2 では最小 24x24px が求められますが、44x44px が推奨されています。


<button class="min-h-11 min-w-11 px-4 py-2.5">
  Click me
</button>


<a href="#" class="block py-3 px-4 min-h-11">
  Navigation Item
</a>


<div class="flex gap-3">
  <button class="min-h-11 px-4 py-2">Button 1</button>
  <button class="min-h-11 px-4 py-2">Button 2</button>
</div>
3. 流動的なタイポグラフィ(ブレークポイントによる急激な変化を解消)
@theme {
  --text-fluid-base: clamp(1rem, 0.9rem + 0.5vw, 1.25rem);
  --text-fluid-lg: clamp(1.25rem, 1rem + 1.25vw, 2rem);
  --text-fluid-xl: clamp(1.5rem, 1rem + 2.5vw, 3rem);
}
<h1 class="text-fluid-xl font-bold">Smoothly Scaling Heading</h1>
<p class="text-fluid-base leading-relaxed">Smoothly scaling body text.</p>
2. 意味に基づいたダークモードの色を使う
@theme {
  /* Instead of raw colors, use semantic names */
  --color-surface: oklch(1 0 0);
  --color-surface-dark: oklch(0.15 0 0);
  --color-on-surface: oklch(0.1 0 0);
  --color-on-surface-dark: oklch(0.95 0 0);
}
3. すべてのブレークポイントをテストする

開発中は debug-screens プラグインを使用します。

npm install -D @tailwindcss/debug-screens
@plugin "@tailwindcss/debug-screens";
4. コンポーネントで繰り返しを減らす
/* components.css */
@layer components {
  .card {
    @apply bg-white dark:bg-gray-800 rounded-lg p-6 shadow-sm;
  }

  .section {
    @apply py-12 md:py-16 lg:py-24;
  }
}
5. 色のコントラストを考慮する

ライトモードとダークモードの両方で十分なコントラストを確保します(WCAG 2.2)。

  • 通常のテキスト:コントラスト比を最低 4.5:1 にする
  • 大きなテキスト(18pt 以上):コントラスト比を最低 3:1 にする
  • インタラクティブ要素:隣接する色に対して 3:1 にする

<button class="
  bg-blue-600 text-white
  dark:bg-blue-500 dark:text-white
  hover:bg-blue-700 dark:hover:bg-blue-400
  /* Focus ring for accessibility */
  focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2
">
  Action
</button>
6. 動きを減らす設定への対応

動きを減らす設定を好むユーザーに配慮します。

<div class="
  transition-transform duration-300
  hover:scale-105
  motion-reduce:transition-none
  motion-reduce:hover:scale-100
">
  Respects motion preferences
</div>
7. パフォーマンスに配慮したレスポンシブ画像

<img
  src="image.jpg"
  alt="Description"
  loading="lazy"
  class="w-full h-auto"
/>


<img
  src="medium.jpg"
  srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1200w"
  sizes="(min-width: 1024px) 50vw, 100vw"
  alt="Responsive image"
  loading="lazy"
  class="w-full h-auto"
/>
8. セーフエリアへの対応(ノッチのあるデバイス)
@utility safe-area-pb {
  padding-bottom: env(safe-area-inset-bottom);
}

<nav class="fixed bottom-0 inset-x-0 safe-area-pb bg-white border-t">
  Navigation
</nav>

コメント