CSS値と単位モジュール レベル5

W3C作業草案

この文書の詳細
このバージョン:
https://www.w3.org/TR/2024/WD-css-values-5-20241111/
最新版公開バージョン:
https://www.w3.org/TR/css-values-5/
編集者ドラフト:
https://drafts.csswg.org/css-values-5/
履歴:
https://www.w3.org/standards/history/css-values-5/
フィードバック:
CSSWG イシューレポジトリ
仕様内インライン
編集者:
Tab Atkins (Google)
Elika J. Etemad / fantasai (Apple)
Miriam E. Suzanne (招待専門家)
この仕様の編集提案:
GitHub エディター
テストスイート:
https://wpt.fyi/results/css/css-variables/

概要

このCSSモジュールは、CSSプロパティが受け入れる共通の値や単位、およびそれらをCSSプロパティ定義で記述する際の構文について説明します。

CSSは、構造化文書(HTMLやXMLなど)の画面・紙などへの描画(レンダリング)方法を記述する言語です。

この文書の位置付け

このセクションでは、本書の発行時点の位置付けについて説明します。 最新のW3C出版物一覧や、この技術レポートの最新版は W3C 技術レポート一覧 https://www.w3.org/TR/で確認できます。

この文書はCSS ワーキンググループによって勧告トラックを利用した作業草案として公開されました。 作業草案としての公開は、W3Cおよびそのメンバーによる承認を意味するものではありません。

この文書はドラフトであり、随時他の文書によって更新・置換・廃止されることがあります。 進行中の作業以外のものとしてこの文書を引用するのは適切ではありません。

ご意見・ご要望はGitHubでイシューを提出(推奨)してください。その際、タイトルに仕様コード「css-values」を含めて、 たとえば「[css-values] …コメントの要約…」のようにしてください。 すべてのイシューとコメントはアーカイブされます。 または、(アーカイブ)付き公開メーリングリスト www-style@w3.org へ送信することもできます。

この文書は2023年11月3日 W3Cプロセス文書に従って運用されています。

この文書は、W3C特許ポリシーの下で活動するグループによって作成されました。 W3Cは、グループの成果物に関連した公開特許開示リストを管理しています。 このページには特許の開示手続きも記載されています。 もし、ある特許が必須クレームを含むと知っている場合、その情報はW3C特許ポリシー第6節に従い開示する必要があります。

この仕様は初期の検討段階です。ご意見を歓迎します。今後大きな変更がある可能性があります。

1. 序章

これは CSS 値と単位 レベル 4 との差分仕様です。

1.1. モジュール間の関係

このモジュールは [CSS-VALUES-4] を拡張します。[CSS-VALUES-4] は [CSS21]1.4.2.14.3、 および A.2 節のデータ型定義を置き換えおよび拡張しています。

2. テキストデータ型

CSS Values 4 § 4 テキストデータ型 を参照。

3. 値の定義構文

CSS Values 4 § 2 値の定義構文 を参照。

さらに、

  1. 条件付き記法のブール結合。 これらは <boolean-expr[]> 記法を用いて記述され、 キーワードおよび括弧で再帰的なブール論理式を表します。 ブラケット内で指定された文法に適用し、 例えば <boolean-expr[ ( &lt;media-feature&gt; ) ]>メディアクエリ を表します。

3.1. 関数記法の定義

CSS Values 4 § 2.6 関数記法の定義 を参照。

3.1.1. 関数引数内のカンマ

関数記法は、その内部文法の区切りとしてカンマを使用することが多いです。 しかし、いくつかの関数 (例えば mix() など)は 値自体がカンマを含むことを許可します。 これらの値 (現時点では <whole-value><declaration-value><any-value>)は カンマを含む生成式 です。

この種の文法を曖昧なく扱うために、 カンマを含む生成式は波括弧{}でラップすることができます(任意)。 これらの波括弧は構文上のみで実際の値の一部ではありません。 具体的には:

例えば、random-item() 関数の文法は以下のようになります:
random-item( <random-caching-options>, [<declaration-value>?]# )

ここで # はカンマ区切りの繰り返しを表すので、 例えば3つのキーワードからランダムで選択する場合、 関数の通常の方法で以下のように書きます:

font-family: random-item(--x, serif, sans-serif, monospace);

しかし、選択する値の中にカンマを含めたい場合があります。 そういった場合は値を{}でくくることで、 そのカンマが関数の引数区切りカンマとは別であると区別できます:

font-family: random-item(--x, {Times, serif}, {Arial, sans-serif}, {Courier, monospace});

これにより、3つのフォントファミリーリスト Times, serifArial, sans-serifCourier, monospace のうちどれかがランダムで選択されます。

これは all-or-nothing(全てかゼロか)ではありません。 必要な引数のみ{}で囲み、他はそのまま裸で書いても構いません。 また、必ずしも必須でない場合にも{}で囲んでよいです。例えば:

font-family: random-item(--x, {Times, serif}, sans-serif, {monospace});

この場合は3つのフォントファミリーリスト Times, serifsans-serifmonospace のいずれかを選択します。

ただし、この{}ラップは カンマを含む生成式 に対してのみ許可されます。 それ以外の生成式に{}を使うことはできません。 他の関数引数を{}でくくると関数の文法にマッチせず、無効になります。 例えば、以下は無効です:

background-image: linear-gradient(to left, {red}, magenta);

注意: {} のラッパーは明示的に必要ない場合でも許可されているため、値にカンマが含まれるか不明な場合や 任意置換関数(例:var()) で値が途中で変わる可能性がある場合に予防的に{}でラップできます。 例えば font-family: random-item(--x, {var(--list1)}, monospace)--list1 カスタムプロパティがカンマ区切りリストでもそうでなくても正しく動作します。

関数記法は 可能な限り {} ラッパー無しでシリアライズされます。

次の汎用生成式は カンマを含む生成式です:

後方互換理由のため、 <declaration-value> で定義された var() のフォールバック値は 非厳密カンマ生成式 です。 "{" トークンで始まらないときに含有できる内容の制限を無視し、 カンマや{}ブロックを含むことができます。 ただし "{" トークンで始まる場合は通常の カンマを含む生成式 ルールが適用され、 フォールバックは{}内部の内容だけになり、ラッパー自体は含みません。

他の文脈でも 非厳密カンマ生成式の使用が定義されることもありますが、 必要な場合のみそうすべきです。

3.2. ブール式乗算子 <boolean-expr[]>

いくつかの文脈 (@media@supportsif() など)が 条件を指定し、 それらの条件をブール論理(and/or/not/グループ化)で組み合わせ可能としています。 これらはすべて同じ非自明な再帰構文を使うため、 特別な <boolean-expr[]> 生成式がこのパターンを一般化して表します。

<boolean-expr[]> 記法は角括弧の中に別の値型をラップし、 例えば <boolean[ <test> ]> のように使います。 そして単独の値型も、キーワード notandor およびグループ化括弧を使う ブール論理結合も表します。 正式な定義は次の通りです:

<boolean-expr[ <test> ]> = not <boolean-expr-group> | <boolean-expr-group>
                                            [ [ and <boolean-expr-group> ]*
                                            | [ or <boolean-expr-group> ]* ]

<boolean-expr-group> = <test> | ( <boolean-expr[ <test> ]> ) | <general-enclosed>

<boolean-expr[]> 生成式は true, false, unknown のいずれかの値を表します。 その値の解釈は3値クレーネ論理によって行われ、 トップレベルのunknown値 (つまり他の <boolean-expr[]> 文法直下でないもの)はfalseとみなされます(特に指定なければ)。 詳細は 付録B: ブール論理 を参照。

例えば @container 規則は様々なテスト(サイズ、スタイル、スクロール状態) を許容します。 これらはすべて任意にブール論理で組み合わせできます。 <boolean-expr[]> を用いた @container クエリの文法例:
<container-query> = <boolean-expr[ <cq-test> ]>
<cq-test> = (<size-query>) | style( <style-query> ) | scroll-state( <scroll-state-query> )
<size-query> = <boolean-expr[ ( <size-feature> ) ]> | <size-feature>
<style-query> = <boolean-expr[ ( <style-feature> ) ]> | <style-feature>
<scroll-state-query> = <boolean-expr[ ( <scroll-state-feature> ) ]> | <scroll-state-feature>

<general-enclosed> 分岐は将来互換性のためにあります。 特に規定のない限り、新しい式は古いUAでは「unknown」と解釈され、生成式全体が無効になることを避けます。 その方針に合わせて、 <test><boolean-expr[]> 内で <general-enclosed> にマッチするよう定義すべきです。

3.3. CSS で構文記述: <syntax>

CSS のいくつかの機能(例えば attr()登録済みカスタムプロパティ など)は、 他の値をどうパースするかを指定可能です。 これは <syntax> 生成式で記述し、 これは仕様で使われるCSS 値定義構文 の制限付き形式に似ており、 構文定義を表します:

<syntax> = '*' | <syntax-component> [ <syntax-combinator> <syntax-component> ]* | <syntax-string>
<syntax-component> = <syntax-single-component> <syntax-multiplier>?
                   | '<' transform-list '>'
<syntax-single-component> = '<' <syntax-type-name> '>' | <ident>
<syntax-type-name> = angle | color | custom-ident | image | integer
                   | length | length-percentage | number
                   | percentage | resolution | string | time
                   | url | transform-function
<syntax-combinator> = '|'
<syntax-multiplier> = [ '#' | '+' ]

<syntax-string> = <string>

<syntax-component><syntax-type-name>(山括弧で囲む)、 または <ident> のいずれかで構成されます。前者は サポートされる構文コンポーネント名 のいずれかと対応し、 後者は キーワード を表します。 さらに <syntax-component> には 乗数(ミュルチプライヤ)を含めることもでき、 これは 値のリスト を表します。

注意: <length>length は別の型です。 前者は <length>、 後者は keyword length をそれぞれ示します。

複数の <syntax-component>コンビネータ | <delim-token> で結合でき、 順に値に対して適用されます。

<percentage> | <number> | auto

上記を <syntax> としてパースすると、 <percentage><number> の値、さらにキーワード auto を受け入れます。

red | <color>

上記の 構文定義<syntax> として使い、パースすると、 入力 red識別子 として一致し、 blue の場合は <color> に一致します。

* <delim-token>万能構文定義 を示します。

<transform-list> 生成式は <transform-function>+ と等価な簡略形です。ただし <transform-list> の後には <syntax-multiplier> を続けてはいけません。

空白は 山括弧 <delim-token>< >)と それに囲まれる <syntax-type-name> の間には入れられません。 また 空白<syntax-multiplier> の前にも記述できません。

注意: 空白 の制限は <transform-list> にも適用されます。

<syntax-string> は、値が <string> であり、これがCSS構文によるパースに成功する場合です。 そしてその <syntax> と同じ値を表します。

注意: <syntax-string> は 主に歴史的な理由で存在します。 <syntax> が定義される以前は、 @property 規則がこの目的に <string> を使っていました。

3.3.1. <syntax> としてのパース

<syntax> の目的は一般に「別の値」( 登録済みカスタムプロパティattr() の属性値など)をどうパースするか指定することです。 しかし一般的な CSS構文によるパース アルゴリズムは 結果を未規定な内部構造として返します ― パース結果が曖昧になる場合、追加の処理が必要だからです。

こうした問題を避け、明確な結果を得るには <syntax>でパースする を使ってください:

<syntax>でパースする には string または list あるいは component values values<syntax>syntax、 (オプションで)要素 el を与えます。 これは CSS値または guaranteed-invalid value を返します。
  1. component valueリストをパース し、 raw parse を得ます。

  2. もし el が与えられていたなら 任意置換関数の置換raw parse へ行い、 その結果を raw parse に設定します。

  3. CSS構文によるパースvaluessyntax に従いパースします。 * 値は <declaration-value>? として扱います。 parsed result をその結果とします。 syntax| コンビネータが使われていた場合、最初に一致した節の結果を parsed result とします。

  4. もし parsed result が失敗なら、 guaranteed-invalid value を返します。

  5. アサーション: parsed result は今や一意に定義されたCSS値のリストである。 なぜなら、<syntax> の各分岐が曖昧でないよう定義されているため (あるいは * 構文自体が曖昧でないため)。

  6. parsed result を返します。

