6 функций препроцессоров приходят в обычный CSS
() translation by (you can also view the original English article)
Использование препроцессоров, таких как Sass, LESS и Stylus, всегда давало разработчикам больше контроля над таблицами стилей, но то, что входит в CSS постепенно закрывает прорехи. CSS-функции, такие как переменные, calc и mixins, являются лишь верхушкой айсберга; давайте рассмотрим, какие препроцессоры в настоящее время помогают нам и как встроенная логика CSS будет меняться, пока мы что-то делаем.



Эпоха препроцессоров
Языковые абстракции, такие как Sass, LESS и Stylus, взорвали миры разработчиков, предоставив им переменные, mixins, функции, расширения (extends) и многое другое. Эти препроцессоры заполняли недостающие функции, которые CSS не смог предоставить. Тем не менее, CSS больше не следует рассматривать как «отсутствие логики» и интеллекта. CSS движется в направлении усовершенствования, мы уже улавливаем проблески будущего; будущее, которое будет конкурировать с препроцессорами.
1. Смешивание (mixin)
Обычно мы ассоциируем “mixins” с препроцессорами, группой CSS определений, которые вы можете использовать повторно в вашем проекте. Mixin может быть использован, как самостоятельный вспомогательный элемент или вы можете передать значение в качестве аргумента, чтобы сделать его очень гибким.
Вот пример для Sass @mixin
, названный font-size
.
1 |
@mixin font-size($size, $base) { |
2 |
font-size: $size; // fallback for old browsers |
3 |
font-size: ($size / $base) * 1rem; |
4 |
}
|
Вышеупомянутый mixin примет аргументы для $size
и $base
, и будет использоваться при объявлении @include
с возможностью подстраивать зависимость аргументов от контекста.
1 |
/* Sass Call */
|
2 |
body { |
3 |
@include font-size(14, 16); |
4 |
}
|
5 |
|
6 |
/* CSS output */
|
7 |
body { |
8 |
font-size: 14px; |
9 |
font-size: 0.875rem; |
10 |
}
|
В результате, значение для font-size
задано в rem
, с резервным вариантом в px
, для браузеров, которые не поддерживают rem
. Mixins препроцессоров, вроде этого, сохраняют разработчикам бесчисленные часы годами.
Mixins в обычном CSS, сейчас находятся в черновом варианте, а так же имеют работающий вариант в Chrome. Если вы уже игрались с переменными в CSS, следующий кусок кода будет для вас знакомым.
1 |
:root { |
2 |
--pink-theme: { |
3 |
background: #F64778; |
4 |
}
|
5 |
}
|
Осторожно, от вышеприведенного кода ваша подсветка синтаксиса определенно спятит. Такой способ написания CSS-mixin использует новое at-rule, называемое @apply
, похожее на то, что мы знаем в Sass как @include
.
1 |
body { |
2 |
@apply --pink-theme; |
3 |
}
|
Так же, как мы знакомы с использованием @include
в Sass, мы наконец-то можем использовать @apply
для CSS!



Вы можете попробовать этот пример в своём Chrome, включив флаг в chrome://flags/#enable-experimental-web-platform-features
.
2. Вычисление
Помните, когда препроцессоры были единственными инструментами стилизации, способными на математические упражнения? Ну так вот, это больше не так. С функцией calc()
, мы можем взять эти надоедливые числа и превратить их в новые значения на основе желаемой арифметики.
1 |
nav { |
2 |
margin: calc(1rem - 2px) calc(1rem - 1px); |
3 |
}
|
Эта красота calc()
; она, наконец, расширяет возможности CSS в стратосфере. Предпочитаете сложение? вычитание? деление? умножение? Calc может обрабатывать всё это и многое другое.
Если вы хотите узнать больше об calc()
, то в спецификации W3C есть всё, что вам нужно, чтобы сделать вас сонным и счастливым одновременно. Поддержка браузера также шикарная, согласно Могу ли я это использовать.



3. Передача значения
И наконец, в CSS появились свои собственные переменные. Это реальная и осязаемая опция для разработчиков, хотя потребовалось некоторое время, чтобы научиться этому у препроцессоров.
Вот как выглядит синтаксис переменной Sass:
1 |
$spacing-unit: 20px; |
2 |
|
3 |
main { |
4 |
margin: $spacing-unit; |
5 |
padding: $spacing-unit; |
6 |
}
|
Переменные Sass обозначаются знаком доллара $
, но в CSS они выглядят несколько иначе:
1 |
:root { |
2 |
--primary-color: skyblue; |
3 |
}
|
4 |
|
5 |
nav.primary { |
6 |
background: var(--primary-color); |
7 |
}
|
Переменные CSS обозначаются двойным тире --
и обычно помещаются внутри :root
для глобального доступа, хотя их область может быть ограничена при помещении их в определенные селекторы.
1 |
div { |
2 |
color: var(--my-var, red); |
3 |
}
|
Переменные могут даже принимать резервное значение, если они ещё не определены, как в случае с приведенным выше примером. Поддержка браузера тоже неплохая, даже Edge показывает частичную поддержку. Спецификация так же относится к рекомендуемой к прочтению для удовольствия.



