Содержание статьи

Как ты помнишь, на заре интернета визуальное представление документов целиком ложилось на плечи браузеров, которые использовали свои собственные встроенные стили для отображения различных HTML-тегов. Поскольку никакими стандартами на тот момент оформление не регламентировалось, производители браузеров в борьбе за неокрепшие умы пользователей украшали странички как могли, и в результате один и тот же документ мог разительно отличаться по внешнему виду в зависимости от ОС и браузера, в котором он отображался.

Глядя на эту дикую вольницу, норвежский ученый-информатик Хокон Виум Ли в 1994 году предложил производителям браузеров концепцию каскадных таблиц стилей, призванную отделить оформление от структуры веб-страницы и целиком отдать его на откуп веб-разработчиков. Идея приглянулась свежесобранному консорциуму W3C, и после двух лет прений и согласований спецификация CSS 1.1 была выброшена прямо на поле боя разгоравшейся войны браузеров. В дальнейшем спецификация CSS пережила еще два мажорных релиза, обзавелась огромной кучей новых свойств и умений, но концептуально недалеко ушла от изначальных редакций: задание стилей, как и раньше, сводилось к монотонному перечислению свойств для каждого элемента индивидуально, браузеры исправно поставляли уникальные префиксозависимые фичи. К тому же отсутствовали единые рекомендации по группировке (или сортировке) CSS-свойств внутри блоков, что, в свою очередь, порождало многочисленные холивары.

В таком виде CSS вступил в конец двухтысячных, своеобразный ренессанс фронтенд-разработки. CSS-разметка все чаще стала ложиться на плечи профильных фронтенд-разработчиков, которые быстро обнаружили, что в текущем виде CSS сложно поддается структуризации и автоматической генерации и не предоставляет никаких возможностей для гибкой и динамической работы со стилями элементов. Грядущий CSS3 обещал немного скрасить ситуацию, предложив некоторые новые селекторы и встроенные средства для работы с анимацией, но необходимость в префиксах и отслеживании поддержки браузерами новых фич делала процесс еще более утомительным. В результате неуемный энтузиазм Ruby- и JavaScript-разработчиков вылился в создание нескольких «семейств» CSS-препроцессоров, а также целых фреймворков на их основе.

В большинстве своем препроцессоры CSS преследуют схожие цели: унификация браузерных префиксов и хаков, упрощение синтаксиса, вложенность селекторов и привнесение в описания стилей базовой логики. Таким образом, вместо сугубо декларативного перечисления свойств появляется возможность описывать стили, используя подходы и приемы, характерные для «полноценных» языков программирования: переменные, миксины (некоторое подобие шаблонных наборов свойств, позволяющее подстановки и замены внутри себя), а также циклы, условия и несложную математику.

В настоящее время многие из этих приемов понемногу переносятся в спецификации самого CSS (например, calc() уже поддерживается большинством современных браузеров, в ближайшем будущем в CSS ожидаются миксины, переменные, задаваемые с помощью @var, и многие другие вкусняшки), но неторопливость W3C никуда не делась, а препроцессоры все это обеспечивают уже сейчас и обеспечивают прекрасную кросс-браузерность получаемых на выходе стилей.

 

Sass

Препроцессор Sass начал свой путь в 2007 году как часть HTML-шаблонизатора Haml для Ruby on Rails. Вдохнув в CSS-разметку новую жизнь, он быстро завоевал симпатии рубистов, несмотря на отсутствие каких-либо средств отладки и необходимость привыкать к нестандартному «своему» синтаксису. В ранних версиях создатели Sass Хэмптон Кэтлин и Натан Вайценбаум вместе с примкнувшим к ним впоследствии Крисом Эпштейном заложили в него многое из того джентльменского набора, что сегодня в том или ином виде сопровождает все CSS-препроцессоры: переменные, вычисления, вложенные селекторы и миксины (в ранних версиях, правда, статические, и не позволяющие подстановку аргументов). По мере взросления функциональность Sass существенно расширялась и дополнялась.

Переменные

То, чего сильно не хватало оригинальному CSS, — переменные в Sass записываются с помощью символа $ и позволяют хранить строки, цвета, булевы значения и даже целые списки свойств:

SASS
$red: #FF4848
$narrow: 45px
$article_text: 1.5em, Helvetica, Arial, sans-serif

