Что такое программа stylus

Если вы часть 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:

Оттуда, вы можете подключить его в рабочий процесс 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 кода, только чтобы усилить его немного.

Аналоги Apple Pencil

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

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

.foo .bar color tomato background deepskyblue

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

.foo, .bar

Переменные

Наиболее часто используемая функция от 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:

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

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

Mixins (примеси)

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

size(width, height = width) width width height height
.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

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

has-js() html.js https://lpgenerator.ru/blog/2016/03/08/znakomimsya-so-stylus/» target=»_blank»]lpgenerator.ru[/mask_link]

Stylus — препроцессор CSS

bg

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

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

Синтаксис Stylus

Сравним CSS и Stylus — слева синтаксис Stylus, справа синтаксис CSS

1

Визуальные отличия от синтаксиса CSS
  1. Не нужны фигурные скобки
  2. Не нужны точки с запятой после каждого свойства
  3. Не нужны двоеточия после названия свойства

Тем не менее Stylus воспринимает обычный синтаксис CSS, то есть рядом с синтаксисом Stylus можно вставить обычный CSS

Логические отличия от синтаксиса CSS
  1. Вложенность селекторов осуществляется через отступ Tab
  2. Возможность зависимости от названия родительского класса

Пример 1: Стилизуем ненумерованный список

На CSS это выглядит следующим образом

CSS

ul < padding: 0; margin: 0; >ul li < list-style: none; >ul li a

Чтобы не писать цепочку селекторов от родительского до дочернего, в Stylus используем отступы Tab

Stylus

ul padding 0 margin 0 li // генерируется селектор ul li list-style none a // генерируется селектор ul li a font-size 18px text-decoration underline

Пример 2: Стилизуем навигацию

CSS

.nav < background: #fafafa; >.nav__flex < display: flex; >.nav__item < background: #fff; >.nav__item:not(:last-child) < margin-right: 30px; >.nav__item a < font-size: 18px; text-transform: uppercase; text-decoration: underline; color: #0d3b66; >.nav__item a:hover < text-decoration: none; >.nav__item_active < background: #0d3b66; >.nav__item_active a

Если в обычном CSS решим переименовать родительский селектор .nav в .navigation , то необходимо будет искать все селекторы, которые зависят от него, и каждый переименовывать вручную.

В Stylus существует специальный служебный символ — __flex // генерируется селектор .nav__flex (Элемент по методологии БЭМ) display flex :not(:last-child) // .nav__item:not(:last-child) margin-right 30px a // .nav__item a font-size 18px text-transform uppercase text-decoration underline color #0D3B66 _active // генерируется селектор .nav__item_active (Модификатор по методологии БЭМ) background #0D3B66 a // .nav__item_active a color #fff

Читайте также:
Программа запускается и сразу закрывается

Если в Stylus решим переименовать родительский селектор .nav в .navigation , то нужно будет переименовать только его, а так как дочерние селекторы зависят от наименования родительского селектора, то будут переименованы автоматически

Дополнительные возможности

Переменные

Переменные объявляются следующим образом — название_переменной = значение переменной . Название переменной может состоять просто из слова на английском языке, но предпочитаю имена переменных начинать со знака $ , чтобы не было пересечений с CSS свойствами и визуально было легче воспринимать переменные в файле стилей

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

$main = #0D3B66 $second = #FF5964 $title-size = 48px $padding = 30px

Используем объявленные переменные

$main = #0D3B66 $second = #FF5964 $title-size = 48px $padding = 30px body background $main // генерируется background: #0d3b66; .section font-size $title-size // генерируется font-size: 48px;

Будут сгенерированы следующие CSS стили

body < background: #0d3b66; >.section__body < padding: 30px; >.section__title

Миксины

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

Объявление миксинов — название_миксина(параметр, параметр) , и на следующей строке после отступа Tab указываем свойство или несколько свойств (каждое свойство на отдельной строке)

// Плавный переход из одного состояния элемента в другое tr() transition all .3s ease // Масштабируем изображение на всю область родительского элемента fit() display block width 100% height 100% object-fit cover

Используем объявленные миксины

