CSS変数を利用したショートハンドプロパティもどき

CSSの各種プロパティの中には、関連するプロパティの値を一括指定できるショートハンドプロパティがあります。一方で、複数の値を指定できるものの、それらの値を個別に設定できない、ショートハンドプロパティではないプロパティもあります。

今回は、ショートハンドプロパティではないプロパティを、ショートハンドプロパティのように扱う、CSS変数 (カスタムプロパティ) の使用方法を紹介します。

backgroundプロパティの例

backgroundプロパティは、次の個別のプロパティを一括指定できるショートハンドプロパティです。

  • background-attachmentプロパティ
  • background-clipプロパティ
  • background-colorプロパティ
  • background-imageプロパティ
  • background-originプロパティ
  • background-positionプロパティ
  • background-repeatプロパティ
  • background-sizeプロパティ

例えば、デフォルトの背景を設定し、部分的に異なるバージョンを複数用意する場合、次のようなCSSコードになります。

/* デフォルト */
.background {
  background: black url(image-0.png) repeat left top / contain;
}

/* .background の black を上書き */
.background_gray {
  background-color: gray;
}

/* .background の url(image-0.png) を上書き */
.background_image-1 {
  background-image: url(image-1.png);
}

/* .background の repeat を上書き */
.background_no-repeat {
  background-repeat: no-repeat;
}

/* .background の left top を上書き */
.background_center {
  background-position: center;
}

/* .background の contain を上書き */
.background_cover {
  background-size: cover;
}

box-shadowプロパティの例

box-shadowプロパティはショートハンドプロパティではありませんが、次の複数の値を指定できます。

  • offset-x (X軸のオフセット値)
  • offset-y (Y軸のオフセット値)
  • blur-radius (ぼかしの半径)
  • spread-radius (拡張する半径)
  • color (影の色)
  • inset (影を内側へ)

部分的に異なるバージョンを複数用意する場合、通常であれば、次のようなCSSコードになります。

/* デフォルトの設定 */
.box-shadow {
  box-shadow: 4px 4px 0 0 black;
}

/* 黒い影を左上に */
.box-shadow_top-left {
  box-shadow: -4px -4px 0 0 black;
}

/* ぼかしのある黒い影を右下に */
.box-shadow_blur {
  box-shadow: 4px 4px 4px 0 black;
}

/* 赤い影を右下に */
.box-shadow_red {
  box-shadow: 4px 4px 0 0 red;
}

box-shadowプロパティはショートハンドプロパティではないので、それぞれの値をピンポイントに変更できません。そこで、CSS変数を使用します。

/* 黒い影を右下に */
.box-shadow {
  --box-shadow--offset-x: 4px;
  --box-shadow--offset-y: 4px;
  --box-shadow--blur-radius: 0;
  --box-shadow--spread-radius: 0;
  --box-shadow--color: black;
  box-shadow: var(--box-shadow--offset-x) var(--box-shadow--offset-y) var(--box-shadow--blur-radius) var(--box-shadow--spread-radius) var(--box-shadow--color);
}

/* 黒い影を左上に */
.box-shadow_top-left {
  --box-shadow--offset-x: -4px;
  --box-shadow--offset-y: -4px;
}

/* ぼかしのある黒い影を右下に */
.box-shadow_blur {
  --box-shadow--blur-radius: 4px;
}

/* 赤い影を右下に */
.box-shadow_red {
  --box-shadow--color: red;
}

それぞれの値を個別のCSS変数にして、部分的な上書きを可能にします。これが「ショートハンドプロパティもどき」です。

もちろん、box-shadow以外のプロパティでも、backgroundプロパティのように扱うことができます。

ショートハンドプロパティもどきの注意点

box-shadowプロパティのinsetのように、その値の有無で有効・無効が切り替わるものはCSS変数にできません。

また、CSS変数を呼び出す、var関数値には代替値 (フォールバック) を設定できますが、代替値は設定せず、CSS変数に初期値を設定したほうがいいです。

/* 代替値を使用 */
.box-shadow {
  box-shadow: var(--box-shadow--offset-x, 4px) var(--box-shadow--offset-y, 4px) var(--box-shadow--blur-radius, 0) var(--box-shadow--spread-radius, 0) var(--box-shadow--color, black);
}

/* 代替値は未使用でCSS変数に初期値を設定 */
.box-shadow {
  --box-shadow--offset-x: 4px;
  --box-shadow--offset-y: 4px;
  --box-shadow--blur-radius: 0;
  --box-shadow--spread-radius: 0;
  --box-shadow--color: black;
  box-shadow: var(--box-shadow--offset-x) var(--box-shadow--offset-y) var(--box-shadow--blur-radius) var(--box-shadow--spread-radius) var(--box-shadow--color);
}

その理由は、要素が入れ子になった場合、祖先要素に設定したCSS変数が、子孫要素に適用される可能性があるためです。

<style>
.box-shadow {
  box-shadow: … var(--box-shadow--color, black);
}
.box-shadow_red {
  --box-shadow--color: red;
}
</style>

<div class="box-shadow">
  <p>--box-shadow--color は未設定。代替値の black が適用され、黒い影で表示される。</p>

  <div class="box-shadow box-shadow_red">
    <p>--box-shadow--color に red を設定。赤い影で表示される。</p>

    <div class="box-shadow">
      <p>親要素で --box-shadow--color に red を設定したため、代替値の black は適用されず、赤い影で表示される。</p>
    </div>

  </div>

</div>

今年はCSS変数に大変お世話になりました。

関連記事