Строго говоря, переменные в Sass скорее являются константами: после присвоения значение переменной изменить нельзя. Подставлять переменные можно в любые свойства, также их можно использовать в вычислениях и некоторых интересных встроенных функциях Sass. Например, для работы с цветом есть отличные darken() и lighten():

SASS
$red: #FF5050
h1
  color: $red
p
  color: darken($red, 10%)

CSS
h1 {
  color: #ff5050;
}
p {
  color: #ff1d1d;
}

Встроенных функций в Sass множество, они позволяют работать с числами, строками (и прочими известными Sass типами данных) не хуже полноценного ЯП. Полный список функций можно найти в документации Sass.

Вложенность

Sass выводит работу с CSS-селекторами на качественно новый уровень, позволяя отступами в коде указывать их вложенность. В результате вместо утомительного перечисления родительских селекторов

CSS
div.toplevel{
    // Какие-то свойства родителя
}
div.toplevel p {
    // Свойства вложенного элемента
}
div.toplevel p ul {
    // Свойства самого глубоко вложенного элемента
}

мы можем записать все гораздо компактнее и проще:

SASS
div.toplevel
  // Какие-то свойства родителя
  p
    // Свойства вложенного элемента
    ul
      // Свойства самого глубоко вложенного элемента

Главное — не поддаваться на провокацию легкости описания и не забывать, что излишней вложенностью CSS-селекторов можно ощутимо затормозить парсинг CSS в браузере.

Импорт

Еще одним долгожданным нововведением в Sass стал импорт файлов. Организован импорт очень просто: имя подключаемого файла (в идеологии Sass такие файлы называются partials) должно начинаться с нижнего подчеркивания, а для его включения в основном файле нужно вызвать директиву @include и указать относительный путь к подключаемому файлу. При этом нижнее подчеркивание и расширение файла можно опустить.

SASS
// Подключаем _buttons.sass
@import 'buttons'

Кроме очевидного повторного использования кода, импорты позволяют структурировать и организовывать код, что особенно актуально для больших проектов.

Вычисления и миксины

Миксины в Sass — главный генератор восторга и слез умиления у суровых бородатых кодеров. Представляя собой некоторое подобие функций, присущих «большим» языкам программирования, миксины позволяют использовать принцип DRY на полную катушку: описывать заранее наборы CSS-правил и подставлять их в любое место легким движением руки:

SASS
// Описываем сам миксин c помощью знака =
=rectangle-block($x, $y)
  display: block
  width: $x
  height: $y
// и подключаем в любой список свойств:
.square
  +rectangle-block(50px, 50px)
  background-color: red
.long
  +rectangle-block(120px, 10px)
  background-color: blue

На выходе получим вот такой CSS:

CSS
.square {
  display: block;
  width: 50px;
  height: 50px;
  background-color: red;
}
.long {
  display: block;
  width: 120px;
  height: 10px;
  background-color: blue;
}

