計算
Sassにおける計算とは、calc()
関数や、clamp()
、min()
、max()
などの類似の関数を表現する方法です。Sassは、これらが互いに組み合わされている場合でも、可能な限り簡略化します。
- Dart Sass
- 1.40.0以降
- LibSass
- ✗
- Ruby Sass
- ✗
LibSass、Ruby Sass、および1.40.0より前のバージョンのDart Sassは、calc()
を element()
のような特殊関数として解析します。
LibSass、Ruby Sass、および1.31.0より前のバージョンのDart Sassは、clamp()
を、特別な構文をサポートするのではなく、通常の CSS 関数として解析します。1.31.0から1.40.0までのバージョンのDart Sassは、clamp()
を element()
のような特殊関数として解析します。
- Dart Sass
- 1.67.0以降
- LibSass
- ✗
- Ruby Sass
- ✗
1.40.0から1.67.0までのバージョンのDart Sassは、有効な CSS である calc(1 var(--plus-two))
(--plus-two
は + 2
と定義できるため)のような場合でも、演算子で区切られていない計算で複数の値を許可しません。
Dart Sass 1.67.0以降、計算内の複数の値は、他のすべての値がクォートされていない文字列(var()
式やクォートされていない文字列 "+ 2"
など)に評価される限り、スペースで区切ることができます。
SCSS 構文
@debug calc(400px + 10%); // calc(400px + 10%)
@debug calc(400px / 2); // 200px
@debug min(100px, calc(1rem + 10%)); // min(100px, 1rem + 10%)
Sass構文
@debug calc(400px + 10%) // calc(400px + 10%)
@debug calc(400px / 2) // 200px
@debug min(100px, calc(1rem + 10%)) ; // min(100px, 1rem + 10%)
計算では、通常のSassScriptとは異なる特殊な構文を使用します。CSS の calc()
と同じ構文ですが、Sass変数を使用し、Sass関数を呼び出すことができます。つまり、計算内では、/
は常に除算演算子です。
💡豆知識
Sass関数呼び出しの引数は、特別な計算構文ではなく、通常のSass構文を使用します。
計算で展開を使用することもできます。ただし、その場合、その展開を含む演算は簡略化または型チェックされないため、冗長な、または無効な CSS が生成される可能性があります。 calc(10px + #{$var})
と書く代わりに、calc(10px + $var)
と書いてください。
簡略化簡略化 パーマリンク
Sassは、1in + 10px
や 5s * 2
など、コンパイル時に組み合わせることができる単位を使用している場合、計算内の隣接する演算を簡略化します。 可能であれば、計算全体を単一の数値に簡略化することさえあります。たとえば、clamp(0px, 30px, 20px)
は 20px
を返します。
⚠️注意
これは、計算式が必ずしも計算を返すとは限らないことを意味します。Sassライブラリを作成している場合は、meta.type-of()
関数を使用して、処理している型を常に判別できます。
計算は他の計算内でも簡略化されます。特に、calc()
が他の計算の中に含まれている場合、関数呼び出しは削除され、通常の演算に置き換えられます。
SCSS 構文
$width: calc(400px + 10%);
.sidebar {
width: $width;
padding-left: calc($width / 4);
}
CSS 出力
.sidebar {
width: calc(400px + 10%);
padding-left: calc((400px + 10%) / 4);
}
演算演算 パーマリンク
+
や *
などの通常のSassScript演算で計算を使用することはできません。計算を許可する数学関数を作成する場合は、それらを独自の calc()
式内に記述します。互換性のある単位の数値の束が渡された場合、それらはプレーンな数値も返します。計算が渡された場合は、計算を返します。
この制限は、計算が不要な場合に、できるだけ早くエラーをスローするようにするために設けられています。計算は、プレーンな数値を使用できる場所すべてで使用できるわけではありません。たとえば、CSS 識別子(.item-#{$n}
など)に挿入することはできず、Sassの組み込み数学関数に渡すこともできません。SassScript演算をプレーンな数値用に予約することで、計算が許可される場所と許可されない場所が明確になります。
SCSS 構文
$width: calc(100% + 10px);
@debug $width * 2; // Error!
@debug calc($width * 2); // calc((100% + 10px) * 2);
Sass構文
$width: calc(100% + 10px);
@debug $width * 2; // Error!
@debug calc($width * 2); // calc((100% + 10px) * 2);
定数定数 パーマリンク
- Dart Sass
- 1.60.0以降
- LibSass
- ✗
- Ruby Sass
- ✗
計算には、CSS 識別子として記述される定数を含めることもできます。将来の CSS 仕様との前方互換性のために、*すべて*の識別子が許可されており、デフォルトでは、そのままパススルーされるクォートされていない文字列として扱われます。
Sassは、CSS で指定されているいくつかの特別な定数名を、単位のない数値に自動的に解決します。
SCSS 構文
@use 'sass:math';
@debug calc(pi); // 3.1415926536
@debug calc(e); // 2.7182818285
@debug calc(infinity) > math.$max-number; // true
@debug calc(-infinity) < math.$min-number; // true
Sass構文
@use 'sass:math'
@debug calc(pi) // 3.1415926536
@debug calc(e) // 2.7182818285
@debug calc(infinity) > math.$max-number // true
@debug calc(-infinity) < math.$min-number // true
計算関数計算関数 パーマリンク
- Dart Sass
- 1.65.0以降
- LibSass
- ✗
- Ruby Sass
- ✗
1.65.0以降のバージョンのDart Sass(1.66.xを除く)は、これらの計算関数の `round()`, `mod()`, `rem()`, `sin()`, `cos()`, `tan()`, `asin()`, `acos()`, `atan()`, `atan2()`, `pow()`, `sqrt()`, `hypot()`, `log()`, `exp()`, `abs()`, `sign()` を処理します.
Dart Sass 1.65.xでは、名前が計算関数と一致する関数呼び出しは、*常に*計算関数として解析されていました。これは既存のユーザー定義関数を壊したため、1.67.0で既存の動作を壊す*ことなく*再び追加できるようになるまで、新しい計算関数のサポートは1.66.0で削除されました。
Sassは、以下の関数を計算として解析します。
- 比較関数:
min()
、max()
、clamp()
- ステップ値関数:
round()
、mod()
、rem()
。 - 三角関数:
sin()
、cos()
、tan()
、asin()
、acos()
、atan()
、atan2()
。 - 指数関数:
pow()
、sqrt()
、hypot()
、log()
、exp()
。 - 符号関連関数:
abs()
、sign()
。
💡豆知識
計算関数と同じ名前のSass関数を定義した場合、Sassは常に計算値を作成する代わりに、定義した関数を呼び出します。
レガシーグローバル関数レガシーグローバル関数 パーマリンク
CSS は、Values and Units Level 4で数式のサポートを追加しました。ただし、Sassは、これよりずっと前に独自のround()
、abs()
、min()
、max()
をサポートしており、既存のすべてのスタイルシートとの下位互換性が必要でした。これが、特別な構文の工夫が必要になった理由です。
round()
、abs()
、min()
、または max()
の呼び出しが有効な計算式である場合、計算として解析されます。ただし、呼び出しの一部に、剰余演算子など、計算でサポートされていないSassScript機能が含まれているとすぐに、適切なSass数学関数の呼び出しとして解析されます。
計算は可能な場合は常に数値に簡略化されるため、唯一の実質的な違いは、Sass関数はビルド時に組み合わせることができる単位のみをサポートするため、min(12px % 10, 10%)
はエラーをスローすることです。
⚠️注意
他の計算では、単位のない数値を単位のある数値に加算、減算、または比較することはできません。ただし、min()
、max()
、abs()
、単一引数の round()
は異なります。歴史的な理由から単位/単位なしの混在を許可するグローバルSassレガシー関数との下位互換性のために、これらの単位は、min()
、max()
、abs()
、または単一引数の round()
計算内に直接含まれている限り、混在させることができます。
たとえば、min(5 + 10px, 20px)
は 15px
になります。ただし、sqrt(5 + 10px)
はエラーをスローします。sqrt(5 + 10px)
はグローバルSass関数ではなく、これらは互換性のない単位であるためです。
min()
および max()
min() および max() パーマリンク
- Dart Sass
- バージョン 1.11.0 以上 1.42.0 未満
- LibSass
- ✗
- Ruby Sass
- ✗
LibSass、Ruby Sass、および 1.11.0 より前のバージョンの Dart Sass は、常に min()
と max()
を Sass 関数として解析します。これらの実装でプレーンな CSS の min()
または max()
呼び出しを作成するには、代わりに unquote("min(#{$padding}, env(safe-area-inset-left))")
のように記述できます。
CSS は、Values and Units Level 4 で min()
および max()
関数 のサポートを追加しました。これはすぐに Safari によって iPhone X のサポート に採用されました。すでに min()
と max()
をレガシー Sass 関数としてサポートしていたため、後方互換性と CSS 関数としてのサポートのためのロジックを実装する必要がありました。
1.11.0 から 1.40.0、および 1.40.1 から 1.42.0 までのバージョンの Dart Sass は、min()
および max()
関数が有効なプレーン CSS である場合、特殊関数として解析しますが、変数や関数呼び出しなど、補間以外の Sass 機能が含まれている場合は、Sass 関数として解析します。
Dart Sass 1.41.0 は、min()
および max()
関数を計算として解析しますが、単位のない数値と単位のある数値を組み合わせることは許可していません。これはグローバルな min()
および max()
関数と後方互換性がなかったため、この動作は元に戻されました。
SCSS 構文
$padding: 12px;
.post {
// Since these max() calls are valid calculation expressions, they're
// parsed as calculations.
padding-left: max($padding, env(safe-area-inset-left));
padding-right: max($padding, env(safe-area-inset-right));
}
.sidebar {
// Since these use the SassScript-only modulo operator, they're parsed as
// SassScript function calls.
padding-left: max($padding % 10, 20px);
padding-right: max($padding % 10, 20px);
}
Sass構文
$padding: 12px
.post
// Since these max() calls are valid calculation expressions, they're
// parsed as calculations.
padding-left: max($padding, env(safe-area-inset-left))
padding-right: max($padding, env(safe-area-inset-right))
.sidebar
// Since these use the SassScript-only modulo operator, they're parsed as
// SassScript function calls.
padding-left: max($padding % 10, 20px)
padding-right: max($padding % 10, 20px)
CSS 出力
.post {
padding-left: max(12px, env(safe-area-inset-left));
padding-right: max(12px, env(safe-area-inset-right));
}
.sidebar {
padding-left: 20px;
padding-right: 20px;
}
round()
round() パーマリンク
- Dart Sass
- 1.65.0以降
- LibSass
- ✗
- Ruby Sass
- ✗
LibSass、Ruby Sass、および 1.65.0 より前のバージョンの Dart Sass、そして Dart Sass 1.66.x は、常に round()
を Sass 関数として解析します。これらの実装でプレーンな CSS 関数を使用するには、代わりに round(#{$strategy, $number, $step})
のように記述できます。
round(<strategy>, number, step)
関数は、オプションの丸め戦略、丸められる値、および丸め間隔 step
を受け入れます。strategy
は nearest
、up
、down
、または to-zero
である必要があります。
SCSS 構文
$number: 12.5px;
$step: 15px;
.post-image {
// Since these round() calls are valid calculation expressions, they're
// parsed as calculations.
padding-left: round(nearest, $number, $step);
padding-right: round($number + 10px);
padding-bottom: round($number + 10px, $step + 10%);
}
Sass構文
$number: 12.5px
$step: 15px
.post-image
// Since these round() calls are valid calculation expressions, they're
// parsed as calculations.
padding-left: round(nearest, $number, $step)
padding-right: round($number + 10px)
padding-bottom: round($number + 10px, $step + 10%)
CSS 出力
.post-image {
padding-left: 15px;
padding-right: 23px;
padding-bottom: round(22.5px, 15px + 10%);
}
abs()
abs() パーマリンク
- Dart Sass
- 1.67.0以降
- LibSass
- ✗
- Ruby Sass
- ✗
LibSass、Ruby Sass、および 1.67.0 より前のバージョンの Dart Sass は、常に abs()
を Sass 関数として解析します。これらの実装でプレーンな CSS 計算を作成するには、代わりに abs(#{$number})
のように記述できます。
⚠️注意
グローバルな abs()
関数の % 単位の引数との互換性は非推奨です。将来的には、ブラウザによって解決される CSS abs() 関数が発行されます。
abs(value)
は、単一の式を引数として受け取り、$value
の絶対値を返します。$value
が負の場合、これは -$value
を返し、$value
が正の場合、$value
をそのまま返します。
SCSS 構文
.post-image {
// Since these abs() calls are valid calculation expressions, they're
// parsed as calculations.
padding-left: abs(10px);
padding-right: math.abs(-7.5%);
padding-top: abs(1 + 1px);
}
Sass構文
.post-image
// Since these abs() calls are valid calculation expressions, they're
// parsed as calculations.
padding-left: abs(-10px)
padding-right: math.abs(-7.5%)
padding-top: abs(1 + 1px)
CSS 出力
.post-image {
padding-left: 10px;
padding-right: 7.5%;
padding-top: 2px;
}