tr() transition all .3s ease fit() display block width 100% height 100% object-fit cover a color red tr() // генерируется свойство transition: all .3s ease; color: #f00; transition: all 0.3s ease; >a:hover < color: #00f; >.image < width: 400px; height: 300px; >.image img

Также в миксинах можно передавать параметры. Название параметра может быть произвольным словом на английском языке

tr(duration) // duration — продолжительность transition all duration ease a color red tr(.5s) // генерируется свойство transition: all 0.5s ease; color: #f00; transition: all 0.5s ease; >a:hover

Можно передавать несколько параметров через запятую

tr(prop, duration) // prop — свойство, для которого будем применять плавный переход, duration — продолжительность transition prop duration ease a color red tr(color,.5s) // генерируется свойство transition: color 0.5s ease; color: #f00; transition: color 0.5s ease; >a:hover

Можно передавать параметры без указания единиц измерения, а единицы измерения указать внутри миксина

tr(duration) // duration — продолжительность transition all (duration s) ease // в скобках на первом месте — параметр, на втором месте через пробел — единица измерения fontSize(val) font-size val em // если у свойства только одно значение, то можно писать без скобок — на первом месте — параметр, на втором месте через пробел — единица измерения a color red fontSize(2) // генерируется свойство font-size: 2em; tr(.5) // генерируется свойство transition: all 0.5s ease; color: #f00; font-size: 2em; transition: all 0.5s ease; >a:hover

В миксинах можно использовать объявленные переменные и другие объявленные миксины

$main = #0D3B66 fontSize(val) font-size val em button() fontSize(2) color $main a button()

Из примера выше генерируется следующий CSS

За счет такой гибкости, можно настроить множество миксинов, с которыми вам будет комфортно работать

Пока приводил простые примеры, на которых проще понять принцип работы миксинов.

Рассмотрим пример посложнее — сделаем миксин кнопки

$main = #0D3B66 $second = #FF5964 tr() transition all .3s ease btn(height,fontSize) // принимаем два параметра — высота кнопки без единиц измерения, размер шрифта кнопки height height px // подставляем значение параметра высоты и указываем единицу измерения — пиксели font-size fontSize // подставляем значение параметра размера шрифта, параметр будет передаваться с единицами измерения display inline-flex align-items center justify-content center text-align center text-decoration none text-transform uppercase font-weight bold color $second // подставляем значение переменной $second background $main // подставляем значение переменной $main padding 0 (height px) // внутренние боковые отступы будут равняться высоте, подставляем значение параметра высоты border-radius (height/2) px // используем оператор деления чтобы высчитать закругление углов (о них чуть позже) tr() // вызываем миксин плавного перехода tr() который сгенерирует transition: all 0.3s ease; height: 48px; font-size: 18px; display: inline-flex; align-items: center; justify-content: center; text-align: center; text-decoration: none; text-transform: uppercase; font-weight: bold; color: #ff5964; background: #0d3b66; padding: 0 48px; border-radius: 24px; transition: all 0.3s ease; >a.button-large:hover < background: #114f89; >a.button-small < height: 30px; font-size: 0.7rem; display: inline-flex; align-items: center; justify-content: center; text-align: center; text-decoration: none; text-transform: uppercase; font-weight: bold; color: #ff5964; background: #0d3b66; padding: 0 30px; border-radius: 15px; transition: all 0.3s ease; >a.button-small:hover

Операторы Stylus

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

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

Расчеты желательно производить в круглых скобках

p font-size 18px line-height (30/18) // например, в макете line-height равен 30px p.accent font-size 36px line-height (48/36) // например, в макете line-height равен 48px

Сгененированный CSS

p < font-size: 18px; line-height: 1.666666666666667; >p.accent

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

btn(height) height height px font-size (height / 2) px // размер шрифта будет в два раза меньше высоты padding 0 ((height + 15) px) // размер внутренних бокобых отступов будет суммой значения высоты + 15px border-radius (height / 2) px // каждый угол будет закруглен ровно на половину от значения высоты a.button-large btn(100) // задаем кнопку высотой 100, остальные значения для свойств расчитываются автоматически