注意: このアルゴリズムはパースした値を computed value へ解決しません。値の使われ方によって解決されることが多いですが、そうでない場合は呼び出し元アルゴリズムがそれを行う必要があります。

4. レベル4値型への拡張

CSS Values and Units Level 4 を参照してください。

4.1. リソースロケータ: <url>

CSS Values 4 § 4.5 リソースロケータ: <url> 型を参照してください。

4.1.1. リクエストURL修飾子

<request-url-modifier>は、<url-modifier> であり、<url> のリソースリクエストに関連したURLリクエスト修飾子ステップを適用して影響を与えます。 CSS Values 4 § 4.5.4 URL処理モデルも参照してください。

この仕様は、次の<request-url-modifier>を定義します:

<request-url-modifier> = <crossorigin-modifier> | <integrity-modifier> | <referrerpolicy-modifier>
<crossorigin-modifier> = crossorigin(anonymous | use-credentials)
<integrity-modifier> = integrity(<string>)
<referrerpolicy-modifier> = referrerpolicy(no-referrer | no-referrer-when-downgrade | same-origin | origin | strict-origin | origin-when-cross-origin | strict-origin-when-cross-origin | unsafe-url)
<crossorigin-modifier> = crossorigin(anonymous | use-credentials)
この修飾子のURLリクエスト修飾子ステップは、request reqに対して以下の通りです:
  1. requestmode を "cors" に設定します。

  2. 与えられた値が use-credentials の場合は、requestcredentials mode を "include" に設定します。

<integrity-modifier> = integrity(<string>)
この修飾子のURLリクエスト修飾子ステップは、request reqrequestintegrity metadata を、与えられた <string> に設定することです。
<referrerpolicy-modifier> = referrerpolicy(no-referrer | no-referrer-when-downgrade | same-origin | origin | strict-origin | origin-when-cross-origin | strict-origin-when-cross-origin | unsafe-url)
この修飾子のURLリクエスト修飾子ステップは、request req に対し、requestreferrer policy を、指定された値に一致する ReferrerPolicy に設定します。
URL値からリクエスト修飾子を適用するには、request req<url> url が与えられたとき、 req に対して url<request-url-modifier>URLリクエスト修飾子ステップ を順に呼び出します。

4.2. 2次元ポジショニング:<position>

<position> 値は、 アライメント対象(例: 背景画像)の位置を、 アライメントコンテナ(例: その背景配置エリア)の内部に 指定されたエッジ間のオフセットの組として示します (デフォルトは左端と上端)。 構文は次の通りです:

<position> = <position-one> | <position-two> | <position-four>
<position-one> = [
  left | center | right | top | bottom |
  x-start | x-end | y-start | y-end |
  block-start | block-end | inline-start | inline-end |
  <length-percentage>
]
<position-two> = [
  [ left | center | right | x-start | x-end ] &&
  [ top | center | bottom | y-start | y-end ]
|
  [ left | center | right | x-start | x-end | <length-percentage> ]
  [ top | center | bottom | y-start | y-end | <length-percentage> ]
|
  [ block-start | center | block-end ] &&
  [ inline-start | center | inline-end ]
|
  [ start | center | end ]{2}
]
<position-four> = [
  [ [ left | right | x-start | x-end ] <length-percentage> ] &&
  [ [ top | bottom | y-start | y-end ] <length-percentage> ]
|
  [ [ block-start | block-end ] <length-percentage> ] &&
  [ [ inline-start | inline-end ] <length-percentage> ]
|
  [ [ start | end ] <length-percentage> ]{2}
]

値が一つだけ指定された場合(<position-one>)、 二つ目の値はcenterとなります。

2つの値が与えられた場合(<position-two>)、 先頭が<length-percentage>の場合は水平方向で、 アライメント対象の左端とアライメントコンテナの左端のオフセットを表します。 2つ目の<length-percentage>は それらの上端間の垂直オフセットを表します。

両方のキーワードがstartまたはendの場合、 一つ目がブロック軸、 二つ目がインライン軸を表します。

注: 軸固有のキーワードの組合せは順序を入れ替えることができますが、 キーワードとlength/percentageの組み合わせではできません。 center left または inline-start block-end は有効ですが、 50% left は無効です。startend は軸固有ではないので、 start endend start は異なる位置を示します。

4つの値が与えられた場合(<position-four>)、 それぞれの<length-percentage>は直前のキーワードで指定されたエッジ間のオフセットを表します。 例えば、background-position: bottom 10px right 20pxでは、 10px 分だけ下端から上向き、 20px 分だけ右端から左向きのオフセットを表します。

正の値はアライメントコンテナの端から内側へのオフセットです。 負の値はアライメントコンテナの端から外側へのオフセットです。

次の宣言は、左上隅から指定された (水平, 垂直) オフセットとなります:
background-position: left 10px top 15px;   /* 10px, 15px */
background-position: left      top     ;   /*  0px,  0px */
background-position:      10px     15px;   /* 10px, 15px */
background-position: left          15px;   /*  0px, 15px */
background-position:      10px top     ;   /* 10px,  0px */
<position>は左上隅以外の他の隅を基準とすることも可能です。 例えば、次の例は背景画像を下端から10px、右端から3emに配置します:
background-position: right 3em bottom 10px

算出値としての<position>は、 水平・垂直オフセットの組(両方共に算出された<length-percentage>値)として アライメント対象アライメントコンテナの左端・上端間の距離を表します。

<length-percentage>
<length-percentage> 値は、 アライメント対象アライメントコンテナの指定エッジ間のオフセット量を示します。

例えば background-position: 2cm 1cm では、 背景画像の左上隅が 背景配置エリアの左上隅から 右へ2cm、下へ1cm配置されます。

水平方向の<percentage>は、 (アライメントコンテナの幅 - アライメント対象の幅) に対する割合です。 垂直方向の<percentage>は (アライメントコンテナの高さ - アライメント対象の高さ) に対します。

例えば、値の組が 0% 0% だと、 アライメント対象の左上隅が アライメントコンテナの左上隅に揃います。 100% 100% の場合は、 アライメント対象の右下隅がアライメントコンテナの右下隅に対応します。 75% 50%なら、 アライメント対象の横75%・縦50%の点が アライメントコンテナにおける同じ比率の点に配置されます。
要素内での画像の位置図
background-position: 75% 50%の意味の図解
top
right
bottom
left
アライメント対象アライメントコンテナのtop/left/right/bottom各エッジを (デフォルト0%で)指定量だけオフセットします。
y-start
y-end
x-start
x-end
[=y-axis|y/x軸] における start/end側の物理エッジキーワードと同じ計算です。
block-start
block-end
inline-start
inline-end
ブロック/インライン軸における、 start/end側の物理エッジキーワードと同じ計算です。
center
対応軸で50%のオフセットに計算されます。

特に指示がない限り、フロー相対キーワードは、 値が指定された要素の書字モードにより解決されます。

注: background-positionプロパティは3値構文も受け入れます。 これはほかのlengthやpercentage成分と組み合わされたときに構文上の曖昧さを生むため一般的には禁止されています。

例:background-position のロングハンドにこの構文が どのように対応するかを定義する必要があります。例えば、いくつかのコンポーネントに var() が使われた場合。[Issue #9690]

4.2.1. <position> の構文解析

ほかのキーワード・<length><percentage>等と文法内で並んで指定されたとき、<position>グリーディにパースされ、 できるだけ多くの構成要素を消費します。

例えば、transform-originは (実質的に) <position> <length>? として3d位置を定義します。 left 50px のような値は2値の <position> としてパースされます(z成分は省略)。 一方 top 50px は、単一値の <position> の後に <length> という扱いになります。

4.2.2. <position> のシリアライズ

指定値<position>をシリアライズする際:

構成要素が1つだけの場合:
  • 暗黙の center キーワードが追加され、 2成分値としてシリアライズされます。

構成要素が2つの場合:
  • キーワードはキーワードとしてシリアライズされます。

  • <length-percentage><length-percentage>としてシリアライズされます。

  • 構成要素は「先に水平方向、次に垂直方向」の順でシリアライズされます。

構成要素が4つの場合:
  • キーワードとオフセットが両方ともシリアライズされます。

  • 構成要素は「先に水平方向、次に垂直方向」または ブロック軸インライン軸 の順でシリアライズされます。

注: <position> の値は 単一値としてシリアライズされることはありません (単一値でも同じ挙動にはなりますが)、 これは一部の文法で <position> の後に <length> が並ぶ際にパース曖昧性が生じるのを避けるためです。 例:transform-originなど。

算出値<position>は、 左端と上端からのオフセット(組となる<length-percentage>)のペアとしてシリアライズされます。

4.2.3. <position> の組み合わせ

補間は、 <position>各構成要素(x, y)ごとに 左上隅からのオフセット(<length-percentage>)として独立して行われます。

加算もまた <position>各構成要素(x, y)ごとに 左上隅からのオフセット(<length-percentage>)として独立して 加算 されます。

5. 補間進捗ファンクショナル表記

このセクションは試験的なドラフトであり、CSSWGによってまだ承認されていません。[Issue #6245]

progress()media-progress()、およびcontainer-progress() ファンクショナル表記は、指定された値(progress value)が、ある値(progress start value)から別の値(progress end value)までの 割合的な距離を表します。 これらは、それぞれ数値関数メディアフィーチャコンテナフィーチャの進捗率を共通の構文パターンで表現できます:

progress-function() = progress-function( progress value from start value to end value )

それぞれは<number>としてprogress関数の計算を行い解決されます。

progress関数の計算は、 progress valueprogress start valueprogress end valueが与えられたときに以下の手順で計算します:
progress start valueprogress end value が異なる場合

(progress value - progress start value) / (progress end value - progress start value)

progress start valueprogress end value が同じ場合

0、-∞、+∞ のいずれか。これはprogress valueが 指定値と等しい・小さい・大きいかによります。

注: 返り値は単なる <number> であり、 引数と型を自動的に整合させるものではありません。

得られた数値は、さらに他の計算、たとえば数値関数mix表記に利用できます。

5.1. 計算進捗値: progress() 表記

progress() ファンクショナル表記は、 一つの<number>値として ある計算値progress value)が 他の二つの計算値progress start valueprogress end value)の間の どこに位置するかを示します。progress()数値関数 です。

progress() の構文は次のとおりです:

<progress()> = progress(<calc-sum>, <calc-sum>, <calc-sum>)

最初、二番目、三番目の<calc-sum>値が それぞれprogress valueprogress start valueprogress end value を表します。

計算値引数は どの<number><dimension><percentage>にもなれますが、 引数の型が一致している必要があり、一致していない場合は無効です。

progress() の値は、まずprogress関数の計算で決定され、 その後引数群の一致型として型整合される<number>です。

percent-progress() のような表記が必要か、あるいは各所で自動変換されるから不要か?

注: progress()関数は、 本質的には特定のcalc()表記パターンの構文糖であり、 数値関数です。

5.2. メディアクエリ進捗値: media-progress() 表記

progress() 表記と同様に、 media-progress() ファンクショナル表記は、 指定されたメディアクエリ [MEDIAQUERIES-4] の 現在値を progress value として 明示的な2つの値(progress start valueprogress end value)間の進捗率を <number>値で返します。

media-progress() の構文は以下の通りです:

<media-progress()> = media-progress(<mf-name>, <calc-sum>, <calc-sum>)

