Spaces:
Sleeping
Sleeping
| # 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拡張** | |
| - テーマパラメータ追加 | |
| - 後方互換性確保 | |
| - エラーハンドリング | |
| この設計により、安全かつ効率的なテーマカスタマイズ機能の実装が可能になります。 |