Harunosuke Webブログ カスタマイズガイド

デザインシステムの活用から新カテゴリの追加まで、ブログサイトをカスタマイズする方法を網羅的に解説します。

このガイドでは、Harunosuke Webブログサイトをカスタマイズする方法を網羅的に解説します。デザインシステムの活用から新カテゴリの追加まで、実用的な情報を提供します。

目次

  1. デザインシステム概要
  2. CSS変数一覧
  3. カラーシステム
  4. レスポンシブデザイン
  5. カテゴリシステム
  6. カスタマイズ実例

デザインシステム概要

本サイトは統一されたデザインシステムを採用しており、CSS変数によって一元管理されています。app/globals.cssがシステムの中核を担います。

設計原則

  • レスポンシブファースト: モバイルから設計
  • アクセシビリティ重視: 44px最小タッチターゲット
  • スケーラブル: CSS変数による統一管理
  • パフォーマンス: CSS Modulesとグローバル変数の使い分け

CSS変数一覧

カラーシステム

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;
}

タイポグラフィ

CSS
/* レスポンシブタイポグラフィ */
--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;   /* 長文用 */

スペーシング

CSS
/* 基本スペーシング(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) など */

レイアウト

CSS
/* 読みやすさを考慮した幅制限 */
--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
/* 推奨: 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変数使用(推奨)

CSS
.component {
color: var(--foreground);
background: var(--background);
}

2. メディアクエリ使用

CSS
.component {
color: #374151;
}

@media (prefers-color-scheme: dark) {
.component {
color: #d1d5db;
}
}

3. クラスベース切り替え

CSS
.component {
color: #374151;
}

.dark .component {
color: #d1d5db;
}

レスポンシブデザイン

ブレークポイント

CSS
/* モバイルファースト設計 */
/* デフォルト: ~639px (mobile) */

@media (min-width: 640px) { /* tablet */ }
@media (min-width: 768px) { /* desktop */ }
@media (min-width: 1024px) { /* large desktop */ }
@media (min-width: 1280px) { /* extra large */ }

レスポンシブユーティリティクラス

CSS
/* 統一されたコンテンツ幅制限 */
.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でカテゴリを厳密に型定義しています:

TypeScript
// 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.tsValidCategoryに新カテゴリを追加:

TypeScript
export type ValidCategory =
| 'Programming'
| 'Web Development'
// ... 既存カテゴリ
| 'New Category'; // ← 新カテゴリを追加

2. スラッグ変換の確認

lib/slugs.tsのスラッグ変換ロジックが適切に動作することを確認:

TypeScript
// URLスラッグ変換(SEO対応)
export function getCategorySlug(categoryName: string): string {
return categoryName.toLowerCase()
.replace(/\s+/g, '-')  // スペースをハイフンに
.replace(/\./g, '-');  // ドットをハイフンに
}

// 例: 'New Category' → 'new-category'

3. TypeScript型チェック

新カテゴリ追加後、以下を実行して型エラーがないことを確認:

Shell
npm run build
npm run type-check  # TypeScriptの型チェック

4. テスト確認

  • ブログ記事一覧でカテゴリが正しく表示される
  • カテゴリページ(/blog/category/[slug])が正常に動作する
  • フッターのカテゴリリンクが正しく生成される

カテゴリ使用例

Markdown
---
title: "新しい記事"
date: "2025-01-15"
category: "New Category"
tags: ["example", "tutorial"]
---

記事内容...

カスタマイズ実例

1. カスタムカラーテーマの作成

CSS
/* 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. カスタムコンポーネントスタイル

CSS
/* 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. カスタムレイアウトの作成

TypeScript
// 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>
);
}
CSS
/* 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変数の活用

非推奨: ハードコーディング

CSS
.component {
color: #6b7280;
font-size: 14px;
margin: 16px;
}

推奨: CSS変数使用

CSS
.component {
color: var(--muted-foreground);
font-size: var(--fs-sm);
margin: var(--space-lg);
}

2. レスポンシブデザイン

非推奨: 固定値

CSS
.component {
padding: 20px;
font-size: 18px;
}

推奨: レスポンシブ変数

CSS
.component {
padding: var(--space-6);
font-size: var(--fs-lg);
}

3. アクセシビリティ

必須: 最小タッチターゲット

CSS
.button {
min-height: 44px;
min-width: 44px;
padding: var(--space-sm) var(--space-lg);
}

4. 型安全性

必須: カテゴリの型チェック

TypeScript
// 型安全なカテゴリ使用
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の形式で使用

まとめ

本ガイドを活用して、統一性のあるデザインシステムの下でカスタマイズを行ってください。新機能追加時は必ず型チェックを実行し、レスポンシブデザインとアクセシビリティを考慮することを忘れずに。

質問や追加要望があれば、お気軽にお声かけください。