FE_Test / docs /css-variable-design.md
GitHub Actions
Deploy from GitHub Actions [test] - 2025-10-31 10:18:25
5f2aab6
# CSS変数設計仕様書
## 概要
`ThemeExtractionResult`型の15色カラーパレットとCSS変数のマッピング設計、および既存CSS構造との統合方法を定義します。
## 1. ThemeExtractionResult型との対応関係
### 1.1 現在の15色カラーパレット構造
```typescript
interface ColorTheme {
// メインカラー
primary_color: string; // #RRGGBB
secondary_color: string; // #RRGGBB
accent_color: string; // #RRGGBB
// セマンティックカラー
success_semantic_color: string; // #RRGGBB
warning_semantic_color: string; // #RRGGBB
error_semantic_color: string; // #RRGGBB
info_semantic_color: string; // #RRGGBB
// 背景色
primary_background_color: string; // #RRGGBB
secondary_background_color: string; // #RRGGBB
tertiary_background_color: string; // #RRGGBB
overlay_background_color: string; // #RRGGBB
// テキスト色
primary_text_color: string; // #RRGGBB
secondary_text_color: string; // #RRGGBB
disabled_text_color: string; // #RRGGBB
inverse_text_color: string; // #RRGGBB
}
```
## 2. CSS変数マッピング設計
### 2.1 基本CSS変数定義
```css
:root {
/* === メインカラーパレット === */
--theme-primary-color: var(--extracted-primary-color, #5a6c7d);
--theme-secondary-color: var(--extracted-secondary-color, #34495e);
--theme-accent-color: var(--extracted-accent-color, #f59e0b);
/* === セマンティックカラー === */
--theme-success-color: var(--extracted-success-semantic-color, #28a745);
--theme-warning-color: var(--extracted-warning-semantic-color, #f59e0b);
--theme-error-color: var(--extracted-error-semantic-color, #dc3545);
--theme-info-color: var(--extracted-info-semantic-color, #17a2b8);
/* === 背景色 === */
--theme-primary-bg: var(--extracted-primary-background-color, white);
--theme-secondary-bg: var(--extracted-secondary-background-color, #f8f9fa);
--theme-tertiary-bg: var(--extracted-tertiary-background-color, #222222);
--theme-overlay-bg: var(--extracted-overlay-background-color, rgba(0,0,0,0.5));
/* === テキスト色 === */
--theme-primary-text: var(--extracted-primary-text-color, #222222);
--theme-secondary-text: var(--extracted-secondary-text-color, #555555);
--theme-disabled-text: var(--extracted-disabled-text-color, #999999);
--theme-inverse-text: var(--extracted-inverse-text-color, white);
/* === フォントファミリー === */
--theme-primary-font: var(--extracted-primary-font,
"YuGothic", "Yu Gothic Medium", "Yu Gothic", "Hiragino Sans",
"Hiragino Kaku Gothic ProN", -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, "Meiryo", sans-serif);
}
```
### 2.2 既存色との後方互換マッピング
```css
:root {
/* === 既存色の変数化(後方互換性確保) === */
/* 最頻出色 → テーマ色へのマッピング */
--legacy-primary-text: var(--theme-primary-text); /* #222222 → primary_text_color */
--legacy-accent: var(--theme-primary-color); /* #5a6c7d → primary_color */
--legacy-border: var(--theme-secondary-text); /* #e9ecef → secondary_text_color */
--legacy-light-bg: var(--theme-secondary-bg); /* #f8f9fa → secondary_background_color */
--legacy-secondary-text: var(--theme-secondary-text); /* #34495e → secondary_text_color */
/* セクション背景色のマッピング */
--section-white-bg: var(--theme-primary-bg); /* white → primary_background_color */
--section-gray-bg: var(--theme-secondary-bg); /* #f8f9fa → secondary_background_color */
--section-dark-bg: var(--theme-tertiary-bg); /* #222222 → tertiary_background_color */
}
```
## 3. 段階的CSS変数導入計画
### 3.1 Phase 1: 低リスク基本色(即座に適用可能)
#### 対象セレクター(特異性: 0,0,1,0 〜 0,0,1,1)
```css
/* 基本要素の色変更 */
body {
color: var(--legacy-primary-text, #222222);
background-color: var(--theme-primary-bg, #f5f5f5);
font-family: var(--theme-primary-font);
}
.container {
color: var(--legacy-primary-text, #333);
font-family: var(--theme-primary-font);
}
/* 単純クラスセレクター */
.global-strategy-title,
.special-offer-title,
.pricing-title,
.success-stories-title,
.use-cases-title,
.awards-main-title,
.staff-title,
.store-title {
color: var(--legacy-primary-text, #222222);
}
```
### 3.2 Phase 2: 中リスク複合セレクター(テスト後適用)
#### 対象セレクター(特異性: 0,0,2,0 〜 0,0,2,1)
```css
/* カード要素の背景とボーダー */
.strategy-card,
.innovation__item,
.pricing-card,
.award-item,
.review-card,
.use-case-item,
.faq-item,
.news-item {
background: var(--theme-primary-bg, white);
border: 1px solid var(--legacy-border, #e9ecef);
}
/* アクセント色要素 */
.simulation-button,
.special-offer-button,
.news-more-button,
.aiPower__benefitIcon,
.comparison-icon,
.staff-avatar,
.review-avatar {
background: var(--legacy-accent, #5a6c7d);
}
```
### 3.3 Phase 3: 高リスク nth-of-type セレクター(最終段階)
#### 対象セレクター(特異性: 0,0,2,0 最高優先度)
```css
/* セクション背景色の変数化 - 最も慎重に */
.section-base:nth-of-type(3n+1) {
background: var(--section-white-bg, white) !important;
color: var(--theme-primary-text, #222222) !important;
}
.section-base:nth-of-type(3n+2) {
background: var(--section-gray-bg, #f8f9fa) !important;
color: var(--theme-primary-text, #222222) !important;
}
.section-base:nth-of-type(3n) {
background: var(--section-dark-bg, #222222) !important;
color: var(--theme-inverse-text, white) !important;
}
```
## 4. CSS生成戦略
### 4.1 ベースCSS + テーマ変数の分離アーキテクチャ
```typescript
interface CSSGenerationStrategy {
baseCSS: string; // 構造・レイアウト(1200行程度、静的)
themeCSS: string; // テーマ変数定義(100行程度、動的)
totalCSS: string; // baseCSS + themeCSS
}
```
### 4.2 動的CSS生成の実装
```typescript
class ThemeCustomizer {
generateThemeCSS(theme: ThemeExtractionResult): string {
return `
:root {
/* テーマ抽出結果からの動的変数生成 */
--extracted-primary-color: ${theme.colors.primary_color};
--extracted-secondary-color: ${theme.colors.secondary_color};
--extracted-accent-color: ${theme.colors.accent_color};
--extracted-success-semantic-color: ${theme.colors.success_semantic_color};
--extracted-warning-semantic-color: ${theme.colors.warning_semantic_color};
--extracted-error-semantic-color: ${theme.colors.error_semantic_color};
--extracted-info-semantic-color: ${theme.colors.info_semantic_color};
--extracted-primary-background-color: ${theme.colors.primary_background_color};
--extracted-secondary-background-color: ${theme.colors.secondary_background_color};
--extracted-tertiary-background-color: ${theme.colors.tertiary_background_color};
--extracted-overlay-background-color: ${theme.colors.overlay_background_color};
--extracted-primary-text-color: ${theme.colors.primary_text_color};
--extracted-secondary-text-color: ${theme.colors.secondary_text_color};
--extracted-disabled-text-color: ${theme.colors.disabled_text_color};
--extracted-inverse-text-color: ${theme.colors.inverse_text_color};
/* フォントファミリーの動的設定(将来拡張) */
--extracted-primary-font: var(--theme-primary-font);
}`;
}
}
```
## 5. 競合回避戦略
### 5.1 特異性優先順位の設計
```css
/* レベル1: 基本変数定義(最低特異性) */
:root { /* 特異性: 0,0,1,0 */ }
/* レベル2: フォールバック付き基本要素(低特異性) */
body, .container { /* 特異性: 0,0,1,1 */ }
/* レベル3: 単純クラス要素(中特異性) */
.strategy-card { /* 特異性: 0,0,1,0 */ }
/* レベル4: 複合クラス要素(高特異性) */
.section-base .strategy-card { /* 特異性: 0,0,2,0 */ }
/* レベル5: nth-of-type + !important(最高特異性) */
.section-base:nth-of-type(3n+1) { /* 特異性: 0,0,2,0 + !important */ }
```
### 5.2 段階的!important戦略
```css
/* Phase 1: !important 不使用 */
.basic-element {
color: var(--theme-primary-text, #222222); /* フォールバック値で安全性確保 */
}
/* Phase 2: 選択的!important使用 */
.complex-element {
color: var(--theme-primary-text, #222222) !important; /* 既存ルールをオーバーライド */
}
/* Phase 3: 必須!important使用 */
.section-base:nth-of-type(3n+1) {
background: var(--section-white-bg, white) !important; /* 最高特異性に対抗 */
}
```
## 6. パフォーマンス最適化設計
### 6.1 キャッシュ戦略
```typescript
interface ThemeCacheStrategy {
// キャッシュキーの生成
generateCacheKey(theme: ThemeExtractionResult): string;
// CSS生成結果のキャッシュ
cacheThemeCSS(key: string, css: string): void;
// キャッシュからの取得
getCachedThemeCSS(key: string): string | null;
}
```
### 6.2 差分生成最適化
```typescript
interface DifferentialCSS {
baseCSS: string; // 一度生成、永続キャッシュ
lastGeneratedTheme: string; // 前回のテーマCSS
generateCSS(theme: ThemeExtractionResult): {
fullCSS: string; // ベース + テーマの完全版
themeOnly: string; // テーマ変数のみ(差分更新用)
};
}
```
## 7. ブラウザ互換性対応
### 7.1 CSS変数未対応ブラウザへのフォールバック
```css
/* 従来ブラウザ対応 */
.element {
color: #222222; /* フォールバック値 */
color: var(--theme-primary-text, #222222); /* CSS変数対応ブラウザ */
}
```
### 7.2 段階的拡張(Progressive Enhancement)
```css
/* 基本サポート: すべてのブラウザで動作 */
.base-support {
color: #222222;
background: white;
}
/* 拡張サポート: CSS変数対応ブラウザのみ */
@supports (color: var(--test)) {
.base-support {
color: var(--theme-primary-text);
background: var(--theme-primary-bg);
}
}
```
## 8. テスト戦略
### 8.1 段階別テスト計画
```typescript
interface TestStrategy {
phase1Tests: {
basicColorApplication: boolean;
fontFamilyApplication: boolean;
fallbackValueVerification: boolean;
};
phase2Tests: {
cardElementStyling: boolean;
buttonColorConsistency: boolean;
borderColorUniformity: boolean;
};
phase3Tests: {
sectionBackgroundColors: boolean;
nthOfTypePatternIntegrity: boolean;
textColorContrast: boolean;
};
}
```
### 8.2 ビジュアル回帰テスト
```typescript
interface VisualRegressionTest {
// テーマ適用前後の比較
compareBeforeAfter(originalHTML: string, themedHTML: string): boolean;
// 異なるテーマ間の一貫性確認
compareThemeConsistency(themes: ThemeExtractionResult[]): boolean;
// ブラウザ間の表示確認
crossBrowserCompatibility(): boolean;
}
```
## 9. エラーハンドリング設計
### 9.1 CSS変数適用失敗時の対応
```css
/* 必須フォールバック値の設定 */
:root {
--theme-primary-text: var(--extracted-primary-text-color, #222222);
--theme-primary-bg: var(--extracted-primary-background-color, white);
/* すべての変数に安全なデフォルト値を設定 */
}
```
### 9.2 色指定の妥当性検証
```typescript
interface ColorValidation {
isValidHexColor(color: string): boolean;
ensureContrastRatio(foreground: string, background: string): boolean;
sanitizeColorValue(color: string): string;
}
```
## 10. 実装ロードマップ
### 10.1 Phase 1.1 完了項目 ✅
- CSS構造分析完了
- 変数マッピング設計完了
- 後方互換性戦略策定完了
### 10.2 Phase 1.2 次期実装項目
1. **ThemeCustomizerクラス実装**
- CSS変数生成ロジック
- キャッシュ機能
- バリデーション機能
2. **ベースCSS分離実装**
- 構造CSS抽出
- 変数化CSS作成
- 統合テスト
3. **ContentsHtmlService拡張**
- テーマパラメータ追加
- 後方互換性確保
- エラーハンドリング
この設計により、安全かつ効率的なテーマカスタマイズ機能の実装が可能になります。