4. Вложенность
Вложенность — это функция многих препроцессоров, которая позволяет размещать селекторы внутри существующего определения. Как правило, вложенность в Sass выглядит примерно так:
1 |
ul { |
2 |
margin: 20px auto; |
3 |
li { |
4 |
font-size: 12px; |
5 |
a { |
6 |
text-decoration: none; |
7 |
}
|
8 |
}
|
9 |
}
|
Вложенность может стать громоздкой и может обернуться вам тонной проблем, что приведет к невозможно длительным цепям селекторов. По этой причине рекомендуется придерживаться начального правила (Inception Rule) и придерживаться вложенности не более чем на три или четыре уровня.
В то время как вложенность может быть опасной, она также может быть полезной, если вы потратите время и будете внимательны. Вот краткий обзор на то, как она может выглядеть, в конечном итоге, в обычном CSS:
1 |
/* CSS Nesting */
|
2 |
nav { |
3 |
color: #222; |
4 |
&.primary { |
5 |
background: maroon; |
6 |
}
|
7 |
}
|
8 |
|
9 |
/* Result */
|
10 |
nav { |
11 |
color: #222; |
12 |
}
|
13 |
|
14 |
nav.primary { |
15 |
background: maroon; |
16 |
}
|
Так же, как мы привыкли к нашим помощникам в препроцессорах, вложенность в обычном CSS работает по тем же принципам, но без необходимости компиляции языка. Для самой функции вложенности в обычном CSS есть черновая спецификация от Тэба Эткинса (Tab Atkins).
5. Правило extend
“Расширения” (extends) это ещë один способ передавать свойства и значения, разделяя их между объявлениями. В Sass мы привыкли использовать следующий синтаксис:
1 |
.message { |
2 |
border: 1px solid #ccc; |
3 |
padding: 10px; |
4 |
color: #333; |
5 |
}
|
6 |
|
7 |
.success { |
8 |
@extend .message; |
9 |
border-color: green; |
10 |
}
|
11 |
|
12 |
.error { |
13 |
@extend .message; |
14 |
border-color: red; |
15 |
}
|
16 |
|
17 |
.warning { |
18 |
@extend .message; |
19 |
border-color: yellow; |
20 |
}
|
Как видите, мы начинаем с определения стилей для .message
, а затем предлагаем три варианта с разными border-colors
. В каждом случае, сначала расширяем .message
, тем самым наследуя все его стили, перед непосредственным изменением цвета границ.
Идентичный синтаксис примера выше — это то, что разрабатывается Тэбом Эткинсом, как ещё одна потенциальная спецификация CSS. Независимо от того, согласны ли вы с extends или нет (функцией, чьи преимущества горячо обсуждаются), здорово видеть, что сторожилы CSS используют идеи, взятые у препроцессоров.
6. Истинные цвета
Если вам когда-нибудь придётся использовать функции препроцессоров по обработке цвета, тогда вы оцените наличие такой функции у CSS. Функция color-mod() берёт существующий цвет и применяется от нуля и больше «регуляторов цвета», которые определяют, как управлять конечным результатом.
1 |
nav { |
2 |
background: color-mod(#79d3e2 hue(360) saturation(100%)); |
3 |
}
|
Разработка находится на ранних стадиях и пока доступны частые изменения синтаксиса полифилов (текущий color-mod
, например, раньше был color
).
Тайлер Гау сделал очень изящный инструмент (colorme.io), который позволяет вам экспериментировать со всеми возможными регуляторами цветов.



Спецификация функции color-mod() в настоящее время находится в режиме черновика у CSS Working Group.
Заключительные мысли
Аналогично тому, как jQuery помогает делать веб лучше, так же действуют препроцессоры для CSS. Языки, подобные Sass, помогли проложить путь для новых идей и подходов, которые ещё не рассмотрены авторами спецификации CSS.
Я надеюсь, что новые функции, о которых мы говорили, вдохновят вас на использование их в работе; я рекомендую вам, по возможности, использовать родную функциональность нежели препроцессор!