Почему мы стали использовать препроцессор Stylus в Яндекс.Почте, а также о библиотеке, помогающей жить с IE

Если вы часть Front-End сцены, вы, возможно, слышали о Stylus, дальнем родственнике препроцессорного языка Sass, которого никто толком не знает. Как и Sass, Slylus является CSS препроцессором, написанном в Node.js. Согласно данным веб-сервиса GitHub, он определяет себя как:

[…] революционно новый язык, обеспечивающий эффективный, динамический и экспрессивный способ создания CSS.

Ну, допустим, что использование слова «революционный» здесь немного преувеличено. Но все остальное, правда. «Что? Еще один?»- спросите Вы. «Своего рода», - отвечу я. Но, Stylus совершенно не новый язык. Он начал свое существование примерно с начала 2011 года, но, как я успел заметить, мнение о нем довольно разнится. Кстати, знаете ли вы, что последние изменения в Mozilla Developer Network были сделаны при помощи Stylus? Дэвид Уолш, занимавшийся проектом, также написал о том, как начать работу со Stylus.

Итак, каковы преимущества Stylus перед Sass? Во-первых, он разработан на базе Node.sj, что для меня лично является плюсом. И как бы это и здорово, что можно использовать Sass в рабочем процессе Node, благодаря Sass wrapper для LibSass, однако, нельзя сказать того же самого о LibSass, написанном в Node.

К тому же, Slylus имеет чрезвычайно податливый синтаксис, который может быть хорошим или плохим в зависимости от проекта, команды и тенденции придерживаться строгих принципов кодирования. Я думаю, что податливый синтаксис это неплохо, конечно, если вы не начнете «привлекать» слишком много логики к таблице стилей, и поставили код, прежде чем совершить это.

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

Итак, что вы думаете? Хотите попробовать?

Начинаем

Как отмечалось ранее, Slylus написан в Node.js, чтобы мы могли установить его, как любой другой пакет npm:

$ npm install stylus -g

Оттуда, вы можете подключить его в рабочий процесс Node с использованием JavaScript API, или вы можете использовать командную строку command line executable, чтобы составить таблицы стилей. Ради простоты, мы будем использовать инструмент командной строки Stylus, но, не стесняйтесь взять его у Node script, Gulp или Grunt

stylus ./stylesheets/ --out ./public/css

Предыдущая команда сообщает Stylus, чтобы собрать все Stylus стили (.styl) из папки stylesheetsи собрать их в папке public/css. Конечно, вы также можете посмотреть каталог, если хотите внести изменения:

stylus --watch ./stylesheets/ --out ./public/css

Написание стилей в Stylus

Если вы только начали, и не хотите перегружать себя новым синтаксисом, знайте, что вы можете написать простой CSS в файле.styl . Так как Stylus поддерживает стандартный синтаксис CSS, то можно начать с CSS кода, только чтобы усилить его немного.

Основной синтаксис

Что касается самого синтаксиса, то там почти все по желанию. Фигурные скобки: зачем беспокоиться? Двоеточия: давай! Запятые: да, кому они нужны! Скобки: пожалуйста. Ниже идеально правильный код Stylus:

Foo .bar color tomato background deepskyblue

Что-то вроде нарушения на первый взгляд, но мы можем привыкнуть к нему, особенно, когда доступны синтаксические маркеры. Как вы, вероятно, догадались, предыдущий код компилируется в:

Foo, .bar { color: tomato; background: deepskyblue; }

Переменные

Наиболее часто используемая функция от CSS препроцессоров должна иметь возможность определять переменные. Это не удивительно, что Slylus предлагает и это тоже. Хотя в отличие от Sass, они выражаются знаком равенства (=), а не двоеточием (:). Кроме того, знак доллара ($) не является обязательным и может быть спокойно опущен.

//Определяем переменную `text-font-stack` text-font-stack = "Helvetica", "Arial", sans-serif; // Используем ее, как часть свойства `font` body font 125% / 1.5 text-font-stack