А ведь Sass еще и поддерживает разнообразные вычислительные и логические операции с известными ему типами данных: например, с размерами (height: ($size + 40px) / 2) или цветами ($base-color - #404040)!

 

INFO

При некоторой сноровке и уйме свободного времени на Sass можно реализовать, например,пузырьковую сортировку. Красиво, бесполезно, работает…

Говоря о Sass, нельзя не упомянуть, что на его основе было создано немало библиотек и целых фреймворков, особое место среди которых занимает Compass, разработанный одним из соавторов Sass Крисом Эпштейном. Compass предоставляет в твое распоряжение отличную подборку CSS3-миксинов (да-да, можно окончательно забыть про все проблемы с префиксами), актуальный reset всех встроенных браузерных стилей, средства для создания различных grid’ов и layout’ов. Чтобы не показалось мало, Compass также обеспечивает разработчика внушительным количеством всяческих утилит и хелперов: средствами для работы с типографикой и шрифтами, расширенной математикой и тригонометрией и многим другим.

 

INFO

В ответ на твит небезызвестной в мире CSS Лии Веру о поисках браузерного компилятора Sass, реализация libsass для C была портирована на JavaScript при помощи emscripten. Теперь при помощи получившейся либы Sass.js Sass и SCSS можно исполнять прямо в браузере!

 

Less

В 2009 году Алексис Селье представляет миру новый инструмент для более гибкой работы со стилями под названием Less. Первая реализация была разработана Алексисом на Ruby, и это означало, что у Sass появился конкурент.

Ходят разговоры, что Less был создан под влиянием Sass. Возможно, так оно и есть, но у детища Селье было преимущество в виде поддержки нативного CSS-синтаксиса, что после уже повлияло на Sass и на зарождение его нового синтаксиса SCSS, который также позволял использовать CSS-синтаксис.

В это время Node.js начал набирать обороты. Алексис, чувствуя тенденцию, решает переписать Less на JavaScript и преподносит подарок на День защитника Отечества в видеinitial-коммита.

Less довольно быстро начал обретать популярность, Twitter заюзал его в своем фреймворке Bootstrap, звездочки и форки в GitHub росли. По данным опроса сайта css-tricks.com в 2012 году, 51% из всех, кто пользуется препроцессорами, отдают свое предпочтение Less, Sass + SCSS — 41%, Stylus — 6%, другим — 2%.

Он не испытывает проблем с подсветкой синтаксиса в различных редакторах, также нет проблем и со встраиванием во всевозможные сборщики, начиная Grunt и заканчивая ENB. Нет проблем и c GUI-приложениями для сборки на разных платформах: Mac, Windows и других.

В мае 2012 года Алексис передает контроль над разработкой и развитием проекта команде, и, на мой взгляд, это скорее плюс, чем минус, так как спустя месяц после принятия этого решения активность разработки над проектом возросла. Ребята даже сделали новый сайт, который хорошо и понятно структурирован, как, впрочем, и документация.

Теперь Less может работать как на сервере под Node.js или Rhino, так и на клиенте. Отмечу, что с кросс-браузерностью особых проблем не наблюдалось, он нормально заводился и работал даже в IE6. Поэтому некоторые ленивые разработчики использовали его на клиенте без особых плясок с бубном: подключил JS-файл и пиши себе спокойно, не нужно поднимать Node.js, настраивать вотчеры, решать иные проблемы (что с производительностью у такого подхода, тебе, думаю, очевидно :)).

Основные возможности и фичи

Активность — это хорошо, а какие плоды этой активности появились в самом препроцессоре? Что, например, предлагает Less для работы с CSS3? Градиенты, анимации, скругления, трансформации, транзишены в суровых реалиях вендорных префиксов добавляют немало работы. А какие-нибудь хелперы для рутинных задач, например перевод изображений в Base64 или автосборка спрайтов?

Перед тем как я расскажу, что есть из фич, хочется кратко озвучить основные возможности Less.

Переменные

Переменные — они и в Африке переменные. Удобно использовать для объявления имени основных шрифтов, цветов.

Миксины

Позволяют выделить повторяющиеся куски кода, также могут принимать входящие аргументы. Любопытно, что есть свойство @arguments, как в JavaScript.

Удобно использовать для создания своих «функций».

LESS
.b-pretty-text (color, family, size) {
  color: @color;
  font-family: “family”;
  font-size: size;
}
.b-pretty-text-1 {
  .b-pretty-text(‘red’, ‘Comic Sans’, ‘27px’)
}

CSS
.b-pretty-text-1 {
  color: #ff0000;
  font-family: "Comic Sans";
  font-size: 27px;
}

Расширение

Позволяет расширить текущее правило правилом, указанным в расширении. Основное отличие расширения от миксинов в том, что миксины позволяют пробрасывать дополнительные параметры, а расширение не дублирует код за счет наследования стилей в CSS.

LESS
.b-message {
  color: black;
  background-color: green;
  background-image: url(‘/i/foo.png’);
  background-repeat: no-repeat;
}
.b-message-error {
  &:extend(.b-message);
  color: white;
  background-color: green;
}

CSS
.b-message,
.b-message-error {
    color: black;
    background-color: green;
    background-image: url(‘/i/foo.png’);
    background-repeat: no-repeat;
}
.b-message-error {
    color: white;
    background-color: green;
}

Импорт

Подключает внешние валидные файлы Less, CSS

Гуарды (guards)

Позволяют декларировать условие, по которому меняется результат выполнения правила для селектора.