Сгененированный CSS

a.button-large

Встроенные функции Stylus

В Stylus большое количество встроенных функций. Рассмотрим некоторые из них

Встроенные функци round() и floor() для округления чисел.

В круглых скобках указываются параметры: первое значение — чаще всего результат деления, второе значение — количество знаков дробной части (после точки/запятой)

p font-size 18px line-height round(30/18, 3) // округляет до трех знаков дробной части в большую или меньшую сторону в зависимости от следующего знака дробной части p.accent font-size 36px line-height floor(48/36, 2) // округляет в меньшую сторону до двух знаков дробной части

Сгененированный CSS

p < font-size: 18px; line-height: 1.667; >p.accent

Встроенные функции darken() и lighten() для вычисления цвета. Чаще всего применяется при вычислении цвета при наведении на элемент или выделении активного элемента.

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

$main = #0D3B66 .circle background red :hover background lighten($main, 20%) // при наведении цвет фона указанный в переменной $main становится на 20% светлее

Сгененированный CSS

.circle < background: #f00; >.circle:hover < background: #d90000; >.square < background: #0d3b66; >.square:hover

Импортирование файлов стилей

В больших проектах основной файл CSS становится довольно большим. На этапе разработки Stylus предоставляет возможность разбивать стили на отдельные фрагменты, сохранять их в отдельных *.styl файлах и подключать эти файлы в основной файл стилей

Рассмотрим простой пример — вынесем часть стилей для адаптивности в отдельный файл media.styl и импортируем его в основной файл стилей main.styl

main.styl

Создадим рядом с main.styl файл media.styl и перенесем в него часть стилей для адаптивности

media.styl

В итоге генерируется main.css включая стили прописанные в файле media.styl

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

В шаблоне gulp-dev, который рассматривали в одной из предыдущих статей, в CSS генерируется только основной файл стилей main.styl (находится в папке app/styl/main.styl) в файл main.css (dist/css/main.css), любые другие *.styl файлы генерироваться не будут — они должны быть импортированы в основной файл main.styl

Читайте также:
Сведения которые должна содержать разработанная программа ревизии проверки

Возможные проблемы и их решения

Как и в случае с Pug, основная ошибка — это использование в отступах Пробелы вместо Tab. В качестве отступов можно использовать или только Пробелы или только Tab.

Решить эту проблему очень просто. В редакторе кода, в файле main.styl или в любом другом *.styl файле выделяем весь код сочетанием клавиш Ctrl+A и ищем настройку Tab size (в Sublime Text и VS Code справа внизу), нажимаем и выбираем пункт Convert Indentation to Tabs — все отступы конвентируются в Tab

Итоги

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

Итоговый CSS файл получается чистым, корректно сформатированым, где не будет разных отступов, пропущенных фигурных скобок, двоеточий и точек с запятой 😉

Источник: frontips.ru

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

image

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

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

Как мы пришли к использованию препроцессоров

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

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

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

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

Выбор препроцессора

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

Less показался поначалу очень простым и удобным: он использует привычный синтаксис CSS и его можно применять в браузере, что удобно для отладки. Но при попытке сделать что-то сложное его возможностей уже не хватает. Что можно сделать без массивов, циклов и нормальных условных конструкций? Не так много.