Теперь есть кое-что, что Stylus делает, а Sass или любой другой препроцессор не делают: поиск величины свойства. Допустим, вы хотите применить отрицательное левое поле в половину ширины; в Sass вам придется сохранить ширину в переменной, но не в Stylus:

При использовании @width, мы говорим Stylus получить значение width

свойства текущего блока, рассматривая его в качестве переменной. Довольно просто! Еще один интересный вариант использования, это выводить свойство в зависимости от того, было ли оно определено ранее:

Foo // ... other styles z-index: 1 unless @z-index

В этом случае, z-index будет иметь значение 1, если только ранее.foo уже не имело установленное значение для свойства z-index. В паре с mixins(примеси) это будет сильный ход.

Mixins (примеси)

Говоря об этом, давайте определим что такое «примесь» , так как это, вероятно, один из самых популярных функций Sass! Примесь в Stylus не нуждается в определенном ключевом слове; это примесь, если она имеет скобки (пустые или нет) в конце своего имени.

Size(width, height = width) width width height height

Также как и в первом случае, чтобы включить примесь, не нужно специального синтаксиса, как например, @include или +:

Foo size(100px)

Вы даже можете опустить скобки, если вы хотите, в этом случае, это будет похоже на то, что вы полностью используете стандартное (еще не) CSS свойство. Этот механизм называют прозрачные примеси, так как их включения невидимы.

Foo size 100px

Это может выглядеть ненужным трюком, на первый взгляд, но на самом деле эта функция позволяет авторам расширить стандартный синтаксис CSS. Рассмотрим следующую overflow примесь:

Overflow(value) if value == ellipsis white-space nowrap overflow hidden text-overflow ellipsis else overflow: value

Если данное значение - это ellipsis, он печатает хорошо известный декларационный триплет, необходимый, чтобы иметь одну строку, переполненную многоточием. Иначе, она печатает заданное значение. Вот как вы будете использовать его:

Foo overflow ellipsis

И это даст:

