【テクニカル・上級編】 訪問済みリンク擬似クラス :visited – CSS実践ガイド

:visitedの深淵:ブラウザのセキュリティ要塞を読み解くCSSアーキテクチャ

フロントエンドの戦場において、`:visited`ほど「厄介者」として扱われ、同時に「仕様の深淵」を感じさせるセレクタはないだろう。

多くの駆け出しエンジニアは「色が変えられない」「なぜか効かない」と頭を抱え、早々に諦めてしまう。しかし、我々のようなシステムアーキテクトにとって、`:visited`はブラウザのプライバシー保護における「要塞」であり、その挙動を理解することは、ブラウザの描画エンジンがどうやってユーザーの履歴を隔離しているかを理解することと同義だ。

今日は、この「制約だらけの擬似クラス」を、いかにして堅牢なアプリケーション設計に組み込むか。その泥臭い現実と、理論武装した解決策について語ろう。

—

なぜ `:visited` には「鉄の掟」があるのか

まず大前提だ。なぜ`color`以外のプロパティ、例えば`background-color`や`font-size`が変更できないのか。

答えは単純。「ユーザーの閲覧履歴をWebサイト側が盗み見ることができないようにするため」だ。もし任意のCSSプロパティが変更可能であれば、攻撃者は巧妙に配置したリンクの`getComputedStyle`をJavaScriptで読み取るだけで、ユーザーがどのサイトを訪問したかを完全に特定できてしまう。これはプライバシーへの重大な脅威だ。

ブラウザエンジンは、この情報のリークを防ぐため、`:visited`に対して極めて厳しい制約を課している。

  • 変更可能なのは color, background-color, border-color などのごく一部のみ
  • アルファチャンネル(透明度)は無視される
  • `getComputedStyle` は常にデフォルト(未訪問状態)を返す

この「壁」を理解せずに設計を行うと、デザインシステム全体が崩壊する。レンダリングパイプラインにおいて、`:visited`はセキュリティレイヤーで完全に隔離された「特異点」なのだ。

—

現場で遭遇する「非同期の競合」と設計の罠

実務において最も頭を悩ませるのが、CSS-in-JSやコンポーネント指向フレームワークとの競合だ。

例えば、`styled-components`や`Emotion`で以下のように書いたとしよう。

/ コンポーネント内の動的スタイル /
const StyledLink = styled.a`
color: blue;
&:visited {
color: purple; / これが効くためには、ブラウザのセキュリティ制限をクリアする必要がある /
}
`;

ここで重要なのは、「`:visited`の優先順位はCSSのカスケーディングルールではなく、ブラウザの内部的な状態管理に依存する」という点だ。もしあなたがグローバルなリセットCSSや、特定のユーティリティクラスで`!important`を乱用しているなら、`:visited`はあっさりと無視される。

堅牢な設計のためのアーキテクチャ・ルール

1. プロパティの分離:
`:visited`に適用するプロパティは、通常のスタイルから完全に独立させること。無理に複雑な継承を行わず、フラットな構成にするのが最もバグが少ない。
2. アルファ値の罠を回避:
`rgba(0, 0, 0, 0.5)`のような透明度を含む色は、`:visited`では無視されるか、不透明色に強制変換される。設計時には、必ず完全な不透明色(HexやRGB)を定義しておくこと。

—

実践:パフォーマンスを犠牲にしない「訪問済み」スタイリング

パフォーマンスの観点から言えば、`:visited`はレンダリング負荷が極めて低い。ブラウザはリンクの履歴をインメモリで保持しており、再描画のトリガーも非常に限定的だからだ。しかし、Webアプリケーションの規模が大きくなると、この「微々たる負荷」が積み重なる。

以下のコードは、保守性とパフォーマンスを両立させた、あるべき実装の指針だ。

/

  • 構造化されたリンクスタイル
  • 状態を分離し、セレクタの特異性(Specificity)を一定に保つ

/
.nav-link {
color: var(–color-primary); / 変数を利用して一元管理 /
transition: color 0.2s ease-in-out;
}

/

  • :visited は常に独立したブロックに記述する。
  • 他の擬似クラス(:hover, :active)と混ぜると、
  • ブラウザごとのレンダリングの不一致を招く可能性がある。

/
.nav-link:visited {
/ セキュリティ制限に抵触しないよう、不透明な色のみを指定 /
color: var(–color-visited);
}

/ ホバー時は履歴に関わらず色を変える /
.nav-link:hover {
color: var(–color-accent);
}

—

結論:技術的負債を生まないために

`:visited`をハックしようとしてはいけない。JavaScriptで履歴を特定しようとするような「小手先の技」は、将来のブラウザアップデートで遮断されるのがオチだ。

上級エンジニアとしての私の推奨はこうだ。
「`:visited`をデザインの『装飾』として過度に期待するな」。

ユーザーの利便性を高めるために訪問済みリンクを示すことは素晴らしいが、それがUIのコアなUX設計を左右するような実装は避けるべきだ。むしろ、サーバーサイドでのセッション管理や、ローカルストレージを活用した「ユーザーの文脈」の保持を検討し、CSS側にはあくまで「視覚的なヒント」という役割を与えるのが、現代的なフロントエンド・アーキテクチャの答えである。

この制約だらけの仕組みを愛し、その上で軽やかに踊る。それこそが、我々エンジニアが持つべき「真の技術力」ではないだろうか。

コメント

タイトルとURLをコピーしました