IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

CSS の「値」とは何か

この前

以下のようなエントリを書きました
CSS の名前の整理 - IT戦記

今回は CSS における

この「value(値)」という言葉の意味、そして曖昧さについて書きたいと思います。

6 つの値

CSS において「値」は曖昧な言葉です。
なので、「値」という言葉を使って CSS の説明をするのは非常に効率が悪かったりします。
たとえば、「ここの値って、 hogehoge の意味の値?」「いやいや、ここの fugafuga の意味の値が piyopiyo なんだよ」というように、まったく無駄な会話が繰り広げられるわけです。
ですので、今日からはちゃんと CSS の「値」をちゃんと説明できるように、「値」に以下の 5 つの名前を付けましょう。

  1. Declared values
  2. Cascaded values
  3. Specified values
  4. Computed values
  5. Used values
  6. Actual values
何故、 6 つ?

これらの「値」たちは要素がレンダリングされる過程で計算された「途中の値」を表しています。
まず、 Declared values から Cascaded values が求められ、 Specified values から Completed values が求められ、、、最終的には要素がレンダリングされる。という感じです。
そして、この値が計算されていく過程はすべての要素に対して一斉に行われる訳ではなくて、 Computed values までは親要素から順に計算されていきます。それは、子要素の Specified values のの計算に親要素の Computed values が必要だからです。
それでは順に、値の意味、遷移を見ていきましょう

Declared values

この「Declared values」という言葉は CSS の仕様に書かれているわけではありませんが、以下に続く 5 つの「値」と区別するために僕が付けた名前です。
「Declared values」とは、 CSS を書いた人が実際に書いた値のことです。
一つの要素の一つのプロパティに対して、複数の「値」が宣言されている場合があります。たとえば <div class="hoge"> に対して div { width: 10px } .hoge { width: 20px } というルールセットが宣言された場合です。
ブラウザが CSS をどう解釈したかではなく、CSS を書いた人が実際に書いた値に対して言及したいときにこの言葉を使うといいです。

Cascaded values

「Cascaeded values」とは、前回説明したカスケーディング(一つの要素の一つのプロパティに対して、複数の「値」が宣言されている場合に一つの値を決めるしくみ)で勝った「値」を表します。
つまり、カスケーディングによって「Declared values」から一つ選ばれた「値」が「Cascated values」ということになります。

ちなみに、カスケーディングする前にショートハンドプロパティの値はそれぞれの値に分解されます。
ショートハンドプロパティとは「margin」や「padding」などのいくつかの宣言がまとまったプロパティのことで、ショートハンドプロパティじゃないプロパティに分解することが出来ます。
たとえば、「margin: 10px」という宣言は「margin-left: 10px」「margin-right: 10px」「margin-top: 10px」「margin-bottom: 10px」という風に分解されます。
ですので、実際はショートハンドプロパティの「Cascaded value」はないです。
でも、 margin-(left|right|top|bottom) のすべてのプロパティの「Cascaded values」に言及する場合に「margin プロパティの Cascaded values」とか表現することはありますね。

Specified values

「Specified values」とは、「継承」または「初期値の割当」が行われた直後の「値」のことを言います。
「継承」というのは、 inherit という「値」をもったプロパティが、親要素の「Computed values」をコピーすることを言います。
「初期値の割当」というのは、 initial という「値」をもったプロパティが、「初期値」になることを言います。「初期値」は、プロパティごとに決まっています。
また、ルート要素(HTML 要素)が「継承」を行おうとした場合は、「初期値の割当」が行われます。
「値」を持たないプロパティは「継承」か「初期値の割当」が自動で行われます。どちらが行われるかは、プロパティごとに決まっています。
この辺は、またややこしいので別のエントリにまとめたいと思います。

Computed values

「Computed values」とは、「レンダリングに依存しない値」に対して単位の変換を行った後の「Specified values」のことを言います。
たとえば、 HTML 要素の width などは実際にブラウザの横幅が分かるまで(レンダリングするまで)計算することできませんよね。ここでは、そういう「レンダリングしないと分からない値」以外の「値」のことを「レンダリングに依存しない値」と言います。
で、実際にどういう風に単位変換されるかというと、

  • em, ex → px
  • レンダリングに依存しない % 値 → px
  • 相対URL → 絶対URL
  • bolder → er が取れた形で

などなどです。
また、ここで重要なのは「継承」に使われるのはこの値だということです。たとえば、 width が 200% の場合、その値がこの段階で求められるかどうかで、継承される値は 2 倍変わってきます。ですので、 width, height の「継承」はしないほうがいいと思います。(明示的に inherit と書かない限りは継承されないので、実害はないと思いますが)
あと、この「値」までは、レンダリングされなくても求めることが出来るため。極端な話、 HTML と CSS が与えられれば暗算することも可能なはずです。
ここら辺もいろいろあるので、そのうちまとめたいと思います。

Used values

「Used values」とは、「レンダリングに依存する値」に対して単位の変換を行った後の「Computed values」の値のことを言います。
レンダリングに依存する値」は具体的にいうと、(祖先要素も含めて)%, auto 指定された widthheight の「値」のことです。
%, auto は px に単位変換されます。
ちなみに、 JavaScript の getComputedStyle で取得できる CSSStyleDeclaration オブジェクトはこの「値」を持っています。

Actual values

「Acltual values」とは、実際にレンダリングされた「値」のことを言います。
たとえば、「Used value」が 4.2 px でも実際ディスプレイにはは 4 px しかレンダリングされません。
ですので、この 4 px に言及したい場合にこの言葉を使います。

という訳で

CSS の「値」を求める過程と、その過程での「値」を振り返ってみました。
このイメージをしっかり持つことは、 CSS を書く場合に非常に重要です。

また

JavaScript で CSSStyle* 系のオブジェクト をいじる場合は

  • どの 要素 or ルールセット の
  • どの プロパティ
  • どの 単位 で

書き換えれば、無理のないレンダリングが出来るかを考えるのが非常に重要です。
たとえば、ここをいじったせいでこっちもいじらければならない><
というようなことを無くすことができ、パフォーマンスを何倍にも向上させることができます(マジで
この知識はそういう場面でも威力を発揮します。

まとめ

もう、 CSS の値については完璧ですね!
この説明、自分で書いててめっちゃ難しかったです><