Foo { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

Вы должны признать, что это довольно крутой трюк. Хотя он может быть запутанным (и, возможно, опасным); быть в состоянии расширить стандартные свойства CSS с дополнительными значениями на самом деле интересная концепция.

Если вы хотите передать некоторое содержание в примесь, в стиле @content, это, возможно, через {block} переменную. Во время включения, вам нужно только поставить перед именем примеси +, чтобы передать ему дополнительное содержание.

Has-js() html.js & {block} .foo +has-js() color red

Этот код скомпилирован в:

Html.js .foo { color: #f00; }

Последняя и очень интересная особенность примесей Stylus: они всегда имеют локальную переменную arguments, содержащий все аргументы (если таковые имеются), которые передаются в примеси, когда они туда включены. Этой переменной можно манипулировать и рассматривать как массив, например, для извлечения значения в конкретных индексах с помощью сочетания [..] как в JavaScript.

И в заключении…

Исследовать все особенности и синтаксические трюки от Stylus было бы слишком долго, и я думаю, что мы уже сделали приличное введение, достаточно, чтобы начать по крайней мере!

Как вы можете видеть, Stylus очень податливый. Из всех существующих инструментов, которые могут помочь написать CSS, Stylus, безусловно, единственный, приближающий CSS к реальному языку программирования.

Обратите внимание, что Stylus, также имеет собственную инфраструктуру, как Sass имеет Compass, и называется он Nib. Nib - это инструменты, обеспечивающие дополнительных помощников и кросс-браузеров поддерживающих примеси для Stylus.

Некоторым людям это, возможно, понравится, а некоторым нет. Хотя мой совет - быть очень строгим с синтаксисом. Работа с таким толерантным синтаксисом не всегда может быть счастьем. В любом случае, приятно видеть здоровую конкуренцию Sass.

Сегодня я хочу рассказать о том, почему и как мы пришли к использованию препроцессора Stylus в разработке Яндекс.Почты, а также описать используемый нами метод работы со стилями для IE. Он очень легко реализуется именно с помощью препроцессоров и делает поддержку IE простой и удобной. Мы разработали для этого специальную библиотеку, которой тоже поделимся - if-ie.styl .

Это только первая статья из серии статей об использовании препроцессора Stylus в Яндекс.Почте, которые мы готовим к публикации.

Как мы пришли к использованию препроцессоров Хотя внешне Яндекс.Почта выглядит как одностраничное приложение, внутри неё содержится огромное число всевозможных блоков, их модификаций и контекстов, в которых эти блоки и модификации могут оказаться.

Кроме того, у неё уже больше тридцати тем оформления. Есть темы со светлым фоном и с тёмным, есть темы, которые различаются между собой только цветами, а есть и такие, в которых почти весь интерфейс вылеплен из пластилина вручную (http://habrahabr.ru/company/yandex/blog/110556/). В некоторых темах только одно фоновое изображение, а в других фон может меняться - случайно или в зависимости от времени суток и погоды.

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

Когда мы только запускали интерфейс «neo2», мы выбрали знакомое нам решение - шаблонизатор Template Toolkit 2, с несколько нестандартным сценарием его использования для генерации CSS, а не HTML. Поначалу нам были нужны только переменные, но со временем темы усложнялись, и в итоге оказалось, что такой инструмент неудобен. Громоздкий синтаксис, отсутствие специализированных под CSS функций и общее чувство использования инструмента не по назначению заставили искать другие варианты. Мы поняли, что нам не обойтись без препроцессора.

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

В Stylus есть ещё много очень разных полезных вещей, но именно приведённые выше заставили нас сделать выбор в его пользу.

Конечно, кроме преимуществ, у Stylus есть и недостатки. И основной из них - гибкий синтаксис - авторы препроцессора считают его главным достоинством. Погнавшись за гибкостью, они целиком реализовали только синтаксис, основанный на отступах, тогда как вариант «а-ля CSS» кое-как прикручен сверху, и не получится просто так взять и переименовать.css в.styl - не все варианты написания CSS заработают и в Stylus. Но мы решили, что возможности, которые даёт нам этот препроцессор, делают его недостатки не такими значительными, поэтому пришлось смириться с некоторой капризностью парсера (и начать использовать синтаксис, основанный на отступах).

Подытоживая рассказ про выбор, стоит отметить, что Sass и Stylus - два почти равнозначных варианта. Каждый из них имеет как свои преимущества и уникальные фичи, так и недостатки. Если вы уже используете какой-то из этих препроцессоров и вас всё устраивает - отлично, можно не думать о поиске нового. Но если вы только подходите к выбору или же с используемым препроцессором вам становится тесно, попробуйте сравнить все варианты. Лучший способ это сделать - примерить каждый препроцессор к своей задаче. Сверстав часть вашего проекта на каждом из препроцессоров, вы поймёте, какие их возможности вам важны, а какие - нет. Только не забывайте, что препроцессор - это не просто другой синтаксис, но и другой подход: при подобной перевёрстке можно заодно и отрефакторить код, сделав что-то оптимальнее, чем было с простым CSS.

Однако нужно рассказать ещё про одну функцию, которая оказалась нам очень полезна в рамках тематизации Яндекс.Почты. Это функция rgba-ie . На самом деле эта функция могла бы называться просто rgba , но в Stylus есть баг: функции, определённые в JS, не получается переопределять так же, как те, что были определены в Stylus, так что тут пришлось создать новую.

Что же она делает? Старые IE не поддерживают значения цвета, заданные в формате rgba. Поэтому обычно разработчики либо прописывают соответствующие цвета дважды - сначала для старых IE в обычном hex-формате, а потом уже всем нормальным браузерам в желаемом rgba - либо используют modernizr и уже с помощью него и класса.rgba задают соответствующие цвета там, где это нужно. Но для фолбеков в IE каждый раз всё равно приходится вычислять примерный цвет того, во что мы будем в нём деградировать. Чаще всего это будет нужный цвет, наложенный поверх фона страницы или среднего фона элемента, над которым будет применён цвет в rgba .

Функция rgba-ie из if-ie.styl сильно упрощает эту задачу: дублируя возможности обычной функции rgba , мы получаем ещё один опциональный параметр, который можно передать в функцию - цвет фона для фолбека. По умолчанию этот параметр задан в #FFF .

Простой пример:

Foo color: rgba-ie(0,0,0,0.5)

В обычных браузерах этот цвет будет обычным rgba(0,0,0,0.5) , но в IE он превратится в #808080 - то есть в соответствующий цвет, наложенный поверх белого.

Более сложный пример, с целевым фоном в качестве последнего аргумента (и с использованием одной из фич Stylus - возможности указать вместо трёх цифр r , g и b цвет в hex):

Foo background: rgba-ie(#FFDE00, .42, #19C261)

В этом примере для нормальных браузеров будет цвет rgba(255,222,0,0.42) , а вот IE получит правильный #7ace38 .

При этом есть возможность задать и фолбек по умолчанию с помощью переменной $default_rgba_fallback .

В итоге можно очень сильно упростить себе жизнь, если использовать функцию rgba-ie вместо обычного rgba - об IE в этом случае можно будет почти не вспоминать.

Теги:

Добавить метки

Абсолютно все опытные верстальщики используют препроцессоры. Исключений нет. Если вы хотите добиться успеха в этой деятельности, не забывайте об этих программах. С первого взгляда они могут вызвать у новичка тихий ужас - это уже слишком похоже на программирование! На самом деле можно разобраться со всеми возможностями препроцессоров CSS примерно за день, а если постараться, то и за пару часов. В дальнейшем они существенно упростят вам жизнь.

Как появились препроцессоры CSS

Чтобы лучше понять особенности этой технологии, ненадолго погрузимся в историю развития визуального представления веб-страниц.

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

В 1994 году норвежский ученый Хокон Ли разработал таблицу стилей, которая могла использоваться для оформления внешнего вида страницы отдельно от HTML-документа. Идея приглянулась представителям консорциума W3C, которые тотчас же принялись за ее доработку. Спустя несколько лет вышла в свет первая версия спецификации CSS. Затем она постоянно совершенствовалась, дорабатывалась… Но концепция оставалась все той же: каждому стилю задаются определенные свойства.

Использование таблиц CSS всегда вызывало определенные проблемы. Например, у верстальщиков часто возникали трудности с сортировкой и группировкой свойств, да и с наследованием не все так однозначно.

И вот наступили двухтысячные. Разметкой все чаще начали заниматься профессиональные фронтенд-разработчики, для которых важна была гибкая и динамическая работа со стилями. Существовавший на тот момент CSS требовал расстановки префиксов и отслеживания поддержки новых возможностей браузеров. Тогда специалисты по JavaScript и Ruby взялись за дело, создав препроцессоры - надстройки для CSS, добавляющие в него новые возможности.

CSS для начинающих: особенности препроцессоров

Они выполняют несколько функций:

  • унифицируют браузерные префиксы и хаки;
  • упрощают синтаксис;
  • дают возможность работать с вложенными селекторами без ошибок;
  • улучшают логику стилизации.

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

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

Популярные препроцессоры CSS. Sass

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

Объявление переменных в Sass

Переменные объявляются с помощью знака $. В них можно сохранять свойства и их наборы, например: “$borderSolid: 1px solid red;”. В этом примере мы объявили переменную под названием borderSolid и сохранили в ней значение 1px solid red. Теперь, если в CSS нам потребуется создать красный border шириной в 1px, просто указывает эту переменную после названия свойства. После объявления переменные менять нельзя. Доступно несколько встроенных функций. Например, объявим переменную $redColor со значением #FF5050. Теперь в коде CSS, в свойствах какого-нибудь элемента, используем ее для задания цвета шрифта: p { color: $redColor; }. Хотите поэкспериментировать с цветом? Используйте функции darken или lighten. Это делается так: p { color: darken($redColor, 20%); }. В результате цвет redColor станет на 20 % светлее.

Вложенность

Раньше для обозначения вложенности приходилось использовать длинные и неудобные конструкции. Представим, что у нас есть div, в котором лежит p, а в нём, в свою очередь, расположен span. Для div нам нужно задать цвет шрифта red, для p - yellow, для span - pink. В обычном CSS это делалось бы следующим образом:

С помощью препроцессора CSS все делается проще и компактнее:

Элементы буквально «вкладываются» один в другой.

Директивы препроцессора

С помощью директивы @import можно импортировать файлы. Например, у нас есть файл fonts.sass, в котором объявлены стили для шрифтов. Подключаем его в основной файл style.sass: @import ‘fonts’. Готово! Вместо одного большого файла со стилями у нас есть несколько, которые можно использовать для быстрого и легкого доступа к требуемым свойствам.

Миксины

Одна из самых интересных задумок. Дает возможность одной строкой задавать целый набор свойств. Работают следующим образом:

@mixin largeFont {

font-family: ‘Times New Roman’;

font-size: 64px;

line-height: 80px;

font-weight: bold;

Чтобы применить миксин к элементу на странице, используем директиву @include. Например, мы хотим применить его к заголовку h1. Получается следующая конструкция: h1 { @include: largeFont; }

Все свойства из миксина будут присвоены элементу h1.

Препроцессор Less

Синтаксис Sass напоминает о программировании. Если вы ищете вариант, который больше подходит изучающим CSS для начинающих, обратите внимание на Less. Он был создан в 2009 году. Главная особенность - поддержка нативного так что незнакомым с программированием верстальщикам его будет проще освоить.

Переменные объявляются с помощью символа @. Например: @fontSize: 14px;. Вложенность работает по тем же принципам, что и в Sass. Миксины объявляются следующим образом: .largeFont() { font-family: ‘Times New Roman’; font-size: 64px; line-height: 80px; font-weight: bold; }. Для подключения не нужно использовать директивы препроцессоров - просто добавьте свежесозданный миксин в свойства выбранного элемента. Например: h1 { .largeFont; }.

Stylus

Еще один препроцессор. Создан в 2011 году тем же автором, что подарил миру Jade, Express и другие полезные продукты.

Переменные можно объявлять двумя способами - явно или неявно. Например: font = ‘Times New Roman’; - это неявный вариант. А вот $font = ‘Times New Roman’ - явный. Миксины объявляются и подключаются неявно. Синтаксис таков: redColor() color red. Теперь можем добавить его элементу, например: h1 redColor();.

На первый взгляд Stylus может показаться непонятным. Где «родные» скобки и точки с запятой? Но стоит только в него погрузиться, как все становится намного более ясным. Однако помните, что длительная разработка с этим препроцессором может «отучить» вас использовать классический синтаксис CSS. Это иногда вызывает проблемы при необходимости работать с «чистыми» стилями.

Какой препроцессор выбрать?

На самом деле это… не имеет значения. Все варианты предоставляют примерно одинаковые возможности, просто синтаксис у каждого разный. Рекомендуем действовать следующим образом:

  • если вы - программист и хотите работать со стилями как с кодом, используйте Sass;
  • если вы - верстальщик и хотите работать со стилями как с обычной версткой, обратите внимание на Less;
  • если вы любите минимализм, воспользуйтесь Stylus.

Для всех вариантов доступно огромное количество интересных библиотек, способных еще сильнее упростить разработку. Пользователям Sass рекомендуется обратить внимание на Compass - мощный инструмент с множеством встроенных возможностей. Например, после его установки вам уже никогда не придется беспокоиться о вендорных префиксах. Упрощается работа с сетками. Имеются утилиты для работы с цветами, спрайтами. Доступен ряд уже объявленных миксинов. Уделите этому средству пару дней - тем самым вы сэкономите немало сил и времени в будущем.

  • Сергей Савенков

    какой то “куцый” обзор… как будто спешили куда то