После Less Sass оказался очень приятным: мощный, с хорошим сообществом и всевозможными дополнительными библиотеками вроде Compass. Однако нашёлся один серьёзный недостаток: в Sass очень негибкий parent reference (использование символа нельзя использовать для префиксного определения множественных классов, уточнения элемента или конкатенации классов. Вот несколько примеров того, что умеют другие препроцессоры, но что может вызвать ошибку в Sass:

  • , применённое для селектора .foo .bar , должно дать мультикласс .baz.foo .bar , но так в Sass сделать не получится: можно будет дать мультикласс только к .bar , если написать , применённое к .foo , должно бы уточнить селектор до button.foo , но — увы.

И всё было бы не так плохо, если бы в Sass можно было использовать указатель на родительский селектор в интерполяции. Но нет — Sass сначала разворачивает интерполяцию и только потом пытается применить селектор, выдавая ошибку.

Обиднее всего то, что подобное поведение — не баг, а фича. И меняться это не будет. Такая уж идеология у синтаксиса Sass.

Stylus оказался самым новым из препроцессоров, и в конце концов наш выбор пал на него. Да, он сыроват, в нём встречаются неприятные баги, его комьюнити не такое большое, и разработка идёт не так быстро, как того хотелось бы. Но для наших задач он подошёл лучше всего, и вот почему:

  • Stylus — очень гибкий препроцессор, и часто он оказывается гораздо гибче того же Sass. Например, parent references Stylus раскрывает идеально.
  • В Stylus есть такая штука как прозрачные миксины — возможность вызвать функцию как обычное CSS-свойство. То есть сначала определить foo(bar) , а потом вызвать её как foo: 10px . Такая запись будет равнозначна вызову foo(10px) . Для обычных функций это не всегда удобно, но зато позволяет переопределить любое имеющееся свойство. Скажем, можно переопределить margin в padding . Если серьёзно, то при использовании подобной функциональности можно легко запутаться и усложнить понимание того, что же делает код: ведь не всегда будет ясно, какие функции были определены выше по коду и что произойдёт в результате вызова очередного свойства.

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

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

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

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

Библиотека if-ie.styl

Во время перевода Яндекс.Почты на Stylus стало понятно, что препроцессор может предоставить возможности, которых у нас не было при использовании обычного CSS. Мы давно использовали в Почте разделение стилей для обычных браузеров и для старых версий IE. Все стили раскладывались по файловой структуре согласно БЭМ, и для каждого блока рядом создавалось два файла: b-block.css и b-block.ie.css .

В первый файл шли стили для всех браузеров, а во второй, соответственно, только те, что были нужны для Internet Explorer. Тут надо отметить, что по ряду причин мы переводим IE8 в режим совместимости с IE7, а также, перестав поддерживать IE6, отправляем его на «облегчённую» версию Почты. Таким образом, у нас есть две разных версии стилей: одна для всех браузеров, вторая — для всех старых версий IE. Всё собиралось автоматически — сначала собиралась таблица стилей «для всех», после чего к ней добавлялись все стили из файлов .ie.css — и получалась таблица стилей для IE.

Каждый браузер получает только свою таблицу стилей — для этого мы используем условные комментарии, примерно так:

Читайте также:
Кто проводит сертификацию программ

Поначалу подобное разделение стилей работало хорошо, однако с появлением препроцессора возник вопрос: а нельзя ли сделать лучше?

Оказалось, что можно.

Так появилась библиотека для Stylus — «if-ie.styl». На самом деле это не совсем библиотека, скорее — методология того, как нужно работать со стилями для IE. Ничего секретного в этой методологии нет, поэтому мы решили выложить её на Гитхаб под лицензией MIT.

Вы можете совершенно спокойно использовать её для своего проекта, сообщать о найденных ошибках или и даже самостоятельно их исправлять — Open Source, все дела. А может быть, у кого-то появится возможность переписать её для другого препроцессора? Форкайте проект или создавайте новый, взяв методологию за основу — будет здорово.

Основа методологии

В основе методологии лежит очень простая идея: мы создаём переменную ie , которая будет равна false для всех обычных браузеров, и true , когда мы захотим получить стили для IE. После этого можно использовать только одну основную таблицу стилей, в которой разграничивать стили для разных браузеров обычными условиями. Простой пример: возьмём файл style.styl :

ie ?= false .foo overflow: hidden zoom: 1 if ie

Такой код на Stylus по умолчанию — для обычных браузеров — станет вот таким CSS:

Так как переменная ie была false , условие if ie не сработало, и свойство zoom не вошло в эту таблицу стилей.

Теперь создадим рядом style_ie.styl :

Если скормить такой код Stylus, то мы получим:

Это именно то, что нам и требовалось — отдельная таблица, в которой есть стили, нужные только в IE.

При этом, если мы захотим написать какие-то стили только для обычных браузеров, мы сможем использовать условие if !ie — и фильтровать стили станет очень просто.

Дополнительные возможности if-ie.styl

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

Для её использования подключение стилей будет выглядеть чуть иначе.

Файл style.styl станет таким:

A style_ie.styl таким:

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

  1. В обоих файлах нужно подключать библиотеку до всех остальных стилей, и обязательно оба раза. (Может показаться, что хватило бы только первого — ведь таблица стилей для IE уже содержит основную таблицу стилей — но тогда некоторые последующие возможности не будут работать). В этом файле уже определяется ie ?= false , и поэтому в основной таблице стилей не нужно это явно прописывать.
  2. В таблице стилей для IE пропало условие if ie — это показана работа первой фичи библиотеки: свойство zoom автоматически появится только в таблице стилей для IE. Конечно, и в обычных браузерах можно использовать это свойство, но на практике такая необходимость случается крайне редко, так что можно облегчить основную таблицу стилей хотя бы чуть-чуть.

В коде Stylus подобные функции очень легко определять. В данном случае новый прозрачный миксин будет выглядеть так:

zoom() zoom: arguments if ie

Этим кодом мы создаём функцию zoom , которая пропишет соответствующее свойство с любыми переданными аргументами только в том случае, если мы в данный момент собираем стили для IE.

inline-block

Широко известно, что в старых версиях IE у свойства display «из коробки» нет поддержки значения inline-block . В IE есть аналогичный механизм, но он срабатывает только для инлайновых элементов и только если у них включён механизм hasLayout. Совершенно случайно display: inline-block в IE как раз его включает, но «забывает» переключить элемент в display: inline , поэтому подобная запись не будет работать для изначально блочных элементов вроде . Так что наиболее простой способ гарантированно применить инлайн-блочное поведение к любому элементу в IE — прописать только для него zoom: 1; display: inline; .

В if-ie.styl свойство display так будет делать автоматически и только для IE. Обычные браузеры увидят display: inline-block , тогда как IE получит только zoom: 1; display: inline; . Тут кто-то мог бы заметить, что вторая запись длиннее первой, и для изначально инлайновых блоков можно было бы и сэкономить… Но если внимательно подсчитать, то экономия окажется всего в один байт. Это не стоит того, чтобы всё время следить — инлайновый ли блок изначально или нет. Тем более что в идеале вёрстка не должна зависеть от того, к какому элементу она применяется.

Переопределение CSS3-свойств

Если мы по умолчанию не отдаём обычным браузерам zoom: 1 , разделив все стили на два файла (как было, в общем-то, и до внедрения препроцессоров), то с препроцессорами можно задуматься и над тем, как облегчить и таблицу стилей для IE.

С помощью Stylus это делается очень просто, при этом можно сэкономить довольно много байт: ведь что нам точно в старых IE не нужно, так это свойства с префиксами.

Выше в статье я уже упомянул, что мы используем библиотеку nib — эта библиотека определяет прозрачные миксины для большинства новых CSS-cвойств, например, для транзишнов. В итоге в стилях для Stylus мы пишем просто transition: opacity .3s и в результате получаем это свойство со всеми нужными префиксами. Но в IE нам не только префиксы не нужны, но и само свойство! А значит, мы можем в нашей библиотеке переопределить это и многие другие свойства так, чтобы они ничего не возвращали.

Делается это примерно так:

if ie transition() z if 0 transition-property() z if 0 // …

Тут всё почти понятно: одним условием мы только для IE переопределяем сразу все нужные свойства. Однако из-за особенностей Stylus приходится в определении функции написать хотя бы одно правило — z if 0 получается довольно коротким.

В итоге IE вместо определённого в nib миксина transition видит тот, что мы определили в if-ie.styl, и полученная таблица стилей окажется гораздо легче, чем раньше — почти всё ненужное из неё будет вырезано.

rgba-ie

Не будем раздувать статью и описывать всё, что есть в if-ie.styl — в документации к проекту это уже подробно описано.

Однако нужно рассказать ещё про одну функцию, которая оказалась нам очень полезна в рамках тематизации Яндекс.Почты. Это функция 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

Источник: habr.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru