tailwindcss について
ユーティリティクラスで Web インターフェースをスタイリングする開発者向けの Tailwind CSS 基礎知識スキルです。レスポンシブデザイン、設定、コンポーネントパターン、ダークモード、アクセシビリティ、本番環境での考慮点を扱います。
主な機能
- 01一般的なユーティリティクラス
- 02レスポンシブデザインのパターン
- 03テーマとコンテンツの設定
- 04再利用可能なクラス構成
- 05ダークモードとアクセシビリティの指針
活用シーン
- 01Web インターフェースのレスポンシブなスタイリング
- 02プロジェクトの色とフォントの設定
- 03再利用可能なユーティリティクラスの整理
- 04Tailwind CSS の本番利用準備の確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ claude-dev-suite/ claude-dev-suite --skill tailwindcssインストール後、Claude Code で/tailwindcssを入力して読み込まれたか確認します。
同梱ファイルquick-ref/responsive.mdquick-ref/utilities.md
詳細
Tailwind CSS のコア知識
深い知識:技術として
tailwindcssを指定し、mcp__documentation__fetch_docsを使用して包括的なドキュメントを取得してください。
よく使うユーティリティ
<div class="flex items-center justify-between gap-4">
<div class="grid grid-cols-3 gap-4">
<div class="container mx-auto px-4">
<div class="p-4 m-2 space-y-4">
<div class="px-4 py-2 mt-8 mb-4">
<div class="w-full h-screen max-w-md min-h-[200px]">
<p class="text-lg font-semibold text-gray-900">
<p class="text-sm text-gray-500 leading-relaxed">
<div class="bg-blue-500 text-white border-gray-200">
<div class="bg-gradient-to-r from-blue-500 to-purple-500">
レスポンシブデザイン
<div class="text-sm md:text-base lg:text-lg">
<div class="flex-col md:flex-row">
<div class="hidden lg:block">
状態
<button class="bg-blue-500 hover:bg-blue-600 active:bg-blue-700">
<input class="border focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<div class="group">
<span class="group-hover:text-blue-500">Text</span>
</div>
<div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-white">
コンポーネントのパターン
<div class="rounded-lg shadow-md bg-white p-6 hover:shadow-lg transition-shadow">
<button class="px-4 py-2 rounded-md bg-blue-500 text-white font-medium
hover:bg-blue-600 focus:outline-none focus:ring-2
focus:ring-blue-500 focus:ring-offset-2
disabled:opacity-50 disabled:cursor-not-allowed">
<input class="w-full px-3 py-2 border border-gray-300 rounded-md
focus:outline-none focus:ring-2 focus:ring-blue-500
focus:border-transparent">
このスキルを使用しない場合
- CSS-in-JS を優先する場合 - styled-components または Emotion を使用します
- 従来の CSS ワークフローの場合 - SCSS/PostCSS を使用します
- コンポーネントライブラリのプロジェクトの場合 - Material-UI、Ant Design には独自のスタイリングがあります
- メールテンプレートの場合 - インラインスタイルが必要です
設定
// tailwind.config.js
export default {
content: ['./src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {
colors: { brand: '#1a73e8' },
fontFamily: { sans: ['Inter', 'sans-serif'] }
}
},
plugins: [require('@tailwindcss/forms')]
}
アンチパターン
| アンチパターン | 問題点 | 正しい方法 |
|---|---|---|
| 任意の値をあらゆる場所で使用する | 保守が難しい | テーマ設定で定義する |
| 長い className 文字列 | 読みにくい | cn() ユーティリティまたはコンポーネントへの切り出しを使用する |
| content 設定を使用しない | CSS バンドルが大きくなる | 正確なファイルパスを指定する |
| HTML でインラインの @apply を使用する | ユーティリティファーストの利点が失われる | CSS で @apply を使用するか、コンポーネントに切り出す |
| purge の警告を無視する | 本番環境で未使用の CSS が残る | content パスを修正する |
| CSS 変数を使用しない | 動的に変更できない | テーマ変更可能な値には CSS 変数を使用する |
すばやいトラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| スタイルが適用されない | purge によりクラスが削除された | safelist に追加するか、content パスを修正する |
| ダークモードが機能しない | darkMode が設定されていない | 設定で darkMode: 'class' を指定する |
| カスタムカラーが機能しない | theme.extend にない | theme.extend.colors に追加する |
| ビルドサイズが大きすぎる | 対象ファイルが多すぎる | content パターンを具体的に指定する |
| タッチ操作でホバーが機能しない | :hover のみを使用している | アクセシビリティのためにフォーカス状態を追加する |
| クラスが競合する | 複数のユーティリティクラスを使用している | tailwind-merge とともに cn() を使用する |
本番環境への準備
パフォーマンスの最適化
// tailwind.config.js
export default {
content: [
'./src/**/*.{js,ts,jsx,tsx}',
// Be specific to avoid scanning node_modules
],
theme: {
extend: {},
},
// Remove unused utilities in production
safelist: [
// Only if dynamically generated
{ pattern: /bg-(red|green|blue)-(100|500)/ },
],
// Disable unused core plugins
corePlugins: {
preflight: true,
// container: false, // if not using
},
};
// postcss.config.js
export default {
plugins: {
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
// Production only
...(process.env.NODE_ENV === 'production'
? { cssnano: { preset: 'default' } }
: {}),
},
};
デザインシステム
// tailwind.config.js
export default {
theme: {
// Override defaults
colors: {
transparent: 'transparent',
current: 'currentColor',
white: '#ffffff',
black: '#000000',
// Brand colors
primary: {
50: '#eff6ff',
100: '#dbeafe',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
},
// Semantic colors
success: '#22c55e',
warning: '#f59e0b',
error: '#ef4444',
},
// Consistent spacing scale
spacing: {
px: '1px',
0: '0',
1: '0.25rem',
2: '0.5rem',
3: '0.75rem',
4: '1rem',
// ...
},
// Typography scale
fontSize: {
xs: ['0.75rem', { lineHeight: '1rem' }],
sm: ['0.875rem', { lineHeight: '1.25rem' }],
base: ['1rem', { lineHeight: '1.5rem' }],
lg: ['1.125rem', { lineHeight: '1.75rem' }],
xl: ['1.25rem', { lineHeight: '1.75rem' }],
},
},
};
コンポーネントのパターン
// lib/styles.ts - Reusable class compositions
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
// Variant patterns with cva
import { cva, type VariantProps } from 'class-variance-authority';
export const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
default: 'bg-primary-600 text-white hover:bg-primary-700',
outline: 'border border-gray-300 hover:bg-gray-50',
ghost: 'hover:bg-gray-100',
},
size: {
sm: 'h-8 px-3 text-sm',
md: 'h-10 px-4',
lg: 'h-12 px-6 text-lg',
},
},
defaultVariants: {
variant: 'default',
size: 'md',
},
}
);
アクセシビリティ
<button class="focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2">
<a href="#main" class="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:px-4 focus:py-2 focus:bg-white">
Skip to content
</a>
<div class="transition-transform motion-reduce:transition-none motion-reduce:transform-none">
<button class="bg-blue-500 forced-colors:bg-[ButtonFace] forced-colors:border forced-colors:border-[ButtonBorder]">
ダークモード
// tailwind.config.js
export default {
darkMode: 'class', // or 'media'
// ...
};
// Theme toggle component
function ThemeToggle() {
const [theme, setTheme] = useState('light');
useEffect(() => {
document.documentElement.classList.toggle('dark', theme === 'dark');
}, [theme]);
return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Toggle theme
</button>
);
}
テスト
// Visual regression testing
import { test, expect } from '@playwright/test';
test('button variants render correctly', async ({ page }) => {
await page.goto('/storybook/button');
// Screenshot comparison
await expect(page.locator('.button-primary')).toHaveScreenshot('button-primary.png');
await expect(page.locator('.button-outline')).toHaveScreenshot('button-outline.png');
});
// Unit testing class compositions
import { cn, buttonVariants } from '@/lib/styles';
describe('buttonVariants', () => {
it('generates correct classes for default variant', () => {
const classes = buttonVariants({ variant: 'default', size: 'md' });
expect(classes).toContain('bg-primary-600');
expect(classes).toContain('h-10');
});
});
監視する指標
| 指標 | 目標 |
|---|---|
| CSS バンドルサイズ | < 30KB gzip 圧縮後 |
| 未使用の CSS | 0% |
| First Contentful Paint | < 1s |
| Lighthouse のパフォーマンス | > 90 |
チェックリスト
- content パスが正しく設定されている
- 本番環境で cssnano を使用した PostCSS
- デザイントークン(色、間隔、タイポグラフィ)
- クラスのマージに cn() ユーティリティを使用
- コンポーネントのバリアントに CVA を使用
- ダークモードへの対応
- アクセシビリティのために focus-visible を使用
- 動きを減らす設定への対応
- バンドルサイズの監視
- ビジュアルリグレッションテスト
リファレンスドキュメント
コメント
Markdown 対応