media featureとして指定された<mf-name>の値が progress value を表し、 2つの<calc-sum>progress start value およびprogress end value です。

指定されたmedia featureは有効な「範囲型」featureでなければならず、 progress start valueprogress end value は 指定メディアクエリで有効な値である必要があります。 また2つの計算値は型が一致していなければ、関数は無効です。

progress start valueprogress end value計算値は 機能が使われる文脈ではなく、そのmedia feature 指定として解釈されます。

media-progress()の値は<number>であり、 progress関数の計算で決定されます。

注: media-progress()数値関数ではありません; これは単に<number>を返す関数です。

5.3. コンテナクエリ進捗値: container-progress() 表記

container-progress() ファンクショナル表記は media-progress()と同様ですが、 コンテナフィーチャ [CSS-CONTAIN-3]media features の代わりとして受け付ける点だけが異なります。

container-progress() の構文は次のとおりです:

<container-progress()> = container-progress(<mf-name> [ of <container-name> ]?, <calc-sum>, <calc-sum>)

<mf-name>サイズフィーチャを表し、オプションの <container-name> コンポーネントは どの名前付きコンテナで解決するかを指定します。 サイズフィーチャの値が progress value となり、 2つの <calc-sum>progress start valueprogress end value となります。

指定された<mf-name>は有効な サイズフィーチャでなければならず、 progress start valueprogress end valueも そのサイズフィーチャで有効な値でなければなりません。 また、2つの計算値の型が一致しない場合は無効です。 container-progress()は プロパティ値の文脈でのみ有効です。 例: メディアクエリ内では使えません。

progress start valueprogress end value計算値は 文脈ではなく、指定されているサイズフィーチャの定義通りに解釈されます。 適切なコンテナが見つからない場合、container-progress()<size-feature> クエリを 小さいビューポートサイズに対して解決します。

media-progress() の値は <number> であり、 progress関数の計算により算出されます。

注: container-progress()数値関数ではありません; これは単に<number>を返す関数です。

6. ミキシングと補間の表記: the *-mix() ファミリ

