currentColor パターン
問題
AIエージェントはすべてのプロパティに色値をハードコードしがちです。color、border-color、box-shadow、outline、SVGの fill に個別の hex 値を設定し、これらすべてが要素のテキストカラーと一致すべき場合でもそうします。これはメンテナンスの問題を生みます:コンポーネントの色を変更する場合、複数の宣言を更新する必要があります。さらに悪いことに、親コンポーネントがテキストカラーを変更した場合(ホバー状態やテーマ切り替えなど)、ボーダー、アイコン、シャドウは特定の hex 値に固定されているため追従しません。
解決方法
currentColor は、要素の計算された color 値に解決されるCSSキーワードです。ボーダー、シャドウ、アウトライン、SVGのフィル、その他のカラープロパティがテキストカラーに自動的に追従するようになります。これはCSSで最も活用されていないパターンの1つで、CSS3から対応しておりすべてのブラウザで動作します。
主な動作
currentColorはカスケードを通じて継承されます — 要素が独自のcolorを設定していない場合、親から継承しますborder-colorはデフォルトで暗黙的にcurrentColorですが、他のプロパティでは明示的に指定する必要があります- CSSカスタムプロパティや
color-mix()と組み合わせて使えます
コード例
テキストカラーに追従するボーダー
/* VERBOSE: separate color declarations */
.card {
color: #1a365d;
border: 1px solid #1a365d;
}
.card:hover {
color: #2b6cb0;
border-color: #2b6cb0; /* Must update separately */
}
/* BETTER: currentColor keeps them in sync */
.card {
color: #1a365d;
border: 1px solid currentColor;
}
.card:hover {
color: #2b6cb0;
/* Border color updates automatically */
}
currentColor — 親の色を変えるとすべてが更新される
テキストカラーに一致するSVGアイコン
currentColor が最も価値を発揮する場面です。fill="currentColor" を持つインラインSVGは、親のテキストカラーを自動的に採用します:
<button class="btn-primary">
<svg width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">
<path fill="currentColor" d="M8 0l2.5 5.3L16 6.2l-4 3.8L13 16 8 13.2 3 16l1-6L0 6.2l5.5-.9z" />
</svg>
Add to favorites
</button>
.btn-primary {
color: white;
background: oklch(50% 0.22 264);
}
.btn-primary:hover {
color: oklch(90% 0.05 264);
/* SVG fill automatically updates to the new color */
}
ボックスシャドウ
.tag {
color: oklch(45% 0.2 264);
border: 1px solid currentColor;
box-shadow: 0 1px 3px currentColor;
}
/* Semi-transparent shadow using color-mix with currentColor */
.card {
color: oklch(30% 0.05 264);
box-shadow: 0 4px 12px color-mix(in oklch, currentColor 25%, transparent);
}
アウトラインとフォーカスリング
/* Focus ring that matches the element's text color */
.input:focus-visible {
outline: 2px solid currentColor;
outline-offset: 2px;
}
/* Link focus ring that matches the link color */
a:focus-visible {
outline: 2px solid currentColor;
outline-offset: 3px;
}
テキストデコレーション
/* Underline color automatically matches text */
a {
color: oklch(50% 0.2 264);
text-decoration-color: currentColor;
}
/* Subtle underline using semi-transparent currentColor */
a {
color: oklch(50% 0.2 264);
text-decoration-color: color-mix(in oklch, currentColor 40%, transparent);
}
a:hover {
text-decoration-color: currentColor; /* Full opacity on hover */
}
マルチカラーコンポーネントバリアント
.badge {
color: var(--badge-color, oklch(45% 0.15 264));
border: 1px solid currentColor;
background: color-mix(in oklch, currentColor 10%, transparent);
}
/* All color properties follow from one custom property */
.badge--success {
--badge-color: oklch(45% 0.15 145);
}
.badge--warning {
--badge-color: oklch(55% 0.18 85);
}
.badge--danger {
--badge-color: oklch(50% 0.2 25);
}
<span class="badge badge--success">Active</span>
<span class="badge badge--warning">Pending</span>
<span class="badge badge--danger">Failed</span>
ディバイダーとセパレーター
.divider {
border: none;
border-block-start: 1px solid currentColor;
opacity: 0.2;
}
/* The divider inherits the section's text color */
.dark-section {
color: white;
}
.light-section {
color: #333;
}
CSSカスタムプロパティとの組み合わせ
:root {
--link-color: oklch(50% 0.2 264);
}
a {
color: var(--link-color);
text-decoration-color: color-mix(in oklch, currentColor 50%, transparent);
transition: color 0.2s;
}
a:hover {
color: oklch(40% 0.25 264);
/* text-decoration-color updates through currentColor */
}
a svg {
fill: currentColor; /* Icon follows link color */
}
AIがよくやるミス
currentColorで同期を保つ代わりに、color、border-color、box-shadow、SVGのfillに同じ色値をハードコードしている- インラインSVGアイコンに
fill="currentColor"を設定せず、状態変更時にSVGの色を変更するためにJavaScriptを書いている currentColorを使えば1つのcolor更新で変更が伝播するのに、ボーダー、シャドウ、アイコンの色を個別に更新する:hoverルールを書いている- 要素の
colorが遠い祖先から継承されており予期せず変わる可能性がある場面でcurrentColorを使っている — どの要素がcolorを設定するか意図的に考えましょう border-colorがすでにデフォルトでcurrentColorであることを忘れている —border-color: currentColorの明示的な設定は有効ですが冗長ですcolor-mix()とcurrentColorを組み合わせた半透明バリアント(例:color-mix(in oklch, currentColor 25%, transparent)のさりげないシャドウ)を活用していないbackground-colorにcurrentColorを使い、テキストを自身の背景に対して見えなくしている —currentColorはアクセントカラー用であり、背景用ではありません
使い分け
- ボタンやリンク内のSVGアイコン: すべての状態(デフォルト、ホバー、アクティブ、無効、フォーカス)でアイコンの色がテキストカラーに自動的に追従する
- コンポーネントのボーダー: 1つの
color変更でテキストとボーダーが一緒に更新される - フォーカスインジケーター:
outline: 2px solid currentColorで要素のコンテキストに常に合うフォーカスリングが作られる - 色調整されたコンポーネント: バッジ、タグ、アラートで、ボーダー、背景ティント、テキストが1つの色から導出されるべき場面
- テキストデコレーション: テキストカラーに一致する、または部分的に一致するさりげないアンダーライン
使わない方がよい場面
- 背景:
background: currentColorはテキストが見えなくなります(子要素に別のcolorを設定しない限り) - テキストと一緒に変わるべきでない色: ロゴ、ブランドマーク、コンテキストに関係なく固定色が必要なアイコン
- 複雑なマルチカラーコンポーネント: ボーダー、アイコン、テキストが意図的に異なる色を使う場合