数学的表現の処理
値のタイプの判定
数学的表現は“<length>”値や“<number>”値などのデータ型である“解決済タイプ(Resolved Type)”を持ち、同じデータ型が許容される場所であればいつでも使用することができます。
さらに“<number>”値を表す数学関数は“<integer>”値のみが認められる場所でも使用することができます。
数量を表す値や数式は“CSS Typed OM Level 1”の仕様で定義されているように、“«[ ”と“]»”で囲まれたベース・タイプと値の組であるタイプ、およびパーセント・ヒントに関連付けられ、それらによってどのデータ型と一致するのかが判断されます。
- “+”もしくは“-”による部分式
- 左右のタイプを加算した結果がそのタイプです。加算が失敗した場合、タイプの判定は失敗です。
- “*”による部分式
- 左右のタイプを乗算した結果がそのタイプです。
- “/”による部分式
- 左のタイプと右のタイプの逆数を乗算した結果がそのタイプです。
計算の他の部分は以下のようにタイプを判断します。
- “<number>”値、“<integer>”値
- タイプは“«[ ]»”
- “<number>”値
- タイプは“«[ "length" → 1 ]»”
- “<angle>”値
- タイプは“«[ "angle" → 1 ]»”
- “<time>”値
- タイプは“«[ "time" → 1 ]»”
- “<frequency>”値
- タイプは“«[ "frequency" → 1 ]»”
- “<resolution>”値
- タイプは“«[ "resolution" → 1 ]»”
- “<flex>”値
- タイプは“«[ "flex" → 1 ]»”
- “<calc-constant>”値
- タイプは“«[ ]»”
- “<percentage>”値
- “<percentage>”値が他のデータ型として解決される場所に置かれている計算ではそのデータ型のタイプ、そうでなければタイプは“«[ ]»”です。
- 上記以外
- タイプの判定は失敗です。
すべての場合で、パーセント・ヒントは“null”です。
また、数学関数自体もタイプがあり、以下のように判断されます。
- “calc()”関数、“abs()”関数
- 引数となる計算のタイプをそのタイプとします。
- “min()”関数、“max()”関数、“clamp()”関数
- コンマで区切られた引数のタイプを加算した結果をそのタイプとします。
- “sign()”関数
- タイプは“«[ "number" → 1 ]»”です。
- “sin()”関数、“cos()”関数、“tan()”関数
- タイプは“«[ "number" → 1 ]»”です。
- “asin()”関数、“acos()”関数、“atan()”関数、“atan2()”関数
- タイプは“«[ "angle" → 1 ]»”です。
- “pow()”関数、“sqrt()”関数、“log()”関数、“exp()”関数
- タイプは“«[ "angle" → 1 ]»”です。
- “hypot()”関数、“round()”関数、“mod()”関数、“rem()”関数
- コンマで区切られた引数のタイプを加算した結果をそのタイプとします。
タイプの判定が失敗した場合はその数学関数は無効です。
最後に、タイプは以下の場合にそれぞれのデータ型に一致します。
- “<length>”値
- 値が“0”でないエントリが“«[ "length" → 1 ]»”のみであり、パーセント・ヒントが“null”の場合
- “<angle>”値
- 値が“0”でないエントリが“«[ "angle" → 1 ]»”のみであり、パーセント・ヒントが“null”の場合
- “<time>”値
- 値が“0”でないエントリが“«[ "time" → 1 ]»”のみであり、パーセント・ヒントが“null”の場合
- “<frequency>”値
- 値が“0”でないエントリが“«[ "frequency" → 1 ]»”のみであり、パーセント・ヒントが“null”の場合
- “<resolution>”値
- 値が“0”でないエントリが“«[ "resolution" → 1 ]»”のみであり、パーセント・ヒントが“null”の場合
- “<flex>”値
- 値が“0”でないエントリが“«[ "flex" → 1 ]»”のみであり、パーセント・ヒントが“null”の場合
- “<percentage>”値
- 値が“0”でないエントリが“«[ "percent" → 1 ]»”のみである場合
- “<length-percentage>”値
- 値が“0”でないエントリが“«[ "length" → 1 ]»”もしくは“«[ "percent" → 1 ]»”のみである場合
- “<frequency-percentage>”値
- 値が“0”でないエントリが“«[ "frequency" → 1 ]»”もしくは“«[ "percent" → 1 ]»”のみである場合
- “<angle-percentage>”値
- 値が“0”でないエントリが“«[ "angle" → 1 ]»”もしくは“«[ "percent" → 1 ]»”のみである場合
- “<time-percentage>”値
- 値が“0”でないエントリが“«[ "time" → 1 ]»”もしくは“«[ "percent" → 1 ]»”のみである場合
- “<number>”値
- 値が“0”でないエントリがないく、パーセント・ヒントが“null”の場合
- “<number-percentage>”値
- 値が“0”でないエントリがないか、“0”でないエントリが“«[ "percent" → 1 ]»”のみである場合
数学関数は必ず“<number>”値、“<length>”値、“<angle>”値、“<time>”値、“<frequency>”値、“<resolution>”値、“<flex>”値、“<percentage>”値のうちの1個に解決され、いずれにも一致しない場合は無効になります。
“CSS Values and Units Module Level 3”までは…
パーセント値が指定できる場所でそのパーセント値が“<number>”値以外の何らかのデータ型の相対値を表す場合、パーセント値はそのデータ型として扱われ、“<percentage>”値のみが認められている場所に置かれた場合にのみ“<percentage>”値として扱われます。
“<percentage>”値の使用が認められていない場所で“calc()”関数の中でパーセント値を使用した場合、“calc()”関数は無効になります。
計算の演算子は部分式を生成し、それぞれの引数によってタイプが判断されます。演算子は受け付けるタイプに制約がある場合があり、その制約を満たすかを判定したうえで、以下のようにタイプが判断されます。
- “+”もしくは“-”による部分式
- 演算子の両側が同じタイプであればそのタイプ、片側が“<number>”値でもう一方の側が“<integer>”値であれば“<number>”値になります。
- “*”による部分式
- 片側が“<number>”値であれば、もう一方の側のタイプ、両側が“<integer>”値であれば“<integer>”値になります。
- “/”による部分式
- 片側が“<number>”値であれば、もう一方の側のタイプ、両側が“<integer>”値であれば“<number>”値になります。
演算子が以上の条件を満たさない場合はそれを含む数学的表現は無効です。また、ゼロ除算も無効です。
“0”や“∞”を含む計算
“0”を含む計算の扱いは以下のように定義されています。
- 正の値を“0”で除算した場合
- 結果は“+∞”です。
- 負の値を“0”で除算した場合
- 結果は“-∞”です。
- “0”を“0”で除算した場合
- 結果は“NaN”です。
ゼロ除算の扱いは“IEEE 754”の標準に準拠します。
計算の中で単位のない“0”は常に“<number>”値として扱われます。
“∞”を含む計算の扱いは以下のように定義されています。
- 何らかの値に“+∞”もしくは“-∞”を加算もしくは減算した場合
- 結果は“+∞”もしくは“-∞”です。ただし、追加の規則があれば“NaN”。
- 何らかの値を“+∞”もしくは“-∞”で乗算した場合
- 結果は“+∞”もしくは“-∞”です。ただし、追加の規則があれば“NaN”。
- 何らかの値を“+∞”もしくは“-∞”で除算した場合
- 結果は“0”です。ただし、追加の規則があれば“NaN”。
- “0”を“+∞”もしくは“-∞”で乗算した場合
- 結果は“NaN”です。
- “+∞”もしくは“-∞”に“+∞”もしくは“-∞”を乗算した場合
- 結果は“NaN”です。
- “+∞”に“-∞”を加算、“+∞”もしくは“-∞”から同じ符号の“∞”を減算した場合
- 結果は“NaN”です。
“NaN”を1個でも含む数式の結果は“NaN”となります。ただし、他の数学関数の中に入れ子にされていない数学関数の計算結果である“NaN”は“+∞”であるように扱われます。
負のゼロ
この仕様では負のゼロ(“0⁻”)が取り入れられています。“0⁻”は負の値を1個だけ含む乗算もしくは除算などによって算出されます。
- “0-”に“0+”加算、もしくは“0-”から“0”を減算した場合
- 結果は“0-”です。これ以外の結果が“0”となる計算の結果は正のゼロです。
- “0-”を正の値(“0+”も含む)で乗算もしくは除算した場合
- 結果は“0-”もしくは“-∞”です。
- “0-”を負の値で乗算もしくは除算した場合
- 結果は“0+”もしくは“+∞”です。
“0+”と“0-”を比較した時、“0-”は“0+”よりも小さいものとして扱われます。
ただし、他の数学関数の中に入れ子にされていない数学関数の計算結果が“0-”である場合、単に“0”として扱われます。
値の範囲に制約がある場合
値が使用されるプロパティが許容する値の範囲の制約がある場合でも、計算結果がその範囲外になる数学関数は直ちにその宣言を無効にすることはありません。許容される範囲外の計算結果は値として認められる範囲内に収まるように丸められます。
例えば、“width”プロパティでは負の値は無効ですが、計算結果が負の値となる数式は値が“0”として扱われるので無効ではありません。
数式の混合
数式同士、もしくは数式と他の数値形式の値との補間による出力結果(“Vresult”)は“calc((1 - p) * Va + p * VB)”で表されます。
数式同士、もしくは数式と他の数値形式の値との加算による出力結果(“Vresult”)は“calc(Va + VB)”で表されます。
その他
ユーザー・エージェントは数字や定数を最低でも20個含んだ数式に対応するように仕様書に求められています。ユーザー・エージェントが対応しているものを超える場合には数式は無効となります。
テーブル・セルやテーブル要素における横幅と高さの計算の複雑さから、“<percentage>”値を含む数式をテーブルの列、列グループ、行、行グループ、セルの横幅と高さの指定に用いると“auto”として扱われる場合があります。