CSSの部分一致セレクタとカスタムプロパティを組み合わせてコードを簡潔にする。
具体例として、別々の要素のborder-color
とbackground-color
を変数で指定するケースを考える。
HTMLとアウトプットイメージ
HTMLは以下の通り。
<body>
<h1 class="container-of-badge">
<span class="badge-color-red badge">RED</span>
</h1>
<h1 class="container-of-badge">
<span class="badge-color-blue badge">BLUE</span>
</h1>
</body>
最終成果物の見た目をこのようにしたい。
CSS
部分一致セレクタとカスタムプロパティを使用しない場合
この見た目を実現するCSSを考える。色関係について部分一致セレクタとカスタムプロパティを使用せずに書くと以下のようになる。
<style>
:root {
--badge-radius: 10px;
}
.badge-color-red {
background-color: red;
color: white;
}
.badge-color-blue {
background-color: blue;
color: white;
}
.container-of-badge {
border-width: 1px;
border-bottom-style: solid;
border-bottom-left-radius: var(--badge-radius);
&:has(> .badge-color-red) {
border-color: red;
}
&:has(> .badge-color-blue) {
border-color: blue;
}
}
.badge {
border-radius: var(--badge-radius);
display: inline-block;
padding-inline: 0.25em;
}
</style>
部分一致セレクタとカスタムプロパティを使用しない場合のデメリットとして、以下のようにred
という文字の重複があることが挙げられる。
.badge-color-red {
background-color: red;
/* 略 */
&:has(> .badge-color-red) {
border-color: red;
セレクタとしてclass名の.badge-color-red
を記載するのは最低限必要なことだとしても:has(> .badge-color-red)
でもclass名を記載しなければいけない。
またbackground-color
, border-color
の両方にred
と書かなければいけない(ただしこの点だけであれば--badge-color-red: red
とカスタムプロパティを設定・使用すれば解決する)。
これを色のバリエーションの分書いていくと、将来のカラーコード修正が大変になる。
部分一致セレクタとカスタムプロパティを使用する場合
部分一致セレクタとカスタムプロパティを使用したコードをまず提示する。
<style>
:root {
--badge-radius: 10px;
--badge-color: black; /* 初期値 書かなくても問題ない */
}
[class*='badge-color-'] {
background-color: var(--badge-color);
color: white;
}
.container-of-badge {
border-color: var(--badge-color);
border-width: 1px;
border-bottom-style: solid;
border-bottom-left-radius: var(--badge-radius);
&:has(> .badge-color-red) {
--badge-color: red;
}
&:has(> .badge-color-blue) {
--badge-color: blue;
}
}
.badge {
border-radius: var(--badge-radius);
display: inline-block;
padding-inline: 0.25em;
}
</style>
主な変更点としては以下になる。
[class*='badge-color-'] {
background-color: var(--badge-color);
/* 略 */
.container-of-badge {
border-color: var(--badge-color);
/* 略 */
&:has(> .badge-color-red) {
--badge-color: red;
}
&:has(> .badge-color-blue) {
--badge-color: blue;
}
[class*='badge-color-']
とすることで、badge-color-
という文字がclassに含まれている要素を指定できるようにしている。
このおかげで色のバリエーション分(つまり.badge-color-red
, .badge-color-blue
)定義する必要がなくなり、一箇所でbackground-color
を変数で設定できるようになった。またborder-color
にも同じ変数を設定するため、カラーコード修正の際に変更が一箇所で済む。
変数の設定はhas
を利用している。.container-of-badge:has(> .badge-color-red)
とすることで、classにbadge-color-red
が指定されている親要素である.container-of-badge
では、--badge-color
が初期値のblack
からred
になる。
カスタムプロパティはカスケードの対象であり、親から値を継承するため、<h1 class="container-of-badge">
の子孫である<span class="badge-color-red badge">RED</span>
も--badge-color
が初期値のblack
からred
になる。