Поддержка больших таблиц стилей часто приводит к повторяющейся логике, особенно при работе с токенами системы проектирования, такими как градиенты или адаптивные шаблоны макетов.
At-правило @function в CSS позволяет инкапсулировать эту логику в параметризованные функции, которые можно использовать повторно. Это делает код CSS более удобным в обслуживании, согласованным и соответствующим принципу DRY (Don't Repeat Yourself).
Синтаксис @function
Специальная функция определяется с помощью правила @function, за которым следует название, разделенное дефисами, и список параметров. Функция возвращает значение, используя свойство result.
@function --my-function(--input1 <length>, --input2: default-value) returns <length> {
/* Logic goes here */
result: var(--input1);
}
Ключевые понятия
- Параметры. Должны начинаться с двойного дефиса (
--). - Значения по умолчанию. Вы можете указать значения по умолчанию, используя двоеточие (
:). - Результат. Свойство
resultопределяет значение, которое возвращает функция. Приоритет имеет последнее значениеresult, объявленное в теле функции. - Область видимости. Параметры и переменные, определенные внутри функции, имеют локальную область видимости.
- Типы. Вы можете потребовать, чтобы параметры и возвращаемое значение соответствовали типу CSS, указанному в квадратных скобках (например,
<color>), и разрешить несколько типов с помощью функцииtype(например,type(<number> | <percentage>)).
Примеры из практики
1. Токены системы проектирования (градиенты)
Инкапсулируйте логику градиентов цвета, чтобы обеспечить их единообразие в приложении. --angle предоставляет значение по умолчанию, которое можно переопределить.
@function --fancy-gradient(--start-color <color>, --end-color <color>, --angle: 98deg) returns <image>{
result: linear-gradient(in oklab var(--angle), var(--start-color), var(--end-color) );
}
.card {
background: --fancy-gradient(#ed73d7, #5d87e9);
}
2. Логика условного макета
Вы можете использовать @media или другие запросы непосредственно в функции, чтобы возвращать разные значения в зависимости от среды. При использовании условной логики в функции обратите внимание, что @function не возвращает первое значение result, а следует каскаду CSS и разрешается до последнего значения, которое соответствует размеру экрана, размеру контейнера или другому запросу.
@function --grid-template(--count <number>){
/* MANDATORY: Put default value first. */
result: 1fr; /* Default: stack */
@media (min-width: 800px) {
result: repeat(var(--count), 1fr); /* Grid on larger screens */
}
}
main {
display: grid;
grid-template-columns: --grid-template(2);
}
Рекомендации
- Используйте дефисы. Всегда добавляйте префикс
--к названиям функций и параметров. - Указывайте значения по умолчанию. Это сделает ваши функции более надежными.
- Простота. Используйте функции для логики, которая действительно повторяется или является сложной. Не усложняйте простые пары "свойство – значение".
- Используйте типы. Убедитесь, что параметры и возвращаемые значения имеют ожидаемые типы.
- Используйте предварительно скомпилированные альтернативы. Для функций, которые не зависят от ввода данных пользователем, запросов медиа или других клиентских вариаций, используйте прекомпилятор CSS, чтобы избежать ненужной работы на стороне клиента.
Резервные стратегии
В браузерах, которые не поддерживают функции CSS, значения, заданные с помощью таких функций, будут недействительными. Чтобы обеспечить поддержку других браузеров, сначала укажите резервное значение свойства. В браузерах с поддержкой функций CSS это значение будет переопределено.
.card {
/* Provide fallback, in this case a solid color. */
background: #5d87e9;
background: --fancy-gradient(#ed73d7, #5d87e9);
}
main {
/* Provide fallback, in this case a simple stacked default. */
grid-template-columns: 1fr;
grid-template-columns: --grid-template(2);
}
Если вам нужно сократить повторение стилей и при этом обеспечить поддержку других браузеров, используйте прекомпилятор CSS с функциями, например Sass.