Если рассматривать препроцессоры вместе с CSS, то получается картина более понятная, нежели чем рассматривать понятие препроцессора отдельно.
ОпределениеCSS препроцессор (от англ. CSS preprocessor) — это надстройка над CSS, которая добавляет ранее недоступные возможности для CSS, с помощью новых синтаксических конструкций.
Основная задача препроцессора — это предоставление удобных синтаксических конструкций для разработчика, чтобы упростить, и тем самым, ускорить разработку и поддержу стилей в проектах.
CSS препроцессоры преобразуют код, написанный с использованием препроцессорного языка, в чистый и валидный CSS-код.
При помощи препроцессоров вы можете писать код, который нацелен на:
- Читабельность для человека
- Структурированность и логичность
- Производительность
И это лишь малая часть того, что может дать вам препроцессор. Но не стоит забегать вперёд.
Синтаксический сахарПеред тем, как перейти к дальнейшему рассмотрению CSS-препроцессоров, давайте обновим наш лексикон новым понятием — «синтаксический сахар».
Синтаксический сахар (от англ. syntactic sugar) — это дополнения синтаксиса языка программирования, которые не вносят каких-то существенных изменений или новых возможностей, но делают этот язык более читабельным для человека.
Синтаксический сахар вводит в язык альтернативные варианты записи заложенных в этот язык конструкций. Под альтернативными вариантами записи стоит понимать более короткие или удобные конструкции для человека, которые в конечном итоге будут преобразовываться препроцессором в исходный язык, без синтаксического сахара.
Если попытаться применить это понятие к CSS-препроцессорам, то оно, в общем случае, полностью описывает их суть. Ещё раз напомню, что основной задачей препроцессоров является упрощение и ускорение разработки, а как это ещё можно сделать, если не ввести альтернативные варианты записи?
Какие бывают CSS-препроцессоры?Пора перейти к более конкретным примерам, а именно к самим CSS-препроцессорам. На момент написания книги можно выделить три популярных препроцессора:
- Sass (SCSS)
- Stylus
И несколько незначительных для нас игроков:
- Closure Stylesheets
- CSS Crush
О первой тройке мы поговорим отдельно немногим ниже, а вот о двух последних разговора вообще не будет, в виду их непопулярности. При желании, описания этих препроцессоров с лёгкостью можно найти в поисковике.
Какой смысл использования препроцессоров?Как я уже отметил выше, основные плюсы — это читабельность кода, структурирование и повышение производительности.
Существуют также и другие причины того, чтобы начать использовать препроцессор уже сегодня. Я хочу заострить на этом внимание, так как разработчики раньше, да многие и сейчас, отнекиваются от использования препроцессоров, находя их сложными, непонятными и ненужными.
CSS — это сложноСтандартный CSS — это сложно. Синтаксис без использования вложенности, которую предлагают CSS-препроцессоры, просто напросто сложен для зрительного восприятия. Кроме того, нужно помнить имя родителя при вложенности. Отсутствие нормальных переменных и «функций» делает CSS-код грязным и узконаправленным.
Доступная документацияПрошли те времена, когда документация от препроцессоров была доступна только людям «в теме». Сейчас любой желающий может в кратчайшие сроки освоить любой из препроцессоров, причём с минимальными затратами сил.
Простота использованияИспользовать препроцессоры стало проще, чем раньше, причём намного проще. Для этого нужно лишь установить программу, которая будет следить за файлами, предназначенными для препроцессора, и при их изменении будет компилировать содержимое этих файлов в чистый CSS-код.
Для более продвинутых пользователей есть специальные сборщики проектов. Не думайте, что если вы используете программу для препроцессоров, а не сборщик проектов, то вы недостаточно круты. На самом деле, такие сборщики предлагают полный контроль и расширенные настройки, а не делают из вас джедая.
Структура и логичность кодаСамым популярным предлагаемым функционалом любого CSS-препроцессора является возможность вкладывать селекторы друг в друга. Я не буду сейчас приводить пример, так как о возможностях Less, включая вложенность, будет написана соответствующая часть книги. На этом этапе вам стоит знать лишь то, что при использовании препроцессоров, можно вкладывать один селектор в другой, а другой в третий, получая что-то, похожее на оглавление книги:
1. Родительский селектор 1.1. Вложенный селектор 1.2. Вложенный селектор 1.2.1. Вложенный селектор 1.3. Вложенный селектор
Конечно, в реальной жизни селекторы не могут начинаться с цифр, однако, для проведения параллели между вложенностью и оглавлением, думаю такое упущение здесь уместно.
ПримесиЕсли говорить совсем кратко, то, используя примеси (от англ. Mixins), можно сделать код переиспользуемым. Это помогает избежать вспомогательных классов в разметке или дублирования свойств от селектора к селектору.
МодульностьЕще одним бонусом, который прямо сейчас уговорил бы меня начать пользоваться CSS-препроцессором, будет возможность вкладывать файлы в файлы, то есть проще говоря, производить конкатенацию файлов в заданной последовательности. Да, это можно организовать и на чистом CSS, но вкупе с другими возможностями получается очень мощный инструмент.
При этом мы получаем возможность делиться модулями (библиотеками примесей), которые создали для своих нужд и посчитали полезными для других людей. Получается, что любой разработчик может загрузить вашу библиотеку и использовать её в своих целях, вызывая по мере необходимости написанные вами примеси.
Почему бы не подождать развития CSS?Развитие CSS идёт очень маленькими и неуверенными шагами, так как W3C придерживается приоритета скорости срабатывания CSS (производительности). С одной стороны это правильно и очень важно, но с другой — это отсутствие удобства для разработчиков.
В пример поставлю одну из спецификаций CSS4, которую ввели под давлением разработчиков — селектор по родителю. Столь долгий путь от идеи до принятия решения был из-за того, что W3C считало такой селектор медленным и дальнейшее его использование на сайтах привело бы к диким тормозам. Конечно же, речь идёт о повсеместном применении этого селектора, а не о единичных случаях.
Так что не стоит ждать в ближайшее время революций и изменений, способных затмить функционал и возможности CSS-препроцессоров.
Разновидности препроцессоровРазумеется, как и в любой другой области, всегда есть конкуренция, и на рынке препроцессоров сейчас три главных, враждующих между собой лагеря:
- Sass (SCSS)
- Stylus
Враждующими я их называю, потому что каждый приверженец одного из препроцессоров считает своим долгом поливать нечистотами представителей других, скажем так, конфессий. Такая неприязнь особенно часто проявляется у любителей препроцессора Sass, который считается старейшим и мощнейшим из всех трёх препроцессоров.
Для полной картины, я хочу привести краткую справку по каждому препроцессору:
LessСобственно, герой этой книги. Самый популярный на момент написания книги препроцессор. Основан в 2009 году Алексис Сельер (Alexis Sellier) и написан на JavaScript (изначально был написан на Ruby, но Алексис вовремя сделал правильный шаг). Имеет все базовые возможности препроцессоров и даже больше, но не имеет условных конструкций и циклов в привычном для нас понимании. Основным плюсом является его простота, практически стандартный для CSS синтаксис и возможность расширения функционала за счёт системы плагинов.
Sass (SCSS)Самый мощный из CSS-препроцессоров. Имеет довольно большое сообщество разработчиков. Основан в 2007 году как модуль для HAML и написан на Ruby (есть порт на C++). Имеет куда больший ассортимент возможностей в сравнении с Less. Возможности самого препроцессора расширяются за счёт многофункциональной библиотеки Compass, которая позволяет выйти за рамки CSS и работать, например, со спрайтами в автоматическом режиме.
Имеет два синтаксиса:
- Sass (Syntactically Awesome Style Sheets) — упрощённый синтаксис CSS, который основан на идентации. Считается устаревшим.
- SCSS (Sassy CSS) — основан на стандартном для CSS синтаксисе.
Самый молодой, но в тоже время самый перспективный CSS-препроцессор. Основан в 2010 году небезызвестной в наших кругах личностью TJ Holowaychuk. Говорят, это самый удобный и расширяемый препроцессор, а ещё он гибче Sass. Написан на JavaScript. Поддерживает уйму вариантов синтаксиса от подобного CSS до упрощённого (отсутствуют: , ; , {} и некоторые скобки).
В этой статье мы поговорим о возможностях препроцессора Less, которые в силу каких-то неведомых сил, практически никто не использует. Кроме того, поговорим о недостающем функционале и попытаемся его добавить.
Начать я предлагаю с небольшого напоминания о том, как делать не нужно, даже если очень хочется. Посмотрите на фреймворк Alesya , который разработал товарищ, обучающий Less других людей. Постарайтесь внимательно посмотреть на файл./core/functions.less . Хотя нет, не переходите по ссылке, просто посмотрите на скриншот небольшой части этого файла. Когда первый раз увидел - я просто выпал в осадок.
Оправдание - циклы очень медленные, как следствие, скорость трансляции Less в CSS снижается, а время трансляции увеличивается. Pentium 4? Без обид, но это расстраивает.
Приведу отрывок из книги «HTML5 для веб-дизайнеров» за авторством Джереми Кит, который не так давно стал героем пабликов в ВК:
Предположим, что живет на свете злой урод, который ненавидит веб и всех пользователей Интернета. Этому господину наверняка плевать, что встраивать на страницу аудиофайл, который начинает проигрываться автоматически, невероятно грубо и глупо. С помощью атрибута autoplay можно удовлетворить его глубоко порочные желания.
Если вы когда-нибудь будете так использовать атрибут autoplay, знайте: я вас найду.
Поэтому, если вы будете так же использовать Less, знайте, вас уже ищут и скоро найдут.
Расширение селекторовИмеем типичный для наших дней прерыватель потока:
Clearfix { &:before, &:after { content: " "; display: table; } &:after { clear: both; } }
И какой-то селектор, который подразумевает использование clearfix. Конечно, можно использовать.clearfix как примесь и всюду плодить огромное количество лишнего, но нужного кода. Однако, можно избежать этого, используя расширение селекторов.
Например, так:
Navbar { &:extend(.clearfix all); ... } .navbar-collapse { &:extend(.clearfix all); ... } .ad { &:extend(.clearfix all); ... }
В итоге наш класс.clearfix начинает общаться с друзьями из различных частей ваших стилей, при этом ни с кем не делясь лишними строчками кода:
Clearfix:before, .clearfix:after, .navbar:before, .navbar:after, .navbar-collapse:before, .navbar-collapse:after, .ad:before, .ad:after { content: " "; display: table; } .clearfix:after, .navbar:after, .navbar-collapse:after, .ad:after { clear: both; }
Конечно, злоупотреблять этим не стоит. Честно говоря, советую использовать расширение селекторов только для clearfix и в случаях, когда действует правило: «Ну очень надо, ничего поделать не могу, иначе будет хуже». Не стоит использовать расширение селекторов тогда, когда происходят махинации со стилями элементов. Наиболее частая и глупая ошибка:
Class { color: #fff; background: #fff; } .new-class { &:extend(.class); } // .class, // .new-class { // color: #fff; // background: #fff; // }
Так делать нельзя. Это глупо. Лучше использовать.class как примесь:
Class { color: #fff; background: #fff; } .new-class { .class; } // .class { // color: #fff; // background: #fff; // } // .new-class { // color: #fff; // background: #fff; // }
Запомните это!
Параметры импортаПожалуйста, обратите внимание на раздел документации «параметры директивы импорта» .
Я приведу лишь краткое описание самых важных из этих параметров:
reference
Позволяет использовать.less файлы, но не выводить их содержимого без явного вызова. Очень полезный параметр, если вы пользуетесь Bootstrap как библиотекой, а не фреймворком, то есть:
@import (reference) "bower_components/bootstrap/less/bootstrap"; .my-alert { .alert; }
Использование этого параметра даёт возможность подключать файлы не.less расширения. Параметр не обязательный, так как и без него всё будет работать, но, тем не менее, если вы любите порядок - пригодится. Этот параметр можно применять при подключении файлов с расширением, отличным от.less , к примеру, .variables , .mixins .
Применять нужно так:
@import (keyword) "filename";
С подробным описанием и примерами можно ознакомиться на страницах документации. Вот так вот вежливо я посылаю тебя, мой читатель, читать документацию. Незабываемые ощущения:)
Условные конструкцииВ Less есть условные конструкции. Да, они не полноценные, если сравнивать их с другими препроцессорами, но всё таки их наличие не может не радовать. Мне они кажутся даже удобнее, чем @if в Sass, хотя практической разницы никакой нет.
Mixin(@variable) { & when (@variable = 1) { content: "TRUE" } & when not (@variable = 1) { content: "FALSE" } } .class-test { .mixin(1); .mixin(2); }
В итоге мы получим следующий CSS:
Class-test { content: "TRUE"; content: "FALSE"; }
Что же только что произошло? Магия?
На самом деле - нет. Ключевое слово when тут заменяет привычный во всех языках программирования if и имеет всего два логических элемента: not - отрицание, and - просто and и всё, больше ничего нет. Особо крутого с этим сделать не получится, но я использую условный оператор для того, чтобы не генерировался лишний код. Одной из таких ситуаций, например, является свойство border-radius в генераторе стилей кнопки. Зачем лишний раз будет прописываться какое-либо свойство при генерации, если его значение не играет роли (0)? - Правильно, не нужно.
Интерполяция переменныхЕсть в Less интересная конструкция, когда значение одной переменной мы получаем в зависимости от других.
// Variables @clr-grey-100: #fafafa; @clr-grey-200: #f5f5f5; @clr-red-100: #ffebee; @clr-red-200: #ffcdd2; .mixin(@color, @temperature: 500) { color: ~"@{clr-@{color}-@{temperature}}"; background: e("@{clr-@{color}-@{temperature}}"); } .class-test { .mixin(grey, 100); &-test { .mixin(red, 200); } }
В этом примере вызывается примесь, в которой параметрами выступают цвет (@color ) и его температура (@temperature ). Далее мы собираем все переменные в одну, то есть, проще говоря, конструируем новую переменную и получаем её значение. Процесс, когда строка, условно говоря, превращается в вызов переменной и есть интерполяция переменных.
Заметьте, что в этом примере мы используем фигурные скобки после собачки - это очень важно.
На выходе:
Class-test { color: #fafafa; background: #fafafa; } .class-test-test { color: #ffcdd2; background: #ffcdd2; }
Кстати, такого я найти в Sass и Stylus не смог. Может подскажет внимательный читатель? :)
ЦиклыМногие приверженцы препроцессоров Sass и Stylus давят на то, что в Less нет циклов, но они есть, хотя и не такие как у всех. Вот только пользоваться ими неудобно.
Допустим, что у нас есть список цветов:
@list-red: #ffebee, #ffcdd2, #ef9a9a, #e57373, #ef5350, #f44336, #e53935, #d32f2f, #c62828, #b71c1c;
Для примера, давайте создадим для каждого цвета свой класс:
Color-generator(@index: 1, @color) when (@index