LESS
.b-chameleon (@val) when (lightness(@val) >= 50%) {
  background-color: black;
}
.b-chameleon (@val) when (lightness(@val) < 50%) {
  background-color: white;
}
.b-chameleon (@val) {
  color: @val;
}
.b-foo { .b-chameleon(#ddd) }
.b-bar { .b-chameleon(#555) }

CSS
.b-foo {
  background-color: black;
  color: #dddddd;
}
.b-bar {
  background-color: white;
  color: #555555;
}

Мердж

Соединение в одно свойство двух свойств.

LESS
.b-button() {
  box-shadow+: inset 0 0 10px #555;
}
.b-button-next {
  .b-button();
  box-shadow+: 0 0 20px black;
}

CSS
.b-button-next {
  box-shadow: inset 0 0 10px #555, 0 0 20px black;
}

Вложенность правил, конкатенация

Простой пример использования, вариации можно посмотреть в разделе Parent Selectors.

LESS
.b-popup {
  positon: fixed;
  padding: 20px;
  &__close {
      color: red;
  }
  .b-button {
      position: absolute:
      bottom: 20px;
  }
}

CSS
.b-popup {
  positon: fixed;
  padding: 20px;
}
.b-popup__close {
  color: red;
}
.b-popup .b-button {
  position: absolute:
  bottom: 20px;
}

Теперь снова можно вернутьcя к фичам. Так вот, на последние два вопроса ответ простой — перевод изображений в Base64 появился в версии 1.4, я в свое время активно работал с версией 1.3, и этой фичи чертовски не хватало, а вот автосборки спрайтов из коробки нет.

Библиотеки

Что касается упрощения работы с CSS3, то тут на помощь приходит 3rd party библиотекаLESS Hat — лучшее, что сейчас есть для этих целей. Она покрывает большинство кейсов, которые возникают при работе с CSS3, позволяет гибко передавать параметры в миксины и делает всю работу за тебя.

Устроена по схожему принципу с LESS Elements. Правда, сходство только в том, что это тоже набор миксинов; таких проблем, как при использовании LESS Elements, не возникает. Решим ту же задачу:

LESS
@import ‘lesshat.less’;
.b-button {
  // Добавляем еще один шаг для отрисовки градиента. Никаких проблем
  .background-image(linear-gradient(to bottom, #fb83fa 0%, red 50%, #e93cec 100%))
}

CSS
.b-button {
  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIx$
  background-image: -webkit-linear-gradient(top, #fb83fa 0%, #ff0000 50%, #e93cec 100%);
  background-image: -moz-linear-gradient(top, #fb83fa 0%, #ff0000 50%, #e93cec 100%);
  background-image: -o-linear-gradient(top, #fb83fa 0%, #ff0000 50%, #e93cec 100%);
  background-image: linear-gradient(to bottom, #fb83fa 0%, #ff0000 50%, #e93cec 100%);
}

Так в чем же хитрость LESS Hat? Как они реализовали гибкость вызовов миксинов? Все просто. В Less мы можем исполнять JavaScript в процессе обработки стилей, и авторы библиотеки парсят входные данные в миксин и преобразуют их в нужный вид.

Кстати, миксины библиотеки не пишутся руками, а описываются в JS-файлах в определенном формате. Сами Less-миксины создаются на основе этих файлов с помощью сборки Grunt.

Отмечу как плюс, что данный подход позволил им покрыть тестами результат работы библиотеки.

Заключение

В общем и целом Less — хороший инструмент; в свое время он страдал от недостатка внимания со стороны разработчиков, и ему не хватало библиотеки для работы с CSS3. Сейчас эти проблемы отходят на задний план, и пару Less + LESS Hat можно рассматривать как один из кандидатов в стеке технологий фронтенд-разработчика.

 

Stylus

Первый релиз Stylus состоялся 31 января 2011 года, и практически следом за ним зарелизилась библиотека Nib, упрощающая работу с CSS3 и решающая проблему контроля вендорных префиксов.

Автором Stylus и, что немаловажно, Nib является небезызвестный TJ Holowaychuk, который описывает Stylus как революционно новый язык. Неясно, правда, что именно в нем революционного: по возможностям он примерно на одном уровне с Sass и Less.

Stylus было не так сложно отвоевать свою часть рынка, так как многие разработчики были знакомы с хорошо зарекомендовавшими себя проектами TJ Holowaychuk (Express, Jade, Mocha). Также немалую роль сыграло то, что в комплекте шел Nib. Приобретенная популярность сыграла свою роль, и вот уже многие IDE поддерживают синтаксис Stylus, системы сборки знают, как и чем собирать его, для Connect написан middleware для исполнения в runtime.

В проекте на текущий момент 113 контрибьютеров, которые активно пилят, в том числе есть разработчики из России, ребята из Яндекс.Почты (кстати, в Почте используется Stylus).

Да, у Stylus определенно есть свои плюсы, он изначально разрабатывался на JavaScript, есть возможность использовать несколько синтаксисов: индентный Ruby-стайл и классический CSS. Также можно отнести к плюсам, что у препроцессора и библиотеки один автор, который явно понимал ее важность и необходимость.

Основные возможности и фичи

У Stylus есть пара примечательных отличий от его коллег по цеху. Первая из них — это возможность получать значения свойств в контексте одного правила:

Stylus
.b-popup {
    position: fixed;
    top: 50%;
    height: 200px;
    margin-top: -(@height / 2);
}

Вторая — это неявный вызов миксинов, что добавляет синтаксису Stylus элегантность и читаемость. Хотя, с другой стороны, из-за этой фичи может пострадать понимание кода, смотри пример, и сам все поймешь:

Stylus
// Объявляем миксин
background() {
    background: #ffffff;
}
.b-button {
    // Неявно вызываем его
    background: #000000;
}

CSS
.b-button {
    background: #fff;
}

В остальном Stylus похож на своих конкурентов. Он так же, как и Less, может выполняться в браузере, может переводить изображения в Base64, так же, как и у Sass, есть автосборка спрайтов (3rd party), имеет схожие базовые возможности: переменные, миксины, расширение, импорт, ветвление, вложенность правил, конкатенация (кстати, у Sass этой возможности нет).

Хочется показать пример использования автосборки спрайтов (в свое время прочитал об этой фиче у команды разработки Facebook и был впечатлен, теперь и ты можешь использовать ее):

Stylus
$animated_flame = sprite-map('flame')
#flame
  background: url(sprite-url($animated_flame)) no-repeat
  height: sprite-height($animated_flame, 'flame_a_0001')
  width: sprite-width($animated_flame, 'flame_a_0001')
.flame-frame-1
  background-position: sprite-position($animated_flame, 'flame_a_0001')
.flame-frame-2
  background-position: sprite-position($animated_flame, 'flame_a_0002')

CSS
#flame {
  background: url(../images/flame-4e9c94d3fa.png) no-repeat;
  height: 512px;
  width: 512px;
}
.flame-frame-1 {
  background-position: 0 0;
}
.flame-frame-2 {
  background-position: 0 -512px;
}

Библиотеки

У Stylus есть флагманская библиотека, о которой я уже не раз говорил, — это Nib, но можно посмотреть и на милые альтернативы Dookie и Roots Axis.

Nib — помимо средств нормализации работы с CSS3 (gradients, box-shadow, transform, transition, animation…) есть еще и утилиты обнуления свойств дефолтных стилей браузера (с возможностью обнулять свойства по группам, например font, использовать clearfix и другое). Все наборы разбиты по группам, что дает возможность подключать конкретно то, что нужно.

Stylus
@import 'nib';
.b-button {
    background: linear-gradient(top, white, black);
}

CSS
.b-button {
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(1, #000));
    background: -webkit-linear-gradient(top, #fff 0%, #000 100%);
    background: -moz-linear-gradient(top, #fff 0%, #000 100%);
    background: linear-gradient(top, #fff 0%, #000 100%);
}

Dookie — набор полезных миксинов, призванных избавить тебя от рутинной работы с CSS3 и не только. В составе есть: reset, normalize, CSS3, странный сахар.

Roots Axis является частью более крупного тулкита лучших решений. По возможностям похож на Dookie, тоже имеет свой странный сахар, но еще есть более странное решение под названием buttons (стили для кнопок) и ui (стили для блоков нотификаций).

Заключение

Stylus — гибкий препроцессор, с активным сообществом, мощными библиотеками и с большим количеством 3rd party решений. У него светлое будущее, скорее даже уже светлое настоящее. Определенно лидер в гонке препроцессоров.

 

Оставить мнение

Check Also

Скрытая сила пробела. Эксплуатируем критическую уязвимость в Apache Tomcat

В этой статье мы поговорим о баге в Apache Tomcat, популярнейшем веб-сервере для сайтов на…