この機能は 複数のブレークポイントをうまく扱えない ことがあり、 再設計が必要かもしれません[Issue #6245]

CSS のいくつかの mix 表記 は、 2 つの値、 mix 開始値mix 終了値、 の間のある進行点での補間(mix 進行値)を表現できます。 これらの 関数表記 は次の構文パターンに従います:

mix-function() = mix-function( <progress>, [=mix start value|start-value=], [=mix end value|end-value=] )

CSS の mix 表記 には次のものが含まれます:

そして最後に、任意のプロパティ値の補間(ただしプロパティの個々のコンポーネントではなくプロパティの全体の値のみ)を表現できる汎用の mix() 表記があります。

注意: cross-fade() 表記には 2 つより多くの値を混ぜる代替構文もありますが、 <progress> のようなより複雑な表現は許可しません。

mix() 表記には キーフレームのセットを取るバリアントもあります。 これは @keyframes ルールを参照し、 そこから対応するプロパティ宣言を取り出すことで実現します。 他の mix 表記も keyframe を取れるようにしたいですが、 ではどのようにしてフルプロパティ値ではなく コンポーネント値 のためのキーフレーム集合を表現するかを考える必要があります。

6.1. 補間の進行を表現する: <progress>

値型 <progress>mix 進行値 を表し、 最終的にはパーセンテージに決定されます。 ただし、そのパーセンテージ値はメディアクエリやアニメーションのタイムラインなどのソースから取得でき、 補間に使用する前に イージング関数 を通して変換することもできます。

その構文は次のように定義されます:

<progress> = [ <percentage> | <number> | <'animation-timeline'> ] && [ by <easing-function> ]?

ここで:

<percentage-token>
同等の <number> に計算されます: 0%0100%1 になる、など。

注意: これは 15% のようなリテラルのパーセンテージのみを許可します; calc(100% / 7) のような計算は機能せず、代わりに通常の文脈でのパーセンテージ解決ルール(例えば <length> に対する解決)を試みます。 代わりに calc(1 / 7) のような式を使用してください。

<number>
mix 進行値 を表します。

注意: これは progress()media-progress()、 および container-progress() 表記の使用を許可します。

<'animation-timeline'>
指定された アニメーションタイムライン の進行として mix 進行値 を表します。 ただし値 noneauto は無効です。[CSS-ANIMATIONS-2] [WEB-ANIMATIONS-2]
<easing-function>
指定された入力の mix 進行値 を、指定された イージング関数 を用いて出力の mix 進行値 に変換します。 [CSS-EASING-1]

注意: 0 未満および 1 を超える進行値は有効です; これらは開始値と終了値で定義される範囲を超えた補間を表現することを可能にします。

注意: <progress> 自体は <percentage> になり得て、 同等の <number> に直接マップされますが、 解決される関数(例えば progress())は文脈の通常のルールを使って <number> を解決し、例えば width では長さに対して解決されます。

パーセンテージまたは数値で指定された 計算済み値<progress> は、 (あれば)<easing-function> を通した数値に変換された計算済みの <number> です。 計算済み値 としての <progress><'animation-timeline'> で指定されている場合は、計算済みの <'animation-timeline'> と(あれば)<easing-function> になります。

6.2. 数値および次元値の補間: calc-mix() 表記

calc-mix()mix 表記 で数値または次元の補間値を表します。 calc() と同様に、これは 数学関数 であり、 構文は次のとおりです:

<calc-mix()> = calc-mix( <progress>, <calc-sum>, <calc-sum> )

引数の <calc-sum> は、任意の <number><dimension>、または <percentage> に解決できますが、 一貫した型 を持たなければ関数は無効になります。 結果の型は 一貫した型 であり、進行値の型に合わせて整合化 されます。

有効な calc-mix()使用値 は、これら 2 つの値を <progress> によって与えられる進行に補間した結果です。 もし <progress><number> に計算できるならば、 計算済み値 も同様にこれら 2 つの計算済み値をその <progress> 値に補間した結果になります; (言い換えれば A * (1-progress) + B * progress) そうでない場合は、各引数がそれぞれの型に従って計算された状態のまま calc-mix() 表記自体になります。

6.3. 色の補間値: color-mix() 表記

この仕様は color-mix()関数表記mix 表記 として拡張し、次の構文を受け入れます:

<color-mix()> =
  color-mix( [ <progress> && <color-interpolation-method>? ] , <color>, <color> ) |
  color-mix( <color-interpolation-method>, [<color> && <percentage [0,100]>?]#{2} )

最初の mix 表記 バリアントの使用値は、 第二のバリアントにおける第二引数の <progress> 値を、 <percentage> として割り当てることと等価です。 つまり、color-mix(progress, color1, color2)color-mix(color1, color2 progress) と等価です。 第二のバリアントの規定の正規定義については CSS Color 5 § 3 Mixing Colors: the color-mix() Function を参照してください。

<progress> は 0–100% の外側のパーセンテージを返すことを許可しますが、 color-mix() はそのような値を許可しないため、 それがどのように処理されるかを定義する必要があります。

6.4. 画像の補間値: cross-fade() 表記

この仕様は cross-fade()関数表記mix 表記 として拡張し、次の構文を受け入れます:

<cross-fade()> =
  cross-fade( <progress>, [ <image> | <color> ], [ <image> | <color> ] ) |
  cross-fade( <cf-image># )

最初の mix 表記 バリアントの使用値は、 第二のバリアントにおける第二引数の <progress> 値を、 <percentage> として割り当てることと等価です。 つまり、 cross-fade(progress, image1, image2)cross-fade(image1, image2 progress) と等価です。 第二バリアントの正規定義については CSS Images 4 § 2.6 Combining images: the cross-fade() notation を参照してください。

6.5. 変形の補間値: transform-mix() 表記

transform-mix()mix 表記<transform-list> の補間を表し、 構文は次の通りです:

<transform-mix()> = transform-mix( <progress>, <transform-list>, <transform-list> )

有効な transform-mix()使用値 は、これら 2 つの値を <progress> によって与えられる進行に補間した結果です。 もし <progress><percentage> に計算でき、 かつ <transform-list> が使用値時間情報なしで補間可能であれば、 計算済み値 も同様にその <progress> 値に補間した 2 つの計算済み値の結果になります; そうでない場合は、各引数がそれぞれの型に従って計算された状態のまま transform-mix() 表記自体になります。

transform-mix() 自身は <transform-function> です。

6.6. プロパティ値の補間: mix() 表記

任意の 2 つのプロパティ値の補間mix() mix 表記 によって表現でき、 これは 2 つの代替構文パターンをサポートします:

<mix()> =
  mix( <progress> , <whole-value> , <whole-value> ) |
  mix( <progress> && of <keyframes-name> )

最初の構文代替は、他の mix 表記 と同様に、 最初の <whole-value>(その mix 開始値) と 2 番目の <whole-value>(その mix 終了値)の間を補間します。 2 番目のものは mix 進行値 を使って keyframes のセットから対応するプロパティ宣言を補間し、より複雑な補間曲線を可能にします。

標準の mix 表記 バリアントについて、 もし mix() によって補間される 2 つの <whole-value> がそのプロパティの値として 補間可能 であり、かつ補間された値が mix() を使わずに表現できるならば、 mix()計算済み値 はこれら 2 つの値を <progress> によって与えられた進行に補間した結果になります。 それ以外の場合、mix()計算済み値 は、mix()関数表記 自体であり、 その <progress> 値が計算され、 (提供されていれば)その <whole-value> がこのプロパティの値として計算されます。

例えば、mix() のほとんどの使用は計算済み値時に解決されます:
color: mix(90%, red, blue);
/* 単純な補間を経て計算される: */
color: rgb(10% 0 90%);

color: mix(90%, currentcolor, black);
/* 計算済み値時に完全には解決できないが、定義された表現は持つ: */
color: color-mix(currentcolor 90%, black 10%);

float: mix(90%, left, right);
/* 離散的にアニメーション可能 */
float: right;

しかし、いくつかのケースは中間表現を持ちません:

transform: mix(90%, translate(calc(1em + 50%)), rotate(30deg));
/* 関数が一致しないため matrix() を介して補間されます。
   しかし translate(%) は matrix() に変換するためにレイアウト情報を必要とするので、
   補間された値は実際には表現できません。
   計算結果: */
transform: mix(90%, translate(calc(16px + 50%)), rotate(30deg));
transform: mix(90% of ripple);

mix() 表記は <whole-value> です。 さらに、その <whole-value> 引数のいずれかが アニメーション不可 の場合、 その表記は無効になります。

例えば、次の宣言は無効で無視されます:
/* 無効な開始値 */
color: mix(90%, #invalid, #F00);

/* 関数が他の値と混在している */
background: url(ocean) mix(10%, blue, yellow);

/* 'animation-*' はアニメーション不可 */
animation-delay: mix(0%, 0s, 2s);

7. その他の値置換関数

7.1. プロパティ全体の値の表現: <whole-value>

この仕様で定義されたいくつかの関数は、 プロパティの「全体の値」としてのみ使用できます。 例えば、background-position: toggle(50px 50px, center); は有効ですが、 background-position: toggle(50px, center) 50px; は無効です。 <whole-value> 生成規則はこれらの値を表します。

すべてのプロパティは暗黙に <whole-value> を値全体として受け入れます。 これは、CSS全域キーワード をプロパティの値全体として受け入れるのと同様です。

関数の構成要素値として使われる場合、<whole-value> は そのプロパティの「全体の値」として通常有効な任意のCSS値(追加の <whole-value> 関数を含む)も表します。 ただし、一部の関数では <whole-value> 引数に含めることができるものを制限する場合があります。

7.2. 最初にサポートされる値の選択: first-valid() 表記

CSSは前方互換のパースによる段階的拡張をサポートしています。 作者はスタイル規則内で同じプロパティを複数回宣言できます。 それぞれ異なる値を使って記述し、 CSS UAは自動的に最後に理解できるものを使い、それ以外を無視します。 この原則と @supports 規則を組み合わせることで、 古いUAと新しいUAの両方でうまく動作するスタイルシートを記述できます。

しかし、var()(やパース後に解決される類似の置換関数)を使うと この機能が妨げられます。 CSS UAはそのようなプロパティをパース時点で有効だとみなさなければなりません。

first-valid() 関数表記は 宣言のパースに内在するフォールバック動作をインライン化します。 ほとんどの表記とは異なり、 引数に任意の有効・無効な構文を受け入れることができ、 その引数のうちUAがそのプロパティの値全体としてサポートする(有効とみなす)最初の値を代表します。

<first-valid()> = first-valid( <declaration-value># )

いずれの引数もそのプロパティの有効な値を表さない場合、 そのプロパティは計算値時に無効になります。

first-valid()<whole-value> です。

この名前で良いでしょうか? 追加を決議した際に十分に決まらなかったため、再検討の余地があります。

注: 実質的に <whole-value> を引数として取るように見えますが、 first-valid() は代わりに <declaration-value> を取ると定義されています。 なぜなら本質的に その値が宣言内で無効になるかもしれない場合に使うことが意図されているためです。 <declaration-value><whole-value> とは異なり、文脈上の有効性制約を課しません。

7.3. 条件付き値選択: if() 表記

if() 表記は 条件付き値を表現する任意置換関数です。 引数は順序付けされたセミコロン区切りの文のリストであり、 各文は条件に続けてコロン、さらに値が続く形です。 if() 表記は、 引数リスト内で最初に条件が true となったものに対応する値を表します。 一致する条件がない場合、 if() 表記は空のトークンストリームを表します。

if() 表記の構文は次の通りです:

<if()> = if( [ <if-condition> : <declaration-value>? ; ]*
             <if-condition> : <declaration-value>? ;? )
<if-condition> = <boolean-expr[ <if-test> ]> | else
<if-test> =
  supports( [ <supports-condition> | <ident> : <declaration-value> ] ) |
  media( <media-query> ) |
  style( <style-query> )

else キーワードは 常にtrueとなる条件を表します。

if()関数を解決するには、 最初にtrueとなる <declaration-value>? に対応する値を返します。 いずれもtrueでなければ 何も返さず(空のトークンストリーム)とします。

注: @media@supports@container 規則のように 偽の場合に中身を無視し、カスケードによって適用値が決まるのとは違い、 if() を使った宣言では 条件が偽の場合もカスケードがロールバックされません。 フォールバック値はインラインで与える必要があります。

7.4. 値の切り替え: toggle() 表記

toggle() 式は 子孫要素が同じ値を継承する代わりに 値リストを循環して利用することを可能にします。

次の例では <em> 要素を通常は斜体に、 しかし斜体内では通常体に切り替えています:
em { font-style: toggle(italic, normal); }
次の例は入れ子リストのマーカーを循環させます。 最上位リストは disc 型のマーカー、 入れ子リストは circle、 さらに squareboxと切り替え、 それ以降はまた disc から繰り返します。
ul { list-style-type: toggle(disc, circle, square, box); }

toggle() 式の構文は次の通りです:

<toggle()> = toggle( <whole-value># )

toggle() 表記は <whole-value> です。 ただし入れ子にすることはできません。 また attr()calc() 表記は含めてはいけません。 これらを含む宣言は無効となります。

以下の toggle() の例はいずれも無効です:
background-position: 10px toggle(50px, 100px);
/* toggle() はプロパティ唯一の値でなければならない */

list-style-type: toggle(disc, 50px);
/* 50px は 'list-style-type' の有効な値ではない */

toggle() の計算値を求めるためには、 まず toggle() が置かれるプロパティの唯一値だったと仮定し各引数の計算値を評価します。 これを toggle()n 番目の引数について Cn とします。 そしてプロパティの継承値と各 Cn を比較します。 継承値と一致した最初の Cn について、 toggle() の計算値は Cn+1 となります。 一致が最後の引数または一致がなかった場合は toggle() の計算値は最初の引数の計算値となります。

注: toggle() 内で値が重複するとリストがその時点で打ち切られます。 例えば toggle(1em, 2em, 1em, 4em) は実質的に toggle(1em, 2em) と等価です。

注: toggle() は明示的に親の計算値を見ているため、 非継承プロパティでも動作します。 これは inherit キーワードと似ています。

注: プロパティの計算値は 特定のシリアライズではなく抽象的な値集合であるため、 計算値同士の比較は常に曖昧さなく意図通りの結果となります。 例えばLevel 2のbackground-positionの計算値は それぞれ絶対長もしくはパーセントとして表される2つのオフセットなので、 background-position: top centerbackground-position: 50% 0% は同じ計算値になります。 定義中の "Computed Value" 行が曖昧または厳しすぎると感じた場合は フィードバック をお願いします。

toggle()ショートハンドプロパティ に使うときは、 各ロングハンドに、 元の toggle() の各引数を そのロングハンド単体の値として受け取ったときに対応する引数で toggle() 値を設定します。

例えば次のショートハンド宣言:
margin: toggle(1px 2px, 4px, 1px 5px 4px);

は以下のロングハンド宣言と等価です:

margin-top:    toggle(1px, 4px, 1px);
margin-right:  toggle(2px, 4px, 5px);
margin-bottom: toggle(1px, 4px, 4px);
margin-left:   toggle(2px, 4px, 5px);

ここで、上マージンには 1px が2回、下マージンには 4px が2回出てくるため、それらは2値間だけで循環します。 一方左右マージンは3値で循環します。 つまり上の宣言は以下のロングハンド宣言と同じ計算値になります:

margin-top:    toggle(1px, 4px);
margin-right:  toggle(2px, 4px, 5px);
margin-bottom: toggle(1px, 4px);
margin-left:   toggle(2px, 4px, 5px);

これは意図通りでない場合があります。

7.5. カスタムプロパティ参照: var() 表記

var() 表記は カスタムプロパティ の値を代入します。 詳細は CSSカスタムプロパティの仕様 を参照。 [CSS-VARIABLES]

7.6. 継承値参照: inherit() 表記

inherit キーワードと同様に、inherit() 関数表記は親のプロパティの計算値として解決します。 ただし同じプロパティの値としてではなく、 第一引数で指定されたプロパティの トークナイズされた計算値として解決します。 第二引数があれば 第一引数が保証無効値となった場合のフォールバック値として使われます。

inherit()任意置換関数であり、その構文は:

<inherit()> = inherit( <custom-property-name>, <declaration-value>? )

inherit()関数を解決するには、 第一引数で指定されたカスタムプロパティ継承値および (指定があれば)第二引数で指定されたフォールバック値を返します。

注: 将来のCSSでは inherit() で標準プロパティを指定できるようになるかもしれません。 ですが計算値のトークナイズは すべてのプロパティでまだ標準化されていないため、 この機能はLevel 5では見送られます。 計算値使用値と異なり、getComputedStyle() の戻り値とも限りません。 そのため仮にinherit(width) が許可された場合も たいていは auto というキーワードとなり、 使用 <length> とはなりません。

7.7. 属性参照: attr() 表記

attr() 関数は、 属性 の値を要素 から プロパティへ代入します。 これは var() 関数が カスタムプロパティを関数で差し込むのと似ています。

attr() = attr( <attr-name> <syntax>? , <declaration-value>?)

<attr-name> = [ <ident-token> '|' ]? <ident-token>

attr() の引数は以下の通りです:

<attr-name>

参照する属性名です。 <wq-name>[SELECTORS-3] より)に似ていますがワイルドカード接頭辞はありません。

名前空間が指定されていなければ(attr(foo)のように識別子だけなら)null名前空間とみなされます。 (これが通常望ましい動作です。 名前空間属性が使われることは稀です。 特にHTMLやSVGでは名前空間属性はありません。) 属性セレクターと同様に、 <attr-name> の大文字小文字の区別は文書言語によります。

attr()が 要素に適用されたプロパティに使用されている場合、 その要素上の同名属性を参照します。 疑似要素に適用されていれば、 疑似要素の生成元要素の属性を参照します。

<syntax>

この属性値をどのようにCSS値としてパース するかを指定します。 この構文に従ってパースに失敗した値は フォールバックを引き起こします。

<syntax> 引数を省略した場合 属性のリテラル値は CSS文字列値としてそのまま扱われ、CSSパース(エスケープ、空白削除、コメントなど)を行いません。

注: これは * を構文に指定する場合と異なり、 その場合はCSSパース自体は行われ(妥当なパースがされればよい)、 パース結果がそのまま挿入され、 <string>値としては扱われません。

<declaration-value>

attr()のフォールバック値です。 属性が無い、または指定型として正しくパースできなかった場合に 属性値の代わりに利用されます。

<syntax> 引数が省略された場合 フォールバックを省略すると空文字列がデフォルト、 それ以外は指定がなければ保証無効値がデフォルトとなります。

プロパティに1つ以上の attr() 関数があり、 その構文が妥当であれば プロパティ全体の文法はパース時に有効だとみなさなければなりません。 計算値時にのみ構文チェックされ、 その時点で attr() 関数が置換された後に検証されます。

フォールバック値は必ずしも指定型に従う必要はありません。 例えば型が <number px>とされた場合でも、デフォルト値としてauto などを指定できます。 例:width: attr(size <number px>, auto);
この例はattr()を使い XMLファイル内のデータを視覚的に示します:
<stock>
  <wood length="12"/>
  <wood length="5"/>
  <metal length="19"/>
  <wood length="4"/>
</stock>

stock::before {
  display: block;
  content: "To scale, the lengths of materials in stock are:";
}
stock > * {
  display: block;
  width: attr(length <number em>, 0px);
  height: 1em;
  border: solid thin;
  margin: 0.5em;
}
wood {
  background: orange url(wood.png);
}
metal {
  background: silver url(metal.png);
}

7.7.1. 属性値の置換: attr() 表記

attr()任意置換関数であり、var() と類似しています。 そのため 計算値(computed value)のタイミングで(可能であれば)代表する値に置き換えられます。 そうでない場合は 保証無効値に置き換えられ、 その宣言は計算値時に無効になります。

attr()関数を解決するには:
  1. el を、attr() 関数を含むスタイルが適用されている要素とする。 attr name を関数で指定された属性名とする。 syntax を、関数で指定された <syntax> とし、省略時は null。 fallback を、関数で指定された <declaration-value>? 引数とし、 省略時は 保証無効値 とする。

  2. elattr name という属性がない場合は、 保証無効値fallback を返す。 それ以外の場合は attr value をその属性値とする。

  3. syntax が null であれば、 attr value を値とするCSSの <string> を返す。

    注: どのようなパースや修飾も一切行われません。

  4. <syntax>でパースし、 attr valuesyntaxel を用いる。 結果と fallback を返す。

7.7.2. セキュリティ

attr() 関数は ページ作成者が本来スタイリング用途を想定していない属性も参照することができ、 機密情報(たとえばページ内スクリプト向けのセキュリティトークン)を含む可能性があります。

通常は問題ありません。 多くの場合、attr() でページの情報を外部に抜き出して悪意のある第三者へ送信するのは困難です。 ただし例外はURLです。 任意属性値でURLがCSSだけで構成できてしまうと、 属性に有る情報を簡単に外部に送信できてしまいます。 特にサードパーティCSSが許可されている場合は危険です。

これを防ぐため、 attr() で得られる値は attr()-汚染(taint) とみなされます。 これは attr()-tainted 値を持つ関数も同様です。登録カスタムプロパティattr() を含む場合も、 attr()-taintattr()-tainted 値に持ち続けます。 var() の置換時も同じです。

attr()-tainted な値を <url> として使ったり、含めたりすると、その宣言は計算値時に無効になります。

例えば、次のようなすべては無効です:

ただし、attr() を他の用途で使う分には、 たとえ urlに近い場所で使われていても 問題ありません:

注: この制限の実装には attr() 由来の値に「ダーティビット」を持たせて追跡する必要があります。 というのもこうした値は登録カスタムプロパティ経由で完全な文字列になりうるからで、 単純に値式を調べるだけでは不十分です。 また、string()のように他型値を文字列化する関数経由でも 非文字列型でこの挙動を引き起こす場合があります: --foo: attr(foo number); background-image: src(string(var(--foo))) も無効にすべきです。

8. ランダム値の生成

デザインにある程度の「ランダム性」を持たせるのは頻繁に有用です。 たとえばページ上の繰り返し要素を均質・静的に見せないためや、 さりげない変化・アクセントを加えたいときに役立ちます。

random() および random-item() 関数 (ランダム関数) により、作者はページ内に乱択性を組み込めます。 このときデザイン上の予測可能性は保ちつつ、 乱択値を複数箇所で再利用するかインスタンスごとに個別にするかを、作者が選択できます。

ランダム数の生成手法はUA依存です。 2つの乱数値間で何らかの相関が簡単に検出できないべきですが、 この仕様ではその暗号学的強度などはあえて規定していません。 作者は ランダム関数 を セキュリティ上の品質に依存する用途には絶対に使うべきではありません。

8.1. ランダムな数値の生成: random() 関数

random() 関数は 数学関数で、指定した最小値・最大値の範囲から 一様分布に従い乱数値を生成します。 また、その値を指定ステップ単位に絞り込むこともできます:

<random()> = random( <random-caching-options>? , <calc-sum>, <calc-sum>, [by <calc-sum>]? )

<random-caching-options> = <dashed-ident> || per-element

引数:

<random-caching-options>

省略可能な <random-caching-options> は その random() 関数が ページ内他の random() と同様に解決されるかどうかを制御します。 詳細は § 8.3 ランダム値の生成/キャッシュ: <random-caching-options>値 を参照。

デフォルトでは random() は単一の値に解決し、 そのスタイルを使う全要素で共有され、 引数が同じ2つの random() 関数は 同じ乱数値に解決されます。

<dashed-ident> を指定しても意味はありませんが、 ほかが同じ random() を 異なる引数リストにして 別の乱数値を出したい場合に使えます。

per-element キーワードは その random() を 「適用先の各要素ごとに」異なる値とするのに使います(スタイルシート内で使われた回数ごとではない)。

<calc-sum>, <calc-sum>

2つの必須計算は、関数が取りうる最小値と最大値を指定します。 双方の端値は含まれます(すなわち min/max そのものも結果になりうる)。

最大値が最小値未満の場合は、最小値と同じものとして扱います。

例: random(100px, 300px)<length> の範囲で 100px300px のランダム値となります。 100px300px234.5px のような間の値もあり得ます。
by <calc-sum>

最後の省略可能引数はステップ値を指定し、 関数が取りうる値は min + (N * step) 形式になります。 ここでNは0以上の整数で、範囲内に収まる値のうち等確率で選ばれます。

例: random(100px, 300px, by 50px)100px, 150px, 200px, 250px, 300px のいずれかだけになります。 120px などは絶対出ません。

最小値は常に結果の候補ですが、 最大値は、minからのstepの倍数でなければ候補から除外されます。 たとえば random(100px, 300px, by 30px) では 最大候補値は 280px となります(minから6step)。

丸めの精度問題もあります。 random(100px, 200px, by 100px / 3) は確かに値が3通り (100px、(約)133.33px166.67px) ですが 200px も得られるかは丸め次第。 安全にstepの倍数になるようmaxをちょっと大きめ指定しましょう(例:random(100px, 201px, by 100px / 3))。

round()の定義どおり、 CSSの値には「自然な」精度単位はありませんが、 ステップ値を指定することでそのような精度を与えることもできます。

例: random(100px, 500px, by 1px) なら1ピクセルごとのみ値を取ります。 random(1, 10, by 1) なら整数値のみなど。

注: ステップ値の意味付けは 単に範囲内の値を得て丸める……という生成手順は許しません。 それだと出現確率が端値と中間で偏る恐れがあるからです。 たとえば random(100px, 200px, by 50px) なら3種それぞれ1/3だが、 よくある丸め法だと 150px が2倍頻度になります。

すべての計算引数は、任意の<number><dimension><percentage> のいずれでもよいですが、 すべて同じでなければならず、そうでなければ無効です。 結果値も同じ型となります。

例: random(50px, 100%, by 1em) は有効です (その文脈でパーセントが有効で長さ型に解決されると仮定)。 3引数とも長さ型となるためです。

ただし random(50px, 180deg) は無効です。 長さ型と角度型は異なるためです。

random() 関数は、その引数が数値に単純化できた時点で単純化できます。

注: 通常random()計算値時に解決され、 静的な数値として継承されます。 ただし、引数の計算使用値時まで解決できない(例えばパーセント型等でレイアウト情報が必要な場合)は、 継承random() 関数自体が継承されます。 (ただしこれはパーセント型自身も同様の振る舞いなので違いはありません。継承時は <percentage> として受け継がれ、 子要素で異なる値になることもありえます。)

少なくとも理論上は per-element を指定しなければ random() をプロパティ外で使っても問題ないはずです。 例えば@media (max-width: random(100px, 500px)) {...} など。だが禁止したほうがよいかも?

8.1.1. 引数の範囲

random(A, B, by C) において、 AまたはBが無限大の場合、 結果はNaNとなります。 Cが無限大の場合、 結果はAとなります。

(Cがゼロまたは負の場合、 結果はAとなりますが、これは標準定義から自明です。)

注: 数学関数全般の慣例として、 任意の引数計算がNaNであれば、 結果もNaNです。

8.2. リストからランダムな項目を選ぶ: random-item() 関数

random-item() 関数は 引数リストの中から ランダムに1項目を解決します。

<random-item()> = random-item( <random-caching-options> , [ <declaration-value>? ]# )

必須の <random-caching-options>random() と全く同じ意味で解釈されます。 (詳細は § 8.3 ランダム値の生成/キャッシュ: <random-caching-options>値 を参照。)

random() と同様に、 <dashed-ident> を用いれば類似の random-item() 関数群に 異なる乱数値を出力させられますし、 per-element で各要素ごとに別個の値を得られます。

これ以外は、 random-item() 関数同士の「同一判定」基準はかなり単純で、 引数数しか関与しません。

つまり、random-item(--x, red, blue, green)random-item(--x, 1, 2, 3) は常に同じ添字で解決されます: すなわち red1、または blue2、またはgreen3 となります。 これにより複数プロパティでランダムセット値が同期できます。

逆に random-item(--x, red, blue, green)random-item(--x, 1, 2, 3, 4) とは何の関連もなく、 12通りどれでも生じます。

注: <random-caching-options> 引数は random-item() では必須ですが、random() では省略可能です。 これはパース上の都合 (たとえば random-item(--foo, --bar, --baz)<declaration-value> 3個なのか 2個+<random-caching-options> か区別できない)や、 random-item() は引数数のみで区別されるため 意図せずランダム生成が結びつくリスクが高いからです。

残りの引数は任意個のCSS値列です。 random-item() 関数はこれらのうちどれか1つに一様ランダムで解決します。

random-item() 関数は 任意置換関数であり、 var() のような性質を持ちます。

つまり random-item() を使う場合:

任意置換関数について、Variables節に定義を追加する必要がある(今後も同機能を持つ関数が増えるため)。

random-item() は var()的な性格なので、 プロパティでしか使えないように制限した方が良いかもしれません。 (こうした関数全てにその制限を課した方がよいでしょう。) ただし random() は本質的に異なる値型ですが、 一貫性のためこちらも制限すべきかもしれません。

8.3. ランダム値の生成・キャッシュ: <random-caching-options>

JavaScriptのようなプログラミング言語では コードには明確な時間順序があり、 Math.random() の呼び出しがいつ評価されるかはっきり分かります。 結果を変数に保存すれば、複数箇所で同じ乱数値を再利用しているのか、場所ごとに違う値を出しているのかも明確です。

一方CSSは宣言型言語であり (コードが特定の順序で「実行」されたり、「実行」回数が制御できたりしません)、 複数要素に同じスタイルを適用するのは容易ですが 全部別の値にしたい場合指定が困難です (random() で全要素同じ値/各要素で異なる値にしたいかが明示しづらい)。 変数機能もとても限定的で (特定生成乱数を複数箇所明示再利用が難しい)。

これらの課題を解消するため random() および random-item() 関数では乱数値生成時に以下のキャッシュ動作を定めます:

「要素または疑似要素ごとの固有値」は、JavaScript参照の生存期間(あるいは生成元要素+疑似要素特定情報)の間保たれるべきです。 異なる文書中の要素(同じページのリロードも新規文書)では異なる値になるべきです。 (厳密な唯一性は必須ではなく疑似乱数で構わないが、異なるドキュメント間で同じ値になることに 作者は依存できない設計にすべきです。)

また、乱数生成は異なる文書で呼び出せば違う値になるべきです (リロード含む)。

例えば次のスタイルシートでは:
.random-square {
  width: random(100px, 500px);
  height: random(100px, 500px);
}

両関数のランダムキャッシュキーは同じで、 (100px, 500px, null, null, null) です。 よってwidthとheightは完全に同じ値になり、要素は正方形になります(100~500px内)。 かつ、ての .random-square 要素もこの同じサイズになります。

一方、以下だと:

.random-rect {
  width: random(100px, 500px);
  height: random(--x, 100px, 500px);
}

2関数のランダムキャッシュキーは異なり、 width 側は (100px, 500px, null, null, null)、 height 側は (100px, 500px, null, --x, null) です。

よって両者は違う値になるため、正方形になることはまずありません。 ただし .random-rect の各要素は全て同じ乱数幅・高さになります。

関数の内容を少しでも変えるとキーも変化し、2つは完全に無関係になります:

.random-rect-2 {
  width: random(100px, 500px);
  height: random(100px, 500px, by 50px);
}

しかし使用値が同じ結果になる場合 見かけ上異なっても同じになることがあります。 次の場合:

.random-square-2 {
  font-size: 16px;
  width: random(160px, 320px);
  height: random(10em, 20em);
}

一見全く別の関数ですが、長さ解決後は同じランダムキャッシュキーとなり (160px, 320px, null, null, null) となるので widthとheightは必ず同じ値になります。

デフォルトでは、スタイルシート内の各 random() インスタンスは 実質的に静的値に解決され、 そのプロパティが適用されている全要素で共有されます。 この動作は per-element キーワードで変えられます。

例:

.foo { width: random(100px, 500px); }

.foo の複数要素は同じ乱数幅になる。

しかし次の例では:

.foo { width: random(per-element, 100px, 500px); }

.foo 要素は固有の幅になる。

この場合、値の固有性は「要素ごと」であり 値ごと ではありません。 例えば:

.random-squares {
  width: random(per-element, 100px, 500px);
  height: random(per-element, 100px, 500px);
}

.random-squares の各要素はそれぞれ異なる乱数値となるが その要素に限れば widthheight は同値となり、正方形になる。 これは両プロパティとも ランダムキャッシュキー(100px, 500px, null, null, [要素固有値]) だからです。

この性質により、カスタムプロパティの random値が予測しやすくなります。 先のコードは次のようにも書けます:

.foo {
  --size: random(per-element, 100px, 500px);
  width: var(--size);
  height: var(--size);
}

9. ツリー要素カウント関数: sibling-count() および sibling-index() 表記

sibling-count() 関数表記は、 それが使われた要素の親に含まれる子要素の総数を <integer> として表します。

sibling-index() 関数表記は、 それが使われた本人要素が 親の子どもの中で何番目かを <integer> として表します。 :nth-child() と同様、sibling-index() も1始まりインデックスです。

注: counter() 関数も sibling-index() 相当の機能が得られますが、 こちらは <string> として返るのに対し、sibling-indexは <integer> です。

疑似要素上で使った場合も、 それが指定された 究極生成元要素に対して評価されます。

注: CSS(セレクターを除く全体)と同じく、 sibling-count()sibling-index()フラットツリー に作用します。

注: これらの関数は将来、 of <selector> の引数(:nth-child()と同様) で子集合をフィルタできるよう拡張されるかもしれません。

10. 内在サイズを使った計算: calc-size() 関数

2つの確定サイズ間の遷移や、 既存の確定サイズを少しだけ調整したい場合、calc()はとても便利です。 例えば 100%20px の中間は calc(50% + 10px)20% 両側に 15px の余白を加えたいときは calc(20% + 15px * 2) など。

しかし、調整対象や遷移先が内在サイズの場合、実用上や後方互換性の理由により この操作はできません。 calc-size() 関数は 安全かつ明確に内在サイズに対して算術演算を可能にします。

<calc-size()> = calc-size( <calc-size-basis>, <calc-sum> )

<calc-size-basis> = [ <intrinsic-size-keyword> | <calc-size()> | any | <calc-sum> ]

<intrinsic-size-keyword> 生成規則は、 文脈で許可されている内在サイズキーワードにマッチします。 例えば width では、 automin-contentstretch など。

なぜ calc-size() は入れ子にできるのか?

引数 basis に calc-size() 自体が許されていることで、 変数などをベースとして利用でき(例: calc-size(var(--foo), size + 20px))、 その変数が元々プロパティに合法なら必ず動きます

同じことを calc() だけでやろうとしても うまくいきません。 例: --foo: calc-size(min-content, size + 20px) や、--foo: min-content に対し calc( (var(--foo)) + 20px ) は失敗します。

内包は補間時や使用値時に簡約化され、 ベースは最終的に単純な値になります。 詳細は § 10.1 calc-size() の簡約化 を参照。

第1引数はcalc-size ベース、 第2引数はcalc-size 計算 です。 いずれに <calc-sum> を指定する場合、 その型一致し、 <length-percentage>でなければならず、 実際に<length>に解決できなければなりません。

calc-size 計算内では、 calc-size ベースany でなければ キーワード size が許されます。 このキーワードは <length> であり、使用値時に解決されます。

calc-size()内在サイズ です。 これは特に長さではありませんcalc-size()を受け入れるには必ず文法に明記が必要です。

なぜ calc() で内在キーワードを直接許可しないのか?

理論上は calc-size() の代わりに calc(auto * .5) などを有効にすれば補間が普通に働くようにできます。

ただし、このやり方では異なるキーワードの混合が依然不可になるうえ それが見た目に分かりづらくなります (例えば calc((min-content + max-content)/2) は自然に見えるが実は許されない)。

より重要なのは、通常パーセント値のスムーズな遷移ができなくなるという点です。 calc(50%)calc(100%) の半分になるのはパーセントが確定なときのみで、 それ以外だと通常は同じサイズ(たとえば 0pxauto になる)。

計算対象のサイズと計算式を分離した新関数にすることで 全てのケースでなめらかな補間が可能となります。

もう一つの理由は、「内在サイズであるか」の有無で多くの挙動(小さいものから大きなものまで)が決まる点です。 calc() で補間する場合 例えば calc(min-content * .2 + 20px * .8) では途中「内在」で、 補間完了時 calc(20px) では「確定」になり、 レイアウトが途中で飛ぶ原因になります。

(これは opacity:1 から opacity: 0へ遷移するとスタッキングコンテキストも変化し得る例と同じです。 opacity なら .999 へ遷移すれば見た目上同じで回避可能ですが、 calc用に calc(auto * .0001) を書けとは現実的でありません。)

繰り返しますが、「内在サイズ」特性を明示する calc-size(auto, 20px) のような新関数を設けることで、 実際の値が確定長さとなっても全区間安定したレイアウトを維持できます。

10.1. calc-size() の簡約化

数学関数と同様に 指定値および計算値時に calc-size 計算(必要なら calc-size ベース も)は 可能な限り簡約化されます(CSS Values 4 § 10.10.1 簡約化)。

補間用正規化calc-size() 関数に対して行うには:
calc-size ベースcalc-size() 関数自身である場合

外側関数の calc-size ベース を内側関数のそれに置き換え、 内側関数の calc-size 計算 を外側関数の calc-size 計算代入する。

それ以外で、calc-size ベース<calc-sum> でかつ長さに一致し(パーセントを含まない場合)

ベースを any に置き換え、 元のベースをcalc-size 計算へ代入する。

さらにそれ以外の場合で、calc-size ベースがパーセントを含む他の <calc-sum> である場合

ベースを 100% に置き換え、元のベースをパーセント解除し、 calc-size 計算に代入する。

(必要ならこれらを再帰的に行う。)

calc-size 計算への代入で失敗となったら 全体ですぐに失敗を返す。

注: この正規化後は calc-size()calc-size ベース は キーワードまたは 100% だけになります。

パーセントをこう簡約化する理由

この処理で遷移時に線形挙動が保証されます。

たとえば 100% を100pxとするとします。

`calc-size(100px, size * 2)`(=200px)から `calc-size(50%, size - 20px)`(=30px) へ引数両方を補間すると 中間点で `calc-size(75px, size * 2 * .5 + (size - 20px) * .5)`(=102.5px) で、これは30と200の中間(115px)にはなりません。 一つを補間して別計算に代入、その補間……だと一般に二次的挙動となります。

この案ではベースを計算式に代入することで `calc-size(percentage, 100px * 2)` `calc-size(percentage, (size * .5) - 20px)` として補間すると 中間点で `calc-size(percentage, 100px * 2 * .5 + ((size * .5) - 20px) * .5)` となり、期待通り115pxになります。 他の遷移点も同様に線形です。

パーセント解除(de-percentify a calc-size calculation) calc を行うには:
  1. calc 内の <percentage-token> をすべて (size * N) に置換する。 ここで N はパーセント値 ÷ 100 です。 calc を返します。

注: 例えば 50% + 20px(size * .5) + 20px となります。

calc-size 計算への代入 calc に値 insertion value を代入するには:
  1. calcsizeキーワードがなければ何もしない。

  2. あれば、calc中のsize全てを insertion value(括弧付き)に置換する。

  3. もしこの置換でUA定義の上限を超えた値になるなら失敗を返す。

    注: この保護は 変数置換時の挙動に合わせたもので、 CSS Variables 1 § 3.3 長い変数の安全な扱いを参照。 ただし calc-size() 値でここまで長いケースは少なく、 UAはより小さい上限を設けてよい。

10.2. calc-size() の解決

calc-size() は、 あらゆる面でそのcalc-size ベース (ただしanyは未指定の確定サイズ扱い)と同一視されます。

ただしレイアウト計算実行時は、 calc-size ベースで表されるサイズが calc-size 計算 の値へ変更され、 size キーワードは 元の ベースのサイズとして評価されます。

(ベースが any なら calc-size()確定長さとなり、 その calc-size 計算 の値と等しい。)

たとえば、 height: calc-size(auto, round(up, size, 20px)) だと height: auto と同じ扱いですが 実際のサイズが20px単位に切り上げられる効果が出ます。

calc-size 計算を評価するとき、 パーセントがその文脈で確定でなければ 0pxとなります。 確定なら通常通り解決されます。

calc-size ベース のパーセントは別処理で、簡約化によって 計算引数側に移動し size 参照に置き換えられます。 ベースは 100% となり、これはその文脈における通常の 100% 振る舞い (auto 振る舞い など)をします。)

ベース内のパーセントは通常通り機能するため、 どのような値・挙動の値にも常にスムーズに補間できます。 たとえば calc-size() なしに 100% から 0px への遷移は パーセントが確定 な場合のみスムーズで、 不確定時は遷移中ずっと auto 振る舞い になりサイズが変わりません。

一方calc-sizeの計算式引数内のパーセントは、不定の場合0に解決され calc-size() の挙動が2通りになるのを避けています。 例えば min-content サイズと 100% サイズで レイアウト挙動が異なるケースもあるため、 calc-size() は どちらか一方として振る舞う必要があります。

10.3. calc-size() の補間

2つの calc-size() 関数は (補間用正規化後)以下の場合に補間できます:

どちらかの関数が 補間用正規化 で失敗を返した場合

補間はできません。

両方の ベースが同じ場合

結果の ベース も同じ値にする。

どちらかの ベースany の場合

結果の ベース は any でない方のベースを使う。

結果の calc-size 計算 は、入力両方の 計算 を補間したものです。

注: これらの補間制約で calc-size() が 同時に2つの異なる動作をしないよう保証されます。 たとえば min-contentmax-content では 違うレイアウト挙動になるため calc-size() はいずれかを装う必要があります。 そのためキーワード間遷移(automin-content など)はできません。

一部の calc-size() 値は、 <length-percentage><intrinsic-size-keyword> とも補間できます。 補間できるか・その挙動は次のように判断します: 非 calc-size()値が <calc-sum> の場合 calc-size(any, value ) とみなし、 それ以外は calc-size(value, size) として上記ルールを当てます。

たとえば calc-size() を使えば height: auto もスムーズに補間できます:
details {
  transition: height 1s;
}
details::details-content {
  display: block;
}
details[open]::details-content {
  height: auto;
}
details:not([open])::details-content {
  height: calc-size(any, 0px);
}

これは実質的に calc-size(auto, size)calc-size(any, 0px) を補間します。 details 要素をopen後0.5秒で ::details-content ラッパーの heightcalc-size(auto, size * .5) となり開いた時の半分の高さになり、 遷移中なめらかに高さがアニメーションします。

注: calc-size()calc-size(any, 確定 長さ) への任意遷移も必ずスムーズに動くよう設計されています。

注: 「通常値を calc-size() にアップグレードする」動作で <length-percentage> 値は calc-size 計算 に入ります。 よってパーセント入り値も 内在キーワードと補間できますが、 パーセントが確定 でないと 0に解決されてしまいます。 実際のサイズの割合で取りたい場合は calc-size(50%, size) のように明示指定してください。

10.4. サイズキーワードの補間: interpolate-size プロパティ

注: もしタイムマシンがあれば、このプロパティは必要ありませんでした。 このプロパティは、多くの既存スタイルシートが 内在サイズキーワード (automin-content など)が アニメーションできないという想定をしているために存在します。 そのため、スタイルシートが期待通りの挙動を選択できるようにこのプロパティを設けています。 ルート要素へ interpolate-size: allow-keywords を指定すると、 ページ全体に対し新しい挙動を選択できます。 互換性の心配がなければ、常にこの指定を推奨します。

名前: interpolate-size
値: numeric-only | allow-keywords
初期値: numeric-only
適用対象: すべての要素
継承: yes
パーセント: 該当なし
計算値: 指定通り
正規順序: 構文通り
アニメーション型: アニメーション不可
numeric-only
<intrinsic-size-keyword> は補間できません。
allow-keywords
2つの値のうちどちらかが <intrinsic-size-keyword> で、 もう一方が <length-percentage> なら補間できます。 この場合、 <intrinsic-size-keyword> keywordcalc-size(keyword, size) と見なして § 10.3 calc-size() の補間のルールを適用します。 その他の場合には <intrinsic-size-keyword> は補間できません。

interpolate-size の値で重要なのは アニメーションが始まる可能性のある時点での要素の計算値です。 CSSトランジションの場合は 変化後スタイルでの値となります。 その後で interpolate-size が変わっても アニメーションは途中で止まったり開始されたりしません。

付録A: 任意置換関数

任意置換関数 とは、関数表記であり、 解決時に 自身を他の値に置き換えるが、 その値はパース時には不明な場合もありうるため、計算値解決中にパースされなければなりません。

注: 任意置換関数計算値時に解決されるため、 その置き換え後の値が無効であれば、 プロパティは基本的に unset 的な挙動をし、 パース時無効な場合のようにカスケード上の前値へは戻りません。 無効な置換参照。

特に規定がない限り、任意置換関数は あらゆるプロパティ値のどこにでも使うことができ (他の関数表記内でも)、 それ以外の文脈では無効です。

こういった関数をプロパティ以外でも有効にすべきか?

たとえば、次はプロパティ名として変数を使おうとして失敗している例です:
.foo {
  --side: margin-top;
  var(--side): 20px;
}

これはmargin-top: 20px; を設定するのと等価ではありません。 代わりに、2行目は無効なプロパティ名のため単なる構文エラーで破棄されます。

プロパティ値に 任意置換関数が1つ以上含まれ、 それが構文的に有効な場合は その値全体もパース時に有効だとみなします。

任意置換関数は、スタイル置換処理中の 計算値の時点で その他の値変換や調査より前に置換されます。 置換後にプロパティ値が宣言文法に一致しなければ、 その宣言は計算値時に無効になります。

また、プロパティ値が置換後に CSS全域キーワード(と空白・コメントのみ)だけで構成される場合、 そのキーワードが最初から指定値だったかのように扱います。

例:
:root { --looks-valid: 20px; }
p { background-color: var(--looks-valid); }

20pxbackground-color には無効な値なため、 そのプロパティは計算値時に無効となり、 transparentbackground-color の初期値)となります。

初期値として継承されるプロパティ、例 color だった場合は、 初期値でなく継承値になります。

var()全域キーワードカスタムプロパティ 自体から取得することはできません。 たとえば --foo: initial; などで指定すると カスタムプロパティ自体の明示的デフォルト化となります。 ただしフォールバック中には全域キーワードは使えます:
p { color: var(--does-not-exist, initial); }

上のコードでは、--does-not-exist プロパティが存在しないか 計算値時に無効のときは var() は かわりに initial キーワードを採用し、そのプロパティはもともと color: initial だったもののように動きます。 つまりこの場合はドキュメントの初期color値になり、 何も記載がない場合のような継承にはなりません。

任意置換関数は 自身用の 任意置換関数を解決する方法を定義する必要があります。 ここで resultfallback のオプション値を返します。 result保証無効値 を含まない限り それで関数を置換します。 そうでなければ fallback を使います。 (fallback は解決不要。実際に使う場合置換処理で扱います。)

注: 例としては「var()関数の解決」を参照。

任意置換関数の置換value に対して行うには:
  1. すべての 任意置換関数 func について value 内で:

    1. 解決する。resultfallbackを得る。

      result が返されなければ 保証無効値をセット。 fallback もなければ 保証無効値をセット。

    2. result保証無効値を含まない場合

      funcvalue 内でresult に置換する。

      そうでなく fallback保証無効値を含まない場合

      funcvalue 内でfallback に置換する。

      それ以外

      value 全体を保証無効値に置換して終了。

  2. なお 任意置換関数value 内にまだ残っていれば(置換のため) 再びこの手順を繰り返す。

  3. value の文脈ごとの文法チェックをする。 この時点で無効なら value保証無効値に置換。

置換はCSSトークン単位 [css-syntax-3]で行われ、 テキストとしてはされません。 変数でトークンの一部のみを構成させることはできません:
.foo {
  --gap: 20;
  margin-top: var(--gap)px;
}

これはmargin-top: 20px;(長さ型)に設定したのと同じではありません。 かわりに margin-top: 20 px;(数値+識別子)となり、 margin-top プロパティとして無効です。 ただし calc() を使えばこのように同等のことができます:

.foo { --gap: 20; margin-top: calc(var(--gap) * 1px); }

この処理により、置換後値そのままでは シリアライズできない場合もあることを示唆しています。 次も類似の例です:

.foo {
  --gap: 20;
  --not-px-length: var(--gap)px;
}

--not-px-length の 計算結果(置換後)の値は 20pxにはならず (再パース時に単一単位値になるため)、トークン分断のため px にコメントが入る形でシリアライズされます。

無効な置換

置換の結果プロパティ値が 保証無効値 を含めば、 その宣言は 計算値時に無効 となります。 この場合プロパティ型により以下のいずれかになります:

プロパティが未登録カスタムプロパティの場合
プロパティが登録カスタムプロパティユニバーサル構文の場合

計算値は保証無効値となります。

それ以外

継承プロパティなら継承値、 そうでなければ初期値となり、 これはunsetキーワード指定と同等です。

例:
:root { --not-a-color: 20px; }
p { background-color: red; }
p { background-color: var(--not-a-color); }

この場合 <p> 要素は背景が透明に(background-color の初期値)なり、 赤にはなりません。 カスタムプロパティ自体が未設定や、無効な var() 関数を含む場合も結果は同じです。

注意:これは background-color: 20px のように記載した場合と異なります。 この場合は通常の構文エラーでルール自体が破棄され、 background-color: red が適用されます。

注: 計算値時に無効 の概念は 任意置換関数が 通常の構文エラーのように「早い段階で失敗」できず、 UAが値の無効を検知した時点ではすでに他のカスケード値を捨ててしまっているためにあります。

ショートハンドプロパティでの置換

任意置換関数ショートハンドプロパティを 構成ロングハンドへ分解・逆シリアライズする際にいくつかの問題を生みます。

ショートハンドの値に任意置換関数が含まれている場合、 関連づけるロングハンドプロパティには、 この関数が 含まれていることを示す特別な「置換待ち値」を設定します。 これは置換までロングハンド値は決まらないことを表します。

この値は通常通りカスケードし、 計算値時に置換を行ってから ショートハンドのパース・ロングハンド値の決定をします。

注: ショートハンドに任意置換関数を含まない場合は パース時に分割して ロングハンド とし、 カスケードに参加します。 このときショートハンド本体は破棄されます。 var() が含まれる場合は その後何が来るかわからないのでこの処理はできません。

置換待ち値は API等で観測できる場合は空文字列としてシリアライズされます。


ショートハンドプロパティのシリアライズは 構成ロングハンド の 値を集め、 それを分解したとき元通りになるような値を合成して行われます。

ある ショートハンド に対応する すべてのロングハンドが 同一ショートハンド値からの置換待ち値の場合、 その ショートハンドプロパティは元の (任意置換関数含みの) 値でシリアライズされなければなりません。

それ以外で、同じ ショートハンド の いずれかのロングハンド置換待ち値または 置換済みでない 任意置換関数 を含む場合は ショートハンドプロパティは空文字列でシリアライズされます。

過度に長い値の安全な置換処理

素朴な実装だと、 一部の任意置換関数(たとえば var() など)は 「ビリオンラフ攻撃(Billion Laughs Attack)」のバリエーションに使われることがあります:

.foo {
  --prop1: lol;
  --prop2: var(--prop1) var(--prop1);
  --prop3: var(--prop2) var(--prop2);
  --prop4: var(--prop3) var(--prop3);
  /* など */
}

この短い例では、--prop4 の計算値は lol lol lol lol lol lol lol lol となり、 元の lol が8回繰り返されます。 レベルを増やすごとに識別子数は倍増します。 これを30レベル程度まで手作業で拡張すると --prop30ほぼ10億個もの識別子を含むことになります。

こうした攻撃を防ぐために、 UAは任意置換関数が展開して得るトークンストリームの長さに UA定義の上限を課さなければなりません。 任意置換関数 の展開がこの制限を超える場合は、 代わりに保証無効値に置換します。

本仕様は制限値の大きさ自体は規定しません。 ただしカスタムプロパティに1キロバイト以上のテキストを入れる妥当な用途もありうるため、 制限は相応に高く設定されるべきです。

注: UAはリソース制約のために標準違反が許されるという一般原則はここでも有効です。 UAによってはカスタムプロパティ長や識別子長に別途上限を設ける場合もあります。 ここでこの攻撃に個別に言及しているのは、 歴史の長さと、見た目上個々の値は小さいにも関わらず攻撃できてしまうからです。

付録B: ブール論理

CSSの将来的な拡張に対応するため、<boolean-expr[]> 生成規則は 多くの場合 <general-enclosed> 文法分岐を未知扱いし、 ブール論理は3値クリーン論理で解決されます。 (@supports など)場合によっては <general-enclosed> を「偽」とみなす定義もあります。 その場合従来通りのブール代数になります。

3値ブール論理は再帰的に以下のように評価されます:

「トップレベル」の <boolean-expr[]> が unknown で 外側文脈で未知扱いの定義がなければ、 false(偽)として評価されます。

注: つまり unknown は明示的な処理がなければ3値ブール式から「脱出」しません。 これは NaNトップレベル計算で「脱出」しないのと同様です。

謝辞

まず編集者一同、 このモジュールの 前レベル 貢献者すべてに感謝します。

さらに Guillaume Lebas氏、 L. David Baron氏、 Mike Bremford氏、 Sebastian Zartner氏、 そして 特に Scott Kellum 氏 に Level 5 へのアイデア・コメント・意見を感謝します。

変更履歴

2024年9月17日 ワーキングドラフト 以降の変更:

初版ワーキングドラフト 以降の変更:

Level 4以降の追加

CSS Values and Units Level 4 以降の追加:

セキュリティ考慮事項

本仕様ではCSS <url>値 で リクエスト内容のさまざまな操作が可能です。 CSSでは新しい仕様ですが、 すでに imglink 、さらにJavaScriptでも同様の制御ができます。

attr() 関数では HTML属性値をCSS値に利用できるため、 以前はCSS経由で取得できなかった機微情報が露出する場合があります。 詳細は§ 7.7.2 セキュリティを参照してください。

プライバシーへの配慮

本仕様で定義される単位の中には、ユーザーの画面サイズやデフォルトフォントサイズなど の情報を直接参照するものがありますが、 いずれもJSで簡単に取得できるため新たなリスクではありません。 同様に media-progress() 記法では ユーザー環境や好みに関する情報を表現できますが、 これはすでにメディアクエリ からも取得可能です。

attr() 関数では HTML属性値をCSS値として使えるため、 以前はCSSでアクセスできなかった情報の露出リスクが生じます。 詳細は§ 7.7.2 セキュリティを参照してください。

適合性

文書慣例

適合性要件は、記述的記述とRFC 2119の用語の組み合わせで表現されます。この文書の規範部分で使われる「MUST」「MUST NOT」「REQUIRED」「SHALL」「SHALL NOT」「SHOULD」「SHOULD NOT」「RECOMMENDED」「MAY」「OPTIONAL」といったキーワードは、RFC 2119のとおり解釈されます。 ただし、可読性の観点から、本仕様ではこれらの単語はすべて大文字では表記されません。

この仕様書の文章は、明示的に非規範である旨記載された部分、例示、ノートを除き全て規範的です。[RFC2119]

この文書の例示は「for example…」で始まるか、class="example" の形で本文から分離されます。例:

これは参考例の一例です。

説明ノートは「Note」で始まり、class="note" で本文と区別されます。例:

Note: これは参考ノートです。

アドバイス(助言)は、規範的な注意事項として特別な強調スタイルで表現され、その他の規範文書から <strong class="advisement"> で分離されます。例: UAはアクセス可能な代替手段を必ず提供しなければなりません。

適合クラス

本仕様への適合は下記3つの適合クラスについて定義されます:

style sheet
CSSスタイルシート
renderer
UA(ユーザーエージェント)で、スタイルシートの意味を解釈し、それを用いた文書をレンダリングするもの。
authoring tool
UA(ユーザーエージェント)で、スタイルシートを作成するツール。

スタイルシートが本仕様に適合するとは、本モジュールで定義された構文を用いる全ての記述が、汎用CSS文法および本モジュール内個別機能の文法に適合している場合を指します。

レンダラーが本仕様に適合するとは、対応する仕様に従ってスタイルシートの意味を正しく解釈するだけでなく、本仕様で定義されたすべての機能を正しくパースしレンダリングすることを意味します。ただし、機器の制限により文書を正しくレンダリングできない場合は非適合とは言いません。(例: UAがモノクロモニターの場合、色をレンダリングできなくても非適合とはなりません。)

オーサリングツールが本仕様に適合するとは、モジュールで定義された汎用CSS文法と各機能ごとの個別文法に合致するスタイルシートを生成し、また本モジュールで求められる全てのその他適合要件を満たす場合を指します。

部分的な実装

CSSの前方互換パース規則を活用してフォールバック値指定できるよう、CSSレンダラーは必ず利用できない@ルール、プロパティ、プロパティ値、キーワード、またはその他記法要素を無効として(必要に応じて無視)扱わなければなりません。特に、UAは一つのマルチ値宣言の中で対応していない成分値だけを無視して対応値だけ尊重してはなりません。どれか一つでも無効(=未対応値)とみなされた場合、その宣言全体を無効として無視する決まりです。

不安定・独自機能の実装について

将来のCSS標準機能との衝突を回避するため、CSSWGは将来互換性確保のベストプラクティスおよび不安定機能独自拡張実装時の留意事項

非実験的実装

仕様が勧告候補ステージに到達すると、非実験的な実装が可能となります。実装者は正しく仕様通り動作することが確認できたCRレベルの機能については、非接頭辞つきでリリースすべきです。

CSS間の相互運用性を確立し保つため、CSSワーキンググループは非実験的レンダラーに対し、未接頭辞実装リリース前に実装報告書(必要に応じテストケース含む)の提出を求めます。提出されたテストケースはWGでレビュー・修正対象となります。

テストケースや実装報告の提出方法などの詳細は、CSSワーキンググループのWebサイト https://www.w3.org/Style/CSS/Test/ を参照してください。質問は public-css-testsuite@w3.org メーリングリストへ。

索引

本仕様で定義される用語

参照によって定義される用語

参照文献

規範参照

[CSS-ALIGN-3]
Elika Etemad; Tab Atkins Jr.. CSS Box Alignment Module Level 3. 2023年2月17日. WD. URL: https://www.w3.org/TR/css-align-3/
[CSS-ANIMATIONS-1]
David Baron 他. CSS Animations Level 1. 2023年3月2日. WD. URL: https://www.w3.org/TR/css-animations-1/
[CSS-ANIMATIONS-2]
David Baron; Brian Birtles. CSS Animations Level 2. 2023年6月2日. WD. URL: https://www.w3.org/TR/css-animations-2/
[CSS-BACKGROUNDS-3]
Elika Etemad; Brad Kemper. CSS Backgrounds and Borders Module Level 3. 2024年3月11日. CR. URL: https://www.w3.org/TR/css-backgrounds-3/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 2022年1月13日. CR. URL: https://www.w3.org/TR/css-cascade-5/
[CSS-COLOR-5]
Chris Lilley 他. CSS Color Module Level 5. 2024年2月29日. WD. URL: https://www.w3.org/TR/css-color-5/
[CSS-CONDITIONAL-3]
Chris Lilley; David Baron; Elika Etemad. CSS Conditional Rules Module Level 3. 2024年8月15日. CR. URL: https://www.w3.org/TR/css-conditional-3/
[CSS-CONDITIONAL-5]
Chris Lilley 他. CSS Conditional Rules Module Level 5. 2024年11月5日. WD. URL: https://www.w3.org/TR/css-conditional-5/
[CSS-CONTAIN-3]
Tab Atkins Jr.; Florian Rivoal; Miriam Suzanne. CSS Containment Module Level 3. 2022年8月18日. WD. URL: https://www.w3.org/TR/css-contain-3/
[CSS-DISPLAY-3]
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 3. 2023年3月30日. CR. URL: https://www.w3.org/TR/css-display-3/
[CSS-EASING-1]
Brian Birtles; Dean Jackson; Matt Rakow. CSS Easing Functions Level 1. 2023年2月13日. CR. URL: https://www.w3.org/TR/css-easing-1/
[CSS-EASING-2]
CSS Easing Functions Level 2. 2024年8月29日. WD. URL: https://www.w3.org/TR/css-easing-2/
[CSS-FONTS-4]
Chris Lilley. CSS Fonts Module Level 4. 2024年2月1日. WD. URL: https://www.w3.org/TR/css-fonts-4/
[CSS-IMAGES-3]
Tab Atkins Jr.; Elika Etemad; Lea Verou. CSS Images Module Level 3. 2023年12月18日. CR. URL: https://www.w3.org/TR/css-images-3/
[CSS-IMAGES-4]
Tab Atkins Jr.; Elika Etemad; Lea Verou. CSS Images Module Level 4. 2023年2月17日. WD. URL: https://www.w3.org/TR/css-images-4/
[CSS-PROPERTIES-VALUES-API-1]
Tab Atkins Jr.; Alan Stearns; Greg Whitworth. CSS Properties and Values API Level 1. 2024年3月26日. WD. URL: https://www.w3.org/TR/css-properties-values-api-1/
[CSS-SIZING-3]
Tab Atkins Jr.; Elika Etemad. CSS Box Sizing Module Level 3. 2021年12月17日. WD. URL: https://www.w3.org/TR/css-sizing-3/
[CSS-SIZING-4]
Tab Atkins Jr.; Elika Etemad; Jen Simmons. CSS Box Sizing Module Level 4. 2021年5月20日. WD. URL: https://www.w3.org/TR/css-sizing-4/
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin. CSS Syntax Module Level 3. 2021年12月24日. CR. URL: https://www.w3.org/TR/css-syntax-3/
[CSS-TRANSFORMS-1]
Simon Fraser; 他. CSS Transforms Module Level 1. 2019年2月14日. CR. URL: https://www.w3.org/TR/css-transforms-1/
[CSS-TRANSFORMS-2]
Tab Atkins Jr.; 他. CSS Transforms Module Level 2. 2021年11月9日. WD. URL: https://www.w3.org/TR/css-transforms-2/
[CSS-TRANSITIONS-1]
David Baron; 他. CSS Transitions. 2018年10月11日. WD. URL: https://www.w3.org/TR/css-transitions-1/
[CSS-TYPED-OM-1]
Tab Atkins Jr.; François Remy. CSS Typed OM Level 1. 2024年3月21日. WD. URL: https://www.w3.org/TR/css-typed-om-1/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2024年3月12日. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-VALUES-5]
Tab Atkins Jr.; Elika Etemad; Miriam Suzanne. CSS Values and Units Module Level 5. 2024年9月17日. WD. URL: https://www.w3.org/TR/css-values-5/
[CSS-VARIABLES-1]
Tab Atkins Jr.. CSS Custom Properties for Cascading Variables Module Level 1. 2022年6月16日. CR. URL: https://www.w3.org/TR/css-variables-1/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. 2019年7月30日. CR. URL: https://www.w3.org/TR/css-writing-modes-4/
[CSS21]
Bert Bos 他. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 2011年6月7日. REC. URL: https://www.w3.org/TR/CSS21/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren 他. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[MEDIAQUERIES-4]
Florian Rivoal; Tab Atkins Jr.. Media Queries Level 4. 2021年12月25日. CR. URL: https://www.w3.org/TR/mediaqueries-4/
[MEDIAQUERIES-5]
Dean Jackson 他. Media Queries Level 5. 2021年12月18日. WD. URL: https://www.w3.org/TR/mediaqueries-5/
[REFERRER-POLICY]
Jochen Eisinger; Emily Stark. Referrer Policy. 2017年1月26日. CR. URL: https://www.w3.org/TR/referrer-policy/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997年3月. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SELECTORS-3]
Tantek Çelik 他. Selectors Level 3. 2018年11月6日. REC. URL: https://www.w3.org/TR/selectors-3/
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. Selectors Level 4. 2022年11月11日. WD. URL: https://www.w3.org/TR/selectors-4/
[WEB-ANIMATIONS-1]
Brian Birtles 他. Web Animations. 2023年6月5日. WD. URL: https://www.w3.org/TR/web-animations-1/
[WEB-ANIMATIONS-2]
Brian Birtles; Robert Flack. Web Animations Level 2. 2023年2月21日. WD. URL: https://www.w3.org/TR/web-animations-2/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

参考文献

[CSS-BOX-4]
Elika Etemad. CSSボックスモデルモジュール レベル4. 2024年8月4日. WD. URL: https://www.w3.org/TR/css-box-4/
[CSS-CASCADE-4]
Elika Etemad; Tab Atkins Jr.. CSS カスケーディングと継承 レベル4. 2022年1月13日. CR. URL: https://www.w3.org/TR/css-cascade-4/
[CSS-CASCADE-6]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS カスケーディングと継承 レベル6. 2024年9月6日. WD. URL: https://www.w3.org/TR/css-cascade-6/
[CSS-COLOR-4]
Chris Lilley; Tab Atkins Jr.; Lea Verou. CSSカラーモジュール レベル4. 2024年2月13日. CR. URL: https://www.w3.org/TR/css-color-4/
[CSS-LISTS-3]
Elika Etemad; Tab Atkins Jr.. CSSリストとカウンター モジュールレベル3. 2020年11月17日. WD. URL: https://www.w3.org/TR/css-lists-3/
[CSS-SCOPING-1]
Tab Atkins Jr.; Elika Etemad. CSSスコーピングモジュールレベル1. 2014年4月3日. WD. URL: https://www.w3.org/TR/css-scoping-1/
[CSS22]
Bert Bos. Cascading Style Sheets Level 2 Revision 2 (CSS 2.2) 仕様書. 2016年4月12日. WD. URL: https://www.w3.org/TR/CSS22/
[CSSOM-1]
Daniel Glazman; Emilio Cobos Álvarez. CSSオブジェクトモデル(CSSOM). 2021年8月26日. WD. URL: https://www.w3.org/TR/cssom-1/

プロパティ一覧

名前 初期値 適用対象 継承 パーセンテージ アニメーション型 正規順序 計算値
interpolate-size numeric-only | allow-keywords numeric-only 全要素 yes 該当なし アニメーション不可 構文ごと 指定通り

課題索引

これは CSS Values and Units Level 4 に対する差分仕様です。
この構文が例えばbackground-positionのロングハンドに対してどのように展開されるかを(たとえば各構成要素にvar()を用いた場合など) 定義する必要があります。 [Issue #9690]
このセクションは試作ドラフトであり、CSSWGでまだ承認されたものではありません。 [Issue #6245]
percent-progress() 記法が必要か、それとも自動変換される箇所が十分あるので不要か?
この機能は複数のブレークポイントをうまく扱えません、 そして 再設計が必要かもしれません[Issue #6245]
mix() 記法には キーフレームセットを取るバリアントもあります。 これは@keyframesルールを参照し、 そこから該当プロパティ宣言を取り出します。 他のmix記法もキーフレーム対応できると便利ですが、 component value (全プロパティ値ではなく)向けに 一連のキーフレームをどう表現すべきか?
<progress> は0-100%外のパーセント返却を許すが、 color-mix() は そのような値を許容しないので、この際の処理定義が必要。
この名前で良いのか?採用決定時に十分議論しきれなかった。
理論上はrandom()のようなものもプロパティ以外で使って問題ない( per-elementが指定されていない限り)。例えば @media (max-width: random(100px, 500px)) {...} など挙動は明確だと思われます。 ただしやはり無効化すべきか?
任意置換関数を定義する必要がある。 おそらくVariables節で。今後この機能を利用する関数が多数控えているため。
random-item()は var()的な性格なので、プロパティ限定利用とすべきかも。 (全同類関数に同じことを適用すべきかもしれない。) ただしrandom()は本質的に異なる値型なので、一貫性のためやはり制限を考えるべきかも。
これら関数をプロパティ以外でも有効にすべきか?