Harunosuke Webブログ カスタマイズガイド
デザインシステムの活用から新カテゴリの追加まで、ブログサイトをカスタマイズする方法を網羅的に解説します。
このガイドでは、Harunosuke Webブログサイトをカスタマイズする方法を網羅的に解説します。デザインシステムの活用から新カテゴリの追加まで、実用的な情報を提供します。
目次
デザインシステム概要
本サイトは統一されたデザインシステムを採用しており、CSS変数によって一元管理されています。app/globals.cssがシステムの中核を担います。
設計原則
- レスポンシブファースト: モバイルから設計
- アクセシビリティ重視: 44px最小タッチターゲット
- スケーラブル: CSS変数による統一管理
- パフォーマンス: CSS Modulesとグローバル変数の使い分け
CSS変数一覧
カラーシステム
/* ライトモード(デフォルト) */
--background: #ffffff;
--foreground: #4b5563;
--muted-foreground: #6b7280;
--muted-background: #f9fafb;
--border: #e5e7eb;
/* ダークモード(自動切り替え) */
@media (prefers-color-scheme: dark) {
--background: #0a0a0a;
--foreground: #d1d5db;
--muted-foreground: #9ca3af;
--muted-background: #1f2937;
--border: #374151;
}タイポグラフィ
/* レスポンシブタイポグラフィ */
--fs-xs: clamp(12px, 11px + 0.3vw, 14px); /* Small text */
--fs-sm: clamp(14px, 13px + 0.3vw, 16px); /* Button text */
--fs-base: clamp(16px, 15px + 0.5vw, 20px); /* Body text */
--fs-lg: clamp(18px, 16px + 0.8vw, 24px); /* H3 */
--fs-xl: clamp(22px, 18px + 1.2vw, 34px); /* H2 */
--fs-2xl: clamp(24px, 20px + 1.5vw, 36px); /* H1 */
/* 行間 */
--lh-tight: 1.25; /* 見出し用 */
--lh-normal: 1.7; /* 本文用 */
--lh-relaxed: 1.8; /* 長文用 */スペーシング
/* 基本スペーシング(rem 基準) */
--space-0-5: 0.125rem;
--space-1: 0.25rem;
--space-1-5: 0.375rem;
--space-2: 0.5rem;
--space-3: 0.75rem;
--space-4: 1rem;
--space-5: 1.25rem;
--space-6: 1.5rem;
--space-7: 1.75rem;
--space-8: 2rem;
/* 流動スペーシング */
--space-xs: clamp(4px, 3px + 0.2vw, 6px);
--space-sm: clamp(8px, 6px + 0.3vw, 12px);
--space-md: clamp(12px, 10px + 0.5vw, 16px);
--space-lg: clamp(16px, 12px + 0.8vw, 24px);
--space-xl: clamp(24px, 16px + 1.2vw, 36px);
--space-2xl: clamp(32px, 20px + 1.8vw, 48px);
/* 縦方向の余白も --space-* を流用 */
/* 例: section 間は var(--space-2xl) など */レイアウト
/* 読みやすさを考慮した幅制限 */
--max-measure: 70ch; /* 最適な読書幅 */
--max-measure-narrow: 45ch; /* 狭いコンテンツ用 */
/* 境界線 */
--border-radius-sm: 4px;
--border-radius: 8px;
--border-radius-lg: 12px;
/* 影 */
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);カラーシステム
基本的な使い方
/* 推奨: CSS変数を使用 */
.my-component {
background-color: var(--background);
color: var(--foreground);
border: 1px solid var(--border);
}
/* 特別な場合: 直接指定 */
.special-component {
background-color: #1e293b;
}
@media (prefers-color-scheme: dark) {
.special-component {
background-color: #0f172a;
}
}ダークモード対応の3つの方法
1. CSS変数使用(推奨)
.component {
color: var(--foreground);
background: var(--background);
}2. メディアクエリ使用
.component {
color: #374151;
}
@media (prefers-color-scheme: dark) {
.component {
color: #d1d5db;
}
}3. クラスベース切り替え
.component {
color: #374151;
}
.dark .component {
color: #d1d5db;
}レスポンシブデザイン
ブレークポイント
/* モバイルファースト設計 */
/* デフォルト: ~639px (mobile) */
@media (min-width: 640px) { /* tablet */ }
@media (min-width: 768px) { /* desktop */ }
@media (min-width: 1024px) { /* large desktop */ }
@media (min-width: 1280px) { /* extra large */ }レスポンシブユーティリティクラス
/* 統一されたコンテンツ幅制限 */
.content-width-sync {
max-width: 1024px;
margin: 0 auto;
padding-left: 1rem;
padding-right: 1rem;
}
@media (min-width: 640px) {
.content-width-sync {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
}
@media (min-width: 1024px) {
.content-width-sync {
padding-left: 2rem;
padding-right: 2rem;
}
}
/* サイト共通コンテナ */
.site-container {
max-width: 1024px;
margin: 0 auto;
padding-left: var(--space-6);
padding-right: var(--space-6);
}カテゴリシステム
型安全なカテゴリ管理
本サイトではlib/types.tsでカテゴリを厳密に型定義しています:
// lib/types.ts
export type ValidCategory =
| 'Programming'
| 'Web Development'
| 'Frontend Development'
| 'Mathematics'
| 'Machine Learning'
| 'Apple'
| 'Design'
| 'DevOps'
| 'Database'
| 'Security'
| 'Mobile Development'
| 'Backend Development'
| 'Technology';
export interface Post {
slug: string;
title: string;
date: string;
excerpt: string;
content: string;
author: string;
category: ValidCategory; // 厳密な型チェック
tags?: string[];
image?: string;
readTime?: number;
layout?: ArticleLayout;
}新カテゴリ追加手順
新しいカテゴリを追加する際は、以下の手順を厳守してください:
1. 型定義の更新
lib/types.tsのValidCategoryに新カテゴリを追加:
export type ValidCategory =
| 'Programming'
| 'Web Development'
// ... 既存カテゴリ
| 'New Category'; // ← 新カテゴリを追加2. スラッグ変換の確認
lib/slugs.tsのスラッグ変換ロジックが適切に動作することを確認:
// URLスラッグ変換(SEO対応)
export function getCategorySlug(categoryName: string): string {
return categoryName.toLowerCase()
.replace(/\s+/g, '-') // スペースをハイフンに
.replace(/\./g, '-'); // ドットをハイフンに
}
// 例: 'New Category' → 'new-category'3. TypeScript型チェック
新カテゴリ追加後、以下を実行して型エラーがないことを確認:
npm run build
npm run type-check # TypeScriptの型チェック4. テスト確認
- ブログ記事一覧でカテゴリが正しく表示される
- カテゴリページ(
/blog/category/[slug])が正常に動作する - フッターのカテゴリリンクが正しく生成される
カテゴリ使用例
---
title: "新しい記事"
date: "2025-01-15"
category: "New Category"
tags: ["example", "tutorial"]
---
記事内容...カスタマイズ実例
1. カスタムカラーテーマの作成
/* globals.css に追加 */
.theme-custom {
--background: #f8fafc;
--foreground: #1e293b;
--muted-foreground: #64748b;
--muted-background: #f1f5f9;
--border: #cbd5e1;
}
.dark.theme-custom {
--background: #0f172a;
--foreground: #f1f5f9;
--muted-foreground: #94a3b8;
--muted-background: #1e293b;
--border: #475569;
}2. カスタムコンポーネントスタイル
/* components/CustomCard.module.css */
.card {
background: var(--muted-background);
border: 1px solid var(--border);
border-radius: var(--border-radius);
padding: var(--space-lg);
margin-bottom: var(--space-md);
box-shadow: var(--shadow-sm);
}
.cardTitle {
font-size: var(--fs-lg);
line-height: var(--lh-tight);
color: var(--foreground);
margin-bottom: var(--space-sm);
}
.cardContent {
font-size: var(--fs-base);
line-height: var(--lh-normal);
color: var(--muted-foreground);
}
/* レスポンシブ調整 */
@media (min-width: 768px) {
.card {
padding: var(--space-xl);
}
}3. カスタムレイアウトの作成
// components/CustomLayout.tsx
interface CustomLayoutProps {
children: React.ReactNode;
className?: string;
}
export default function CustomLayout({ children, className = '' }: CustomLayoutProps) {
return (
<div className={`content-width-sync ${className}`}>
<div className="custom-grid">
{children}
</div>
</div>
);
}/* CustomLayout.module.css */
.customGrid {
display: grid;
grid-template-columns: 1fr;
gap: var(--space-lg);
}
@media (min-width: 768px) {
.customGrid {
grid-template-columns: 2fr 1fr;
gap: var(--space-xl);
}
}ベストプラクティス
1. CSS変数の活用
❌ 非推奨: ハードコーディング
.component {
color: #6b7280;
font-size: 14px;
margin: 16px;
}✅ 推奨: CSS変数使用
.component {
color: var(--muted-foreground);
font-size: var(--fs-sm);
margin: var(--space-lg);
}2. レスポンシブデザイン
❌ 非推奨: 固定値
.component {
padding: 20px;
font-size: 18px;
}✅ 推奨: レスポンシブ変数
.component {
padding: var(--space-6);
font-size: var(--fs-lg);
}3. アクセシビリティ
✅ 必須: 最小タッチターゲット
.button {
min-height: 44px;
min-width: 44px;
padding: var(--space-sm) var(--space-lg);
}4. 型安全性
✅ 必須: カテゴリの型チェック
// 型安全なカテゴリ使用
const category: ValidCategory = 'Programming'; // ✅ OK
const category: ValidCategory = 'Invalid'; // ❌ TypeScriptエラートラブルシューティング
よくある問題と解決法
1. カテゴリが表示されない
原因: ValidCategory型に含まれていない
解決: lib/types.tsにカテゴリを追加
2. レスポンシブが効かない
原因: CSS変数ではなく固定値を使用
解決: var(--変数名)を使用
3. ダークモードで色が変わらない
原因: CSS変数を使用していない
解決: var(--background)等に変更
4. スタイルが適用されない
原因: CSS Modulesのクラス名が正しくない
解決: styles.classNameの形式で使用
まとめ
本ガイドを活用して、統一性のあるデザインシステムの下でカスタマイズを行ってください。新機能追加時は必ず型チェックを実行し、レスポンシブデザインとアクセシビリティを考慮することを忘れずに。
質問や追加要望があれば、お気軽にお声かけください。