キーワード検索50の記事がヒットしました。

鳥に生まれることができなかった人へ

CSSでも変数が使える❗️❗️

CSSでは長らく、いわゆる「変数」なるものを使用することが出来ませんでした。例えばサイトのテーマカラーが#339898だとしたら、CSSファイルの色んな所でこの文字列をハードコードしないといけなかったわけです。ここだけ進化していないと言うか、何ともウェッブ黎明期らしい香りがしますね。

SCSSには変数という機能がありこれをカバーしてくれるので、SCSSを使用しだしてからは不便さは感じていなかったんですが、現在では生のCSSで変数を使用できるというわけです。

仕様としてはまだ勧告候補(Candidate Recommendation Draft)の状態ですが、この通りモダンブラウザーは既にこの仕様をサポートしているので早速試してみましょう。

今回の記事ではCSS変数の概要について簡単に説明します。なお、正式名称は「CSS変数」ではなく、CSS custom properties for cascading variablesといいます。ただし今回の記事では便宜上、CSS変数と呼ぶことにします。

変数の定義と呼び出し方

では、サイトのメインカラーの値を定義する変数を用意して使用してみましょう。以下のように変数名: 値という風に変数を定義します。

style.css
:root {
  --main-color: #399;
}

この変数--main-colorを呼び出すには、var関数を使用します。

style.css
:root {
  --main-color: #399;
}

h1 {
  color: var(--main-color);
}

たったこれだけの事でCSS変数を利用できます。簡単ですね。

命名規則

では、CSS変数の概要についてざっと追っていきましょう。

まずは変数の命名規則ですが、先頭に--をつける必要があります。また、単語をつなぐときはケバブケースにするのが慣習のようですね。

style.css
:root {
  /* 先頭に--をつける */
  /* ケバブケースにするのがGood */
  --main-color: #399;
}

また、ケースセンシティブですのでアルファベットの大文字と小文字は区別されます。

style.css
:root {
  /* これらは別の変数 */
  --main-color: #399;
  --Main-Color: #5f5;
}

大文字を含めるか否かという所ですが、全部小文字の方がCSSらしいと思いますし、ドキュメントのサンプルを見ていてもほとんど小文字だったのでやはりその方がいいと思います。CSSで大文字を使うと違和感がすごいですね。

単位も一緒に変数にする

これまでは色を定義する変数を例にとりましたが、もちろんwidthの値を定義しておくこともできます。この時、単位も含めて変数に格納しましょう。

style.css
:root {
  /* 単位も含めること */
  --wrapper-width: 1166px;
}

.wrapper {
  width: var(--wrapper-width);
}

値(数値)だけを変数に含めて、呼び出し側で単位を付与することはできません。下記のようにするとスタイルは適用されません。

style.css
:root {
  /* 単位なし */
  --wrapper-width: 1166;
}

.wrapper {
  /* こんな風に単位を付与しようとしても動作しない */
  width: var(--wrapper-width)px;
}

calc()を使用して、変数から呼び出した値に* 1pxなどとして単位を付与することもできます。ただ、これはハック的というか、個人的にはあまり好きではない方法です。使える場面ってどれだけあるんだろうか?

style.css
:root {
  /* 単位なし */
  --width-container: 1166;
}

.wrapper {
  /* 1pxをかけて単位をつける */
  width: calc(var(--wrapper-width) * 1px);
}

スコープ

プログラミング言語の変数と同じように、CSS変数もスコープを持ちます。変数定義の際、:rootブロックの中で宣言すればHTMLファイル全体で有効な変数を定義することになります。例えばsectionブロックの中ならsection要素の中だけ、.wrapperブロックならばwrapperクラスの中でだけ有効な変数になります。

style.css
/* HTML全体で使用できる、グローバル */
:root {
  --main-color: #338989;
}

/* section要素の中でのみ使用できる */
section {
  --section-title-color: #445;
}

/* wrapperクラスの中でのみ使用できる */
.wrapper {
  --wrapper-width: 1166px;
}

HTML側で変数を定義できる

さて、ここまででもCSS変数の便利さは伝わったと思うのですが、もうひとつ、個人的にとても好きなCSS変数の利用方法を紹介します。CSS変数はなんと、html側のタグのstyle属性でも定義できるのです。

題材として、以下のようなプログレスバーを考えます。

image01

HTMLとCSSは以下の通りです。

index.html
<body>
  <p>30%</p>
  <div class="wrapper">
    <span class="bar bar1"></span>
  </div>

  <p>40%</p>
  <div class="wrapper">
    <span class="bar bar2"></span>
  </div>

  <p>50%</p>
  <div class="wrapper">
    <span class="bar bar3"></span>
  </div>
</body>
style.css
:root {
  --wrapper-width: 350px;
}

.wrapper {
  position: relative;
  width: var(--wrapper-width);
  height: 20px;
  margin-bottom: 30px;
  border: 1px solid #444;
}

/* グラデーションバーの共通スタイル */
.bar {
  position: absolute;
  display: block;
  height: 20px;
  background: linear-gradient(to right, #5691c8, #457fca);
}

/* グラデーションバーの横幅をそれぞれ定義 */
.bar1 {
  width: calc(var(--wrapper-width) * 0.3);
}

.bar2 {
  width: calc(var(--wrapper-width) * 0.4);
}

.bar3 {
  width: calc(var(--wrapper-width) * 0.5);
}

構成をざっと説明します。.wrapperがバーの外枠で、.barが青のグラデーションになっている部分です。CSS変数--wrapper-widthを定義することで、外枠の大きさを定義しています。グラデーションバーについては、.barで定義しています。また、3つの.barそれぞれにbar1bar2bar3と個別のクラスを定義し、そこでcalc()を使ってwidthの値を計算しています。

これでも問題ないのですが、HTML側でもCSS側でもbar1bar2bar3という3つのクラスが定義されていることがちょっと気になります。以下のようにHTML側でCSS変数を定義してみましょう。

index.html
<div class="wrapper">
  <span class="bar" style="--width: 0.3"></span>
</div>

<div class="wrapper">
  <span class="bar" style="--width: 0.4"></span>
</div>

<div class="wrapper">
  <span class="bar" style="--width: 0.5"></span>
</div>

HTML側ではstyle属性の中にCSS変数を定義します。そうすればCSS側で取り出して利用することができます。

style.css
.bar {
  position: absolute;
  display: block;
  height: 20px;
  /* style属性で定義された--widthを利用して計算する */
  width: calc(var(--wrapper-width) * var(--width));
  background: linear-gradient(to right, #5691c8, #457fca);
}

こうしてCSS側での.bar1.bar2.bar3を削除することができました。メンテナンス性も向上しますね。


このCSS変数はかなり利用シーンが広そうなので、改めて別で詳しく記事にする予定です。

参考