プロダクトナビゲーションにホバー連動の背景色トランジションを追加

shoelace-style/webawesome

プロダクトナビゲーションバーとドロワーヘッダーに、ホバー操作と連動した背景色のスムーズなトランジションが追加されました。ユーザーが各プロダクトリンクにホバーすると、そのブランドカラーを薄く溶け込ませた背景色にナビゲーション全体が切り替わります。

背景

今回の変更は、11ty.dev のプロダクトナビゲーションの実装を参考に導入されました。PR本文では「Copying the legend, @zachleat and his efforts」と言及されており、同様のインタラクションパターンをWebAwesomeのドキュメントサイトに取り込んだものです。

WebAwesomeのドキュメントサイトは Web Awesome・Font Awesome・Build Awesome という複数プロダクトを横断するナビゲーションを持ちます。各プロダクトにはそれぞれブランドカラー(オレンジ・ブルー・グリーン)が定義されていましたが、これまでナビゲーション背景は静的な --wa-color-surface-lowered で固定されており、ホバー操作に対する視覚的フィードバックがありませんでした。

技術的な変更

変更の中心は utils.css に集約されており、CSS カスタムプロパティと :has() セレクタを組み合わせた状態管理のアプローチが採用されています。

まず、ライトモード・ダークモードそれぞれに対応した「静かな塗りつぶし」カラートークンが追加されました。color-mix(in oklab, ...) を使ってブランドカラーを白または黒と混ぜることで、主張しすぎない淡い背景色を生成しています。

/* ライトモード(white 85% で希釈) */
--nav-products-fill-quiet-web: color-mix(in oklab, var(--brand-web-awesome-orange), white 85%);
--nav-products-fill-quiet-font: color-mix(in oklab, var(--brand-font-awesome-blue), white 85%);
--nav-products-fill-quiet-build: color-mix(in oklab, var(--brand-build-awesome-green), white 85%);

/* ダークモード(black 65% で希釈) */
.wa-dark {
  --nav-products-fill-quiet-web: color-mix(in oklab, var(--brand-web-awesome-orange), black 65%);
  --nav-products-fill-quiet-font: color-mix(in oklab, var(--brand-font-awesome-blue), black 65%);
  --nav-products-fill-quiet-build: color-mix(in oklab, var(--brand-build-awesome-green), black 65%);
}

次に、ホバー状態の検知とCSS変数の切り替えに :has() セレクタが使われています。wa-page をルートとして、内部のプロダクトリンク要素のホバー状態を上位セレクタから参照することで、ナビゲーション全体の背景色を制御します。

wa-page:has(.wrapper-nav-products, .nav-products-drawer) {
  &:has(.product-web-awesome:hover) {
    --nav-products-bg: var(--nav-products-fill-quiet-web);
  }
  &:has(.product-font-awesome:hover) {
    --nav-products-bg: var(--nav-products-fill-quiet-font);
  }
  &:has(.product-build-awesome:hover) {
    --nav-products-bg: var(--nav-products-fill-quiet-build);
  }
}

背景色の適用側では、.wrapper-nav-productswa-page > [slot='banner'] の両方で background-color がCSS変数 --nav-products-bg を参照するよう変更され、ホバーがない状態ではフォールバック値として従来の --wa-color-surface-lowered が使われます。

/* 変更前 */
background-color: var(--wa-color-surface-lowered);

/* 変更後 */
background-color: var(--nav-products-bg, var(--wa-color-surface-lowered));
transition: background-color var(--wa-transition-slow) var(--wa-transition-easing);

この変更により、ホバー時には --nav-products-bg が上書きされて有効になり、非ホバー時はフォールバックが機能するため、既存の表示に影響を与えません。

設計判断

:has() による「上位要素からの状態参照」 という手法が採用された点が、この変更の設計上の核心です。通常のホバースタイルは対象要素自身や子要素に適用されますが、今回はホバーされた子孫要素の状態を祖先要素のカスタムプロパティに伝播させています。これによって、ナビゲーション背景・バナースロットという複数の要素を単一の状態変数 --nav-products-bg で一元制御できています。

color-mix(in oklab, ...) の混合比率がライト(white 85%)とダーク(black 65%)で非対称になっている点も注目されます。ダークモードで混合量を少なく(35%のブランドカラーを残す)することで、暗い背景上でも色の存在感を保つよう調整されています。

まとめ

CSSカスタムプロパティ・:has() セレクタ・color-mix() というモダンCSS機能を組み合わせることで、JavaScriptを一切使わずにホバー連動の背景色トランジションが実現されています。コンポーネントの実装ではなくドキュメントサイトのスタイリングへの変更ですが、状態のスコープ管理とフォールバック設計のパターンとして参考になる実装です。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
ce6126da

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

「総論→各論→結論」の3部構成(リード文、背景、技術詳細、設計判断、まとめ)が明確に守られており、非常に分かりやすい構成です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きコードブロック(`css:filepath`)、PR番号のリンク記法共に正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

CSSの専門用語(:has(), color-mix, カスタムプロパティ)を適切に使用しており、専門知識を持つエンジニアという対象読者に完全に適合しています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクション・各パラグラフが要点から始まる構成になっており、1段落1トピックの原則も守られているため、非常に高い可読性を実現しています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内のすべてのコード引用は、提供されたDiffの内容とファイル名を正確に反映しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

`:has()`、`color-mix`、`oklab`、CSSカスタムプロパティといった技術用語を文脈に沿って正確に使用しています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

コード変更の意図と結果に関する説明は、Diffの内容と完全に整合しており、技術的に正確です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張(11ty.devからのインスピレーションなど)は、PRのDescriptionやDiff内のコードで裏付けられています。ハルシネーションは一切ありません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#2131)やCSSの混合比率(85%, 65%)など、記事内のすべての数値・固有名詞は正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルはPRの主題を的確に要約しており、PR Descriptionの内容とも完全に一致しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

PR情報に含まれない外部知識(バージョン情報、サポート状況など)の追記はなく、提供された情報源に忠実です。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

実装済みの変更を説明する時制が適切に使われており、時間表現の歪曲はありません。