Вычисления
Вычисления — это способ, которым Sass представляет функцию calc(), а также аналогичные функции, такие как clamp(), min() и max(). Sass максимально упростит их, даже если они объединены друг с другом.
- Dart Sass
- с версии 1.40.0
- LibSass
- ✗
- Ruby Sass
- ✗
LibSass, Ruby Sass и версии Dart Sass, предшествующие 1.40.0, анализируют calc() как специальную функцию, подобную element().
LibSass, Ruby Sass и версии Dart Sass, предшествующие 1.31.0, анализируют clamp() как простую функцию CSS, а не поддерживают специальный синтаксис внутри нее. Версии Dart Sass между 1.31.0 и 1.40.0 анализируют clamp() как специальную функцию, подобную element().
- Dart Sass
- с версии 1.67.0
- LibSass
- ✗
- Ruby Sass
- ✗
Версии Dart Sass между 1.40.0 и 1.67.0 не допускают нескольких значений в вычислениях, которые не разделены оператором, даже в таких случаях, как calc(1 var(--plus-two)), что является допустимым CSS (поскольку --plus-two может быть определено как + 2).
Начиная с Dart Sass 1.67.0, несколько значений в вычислении могут быть разделены пробелами, при условии, что каждое другое значение оценивается как нецитированная строка (например, выражение var() или нецитированная строка "+ 2").
@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() окажется внутри любого другого вычисления, вызов функции будет удалён, и он будет заменён обычной операцией.
$width: calc(400px + 10%);
.sidebar {
width: $width;
padding-left: calc($width / 4);
}// SASS $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 для простых чисел чётко показывает, где разрешены вычисления, а где нет.
$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 будущего, все идентификаторы разрешены, и по умолчанию они просто обрабатываются как нецитированные строки, которые передаются такими, какие они есть.
@debug calc(h + 30deg); // calc(h + 30deg);
// SASS @debug calc(h + 30deg) // calc(h + 30deg);
Sass автоматически разрешает несколько специальных имён констант, указанных в CSS, до безразмерных чисел:
-
pi— это сокращённая запись для математической константы π. -
e— это сокращённая запись для математической константы e. -
infinity,-infinityиNaNпредставляют соответствующие значения с плавающей запятой.
@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
- ✗
Версии Dart Sass 1.65.0 и более поздние версии за исключением 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.66.0 до тех пор, пока её не удалось добавить обратно без нарушения существующего поведения в 1.67.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 добавила поддержку математических выражений в 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()
- Dart Sass
- с >=1.11.0 <1.42.0
- LibSass
- ✗
- Ruby Sass
- ✗
LibSass, Ruby Sass и версии Dart Sass до 1.11.0 *всегда* анализируют min() и max() как функции Sass. Чтобы создать обычный вызов CSS min() или max() для этих реализаций, вы можете написать что-то вроде unquote("min(#{$padding}, env(safe-area-inset-left))") вместо этого.
CSS добавила поддержку min() и max() функций в Level 4 значений и единиц, откуда их быстро адаптировал Safari для поддержки iPhoneX. Поскольку мы уже поддерживали min() и max() в качестве устаревших функций Sass, нам пришлось реализовать логику обратной совместимости и поддержки в качестве функций CSS.
Версии Dart Sass между 1.11.0 и 1.40.0, и между 1.40.1 и 1.42.0 анализируют min() и max() функции как специальные функции, если они являются допустимыми простыми CSS, но анализируют их как функции Sass, если они содержат функции Sass, кроме интерполяции, такие как переменные или вызовы функций.
Dart Sass 1.41.0 анализирует min() и max() функции как вычисления, но не допускает комбинирования безыменных чисел с числами с единицами. Это было несовместимо с глобальными min() и max() функциями, поэтому это поведение было отменено.
$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()
- Dart Sass
- с 1.65.0
- LibSass
- ✗
- Ruby Sass
- ✗
LibSass, Ruby Sass и версии Dart Sass до 1.65.0, а также Dart Sass 1.66.x, *всегда* анализируют round() как функцию Sass. Чтобы использовать обычную функцию CSS, для этих реализаций вы можете написать что-то вроде round(#{$strategy, $number, $step}) вместо этого.
Функция round(<strategy>, number, step) принимает необязательную стратегию округления, значение для округления и интервал округления step. strategy должен быть nearest, up, down или to-zero.
$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()
- Dart Sass
- с 1.67.0
- LibSass
- ✗
- Ruby Sass
- ✗
LibSass, Ruby Sass и версии Dart Sass до 1.67.0 *всегда* анализируют abs() как функцию Sass. Чтобы создать обычное вычисление CSS для этих реализаций, вы можете написать что-то вроде abs(#{$number}) вместо этого.
Глобальная функция abs() несовместима с параметрами % unit, что устарело. В будущем это будет выводить функцию CSS abs() для обработки браузером.
Функция abs(value) принимает в качестве параметра единственное выражение и возвращает абсолютное значение $value. Если $value отрицательно, то возвращает -$value, а если $value положительно, то возвращает $value как есть.
.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;
}
© 2006–2025 the Sass team, and numerous contributors
Licensed under the MIT License.
https://sass-lang.com/documentation/values/calculations