43
Генерация CSS От LESS к Stylus, от фреймворка — к тулкиту Interlabs 23 июня 2014 1 / 43

Генерация CSS: от LESS к Stylus

  • View
    652

  • Download
    8

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: Генерация CSS: от LESS к Stylus

Генерация CSSОт LESS к Stylus, от фреймворка — к тулкиту

Interlabs

23 июня 2014

1 / 43

Page 2: Генерация CSS: от LESS к Stylus

О чем речьДва года LESS + Boot.LESS, пора двигаться дальше:

• IE7 — давай, до свидания1

• адаптивный дизайн→ responsive design• исправление допущенных проектировочных ошибок

LESS — хорошо, но хотелось бы:

• более компактный код• ближе по духу к CSS (просто свойства внутри правил)• простые расширения на JavaScript

Новый препроцессор + новый фреймворк1http://theie7countdown.com/ 2 / 43

Page 3: Генерация CSS: от LESS к Stylus

Именование классов.namespace-element-subelement--modifier

Базовая модель остается без изменений, улучшаем:

• отказываемся от префикса app- — уменьшаем объем CSS• классы состояний: is-active, is-valid и т.д., всегдаопределяются только вместе с другими классами

• несколько стандартных классов (block, block-group и т.д.)

.app-top-menu→ .top-menu

.top-menu-item–active→ .top-menu-item.is-active

3 / 43

Page 4: Генерация CSS: от LESS к Stylus

box-sizing: border-boxСамый главный выигрыш от отказа от IE7:

• упрощает работу с сетками, особенно с тянущимися• существенно упрощает стилизацию форм• уменьшает количество уровней вложенности DOM• если очень надо IE7 — отдельные стили и (или) polyfill

margin

border

padding

content

box-sizing: content-box

margin

border

padding

content

box-sizing: border-box

Де-факто стандарт современных CSS-фреймворковBootstrap, Foundation, Pure и т.д.

4 / 43

Page 5: Генерация CSS: от LESS к Stylus

Новый препроцессор

http://learnboost.github.io/stylus/

5 / 43

Page 6: Генерация CSS: от LESS к Stylus

Stylus• вложенные правила — как в LESS• синтаксис, основанный на отступах (как в Python)• минимальный синтаксис (но с осторожностью)• transparent mixins: макросы как пользовательскиеCSS-свойства (killer feature)

• циклы, хеши, блоки, списки параметров• простая расширяемость на JavaScript• абстрактные классы, расширяемость классов• единое пространство имен (как и в CSS)

Современный LESS функционально не уступает, но сложнее имногословнее, старый LESS — многое отсутствовало.

6 / 43

Page 7: Генерация CSS: от LESS к Stylus

Stylus: вложенные правилаПохоже на LESS, но отступы определяют вложенность:

ul, ol, li // через запятуюmargin: 0

.block // или списком

.block-groupdisplay: block

.menu-itema

text-decoration: none&:hover // & = parent/.is-hover // / = root

text-decoration: underline

7 / 43

Page 8: Генерация CSS: от LESS к Stylus

Stylus: переменные и макросыbaseline ?= 8px // переменная, значение по умолчаниюsans-16 = { // переменная-хеш

font-size: 16px,line-height: 24px

}text-lines(n) // функция

return (n*baseline)

margin-top(s) // переопределение стандартного свойстваif ’’ == unit(s) and s != 0margin-top: text-lines(s)

elsemargin-top: s

text-style(style) // макро/пользовательское свойствоfont-size: style.font-size if style.font-sizeline-height: style.line-height if style.line-height

bodytext-style: sans-16 // font-size: 16pxmargin-top: 2 // line-height: 16px

// margin-top: 16px8 / 43

Page 9: Генерация CSS: от LESS к Stylus

Stylus: управляющие конструкцииsupport-ie = true

.inlinedisplay: inline-blockif support-ie // префиксный if

zoom: 1

vertical-size(num, adjust = 0)adjust = 0 if ’’ == unit(adjust) // постфиксный ifreturn (vertical-baseline*num - adjust) // return

// постфиксный unless (if (!())name = font-path + "/" + files unless match("^(http://|/)", files)

// Циклыscale = 8px 10px 12px 16px 20pxfor s, i in scale

size-{i}font-size: s

9 / 43

Page 10: Генерация CSS: от LESS к Stylus

Stylus: блоки кодаmedia(query = any)

if query == any{block} // передаваемый блок

else@media query

{block}

+media(above-480) // если вызов начинается с +,.sidebar // то передается вложенный блок

width: 40%

code = // можно присвоить переменнойwidth: 20pxheight: 20px

.style // и выполнить подстановку{code}

10 / 43

Page 11: Генерация CSS: от LESS к Stylus

Stylus: @extendПозволяет выполнять композицию селекторов:

.message { // .message, .warning {padding: 10px; // padding: 10px;border: 1px solid #eee; // border: 1px solid #eee;

} // }//

.warning { // .warning {@extend .message; // color: #E2E21E;color: #E2E21E; // }

}

• появился в SASS, раньше не было в LESS теперь есть и там• может существенно сократить размер CSS• применяя, помним о размере генерируемых селекторов• mixin() vs @extend — индивидуально для каждого случая

11 / 43

Page 12: Генерация CSS: от LESS к Stylus

Stylus: @extend// Множественный @extend:.a // .a, .c {

color: red // color: red;.b // .b, .c {

width: 100px // width: 100px;.c // }

@extend .a, .b // .c {height: 200px // height: 200px;

// }

// Абстрактный класс (placeholder)$block // .content-block,

display: block // .menu-item {float: left // dispay: block

.content-block // float: left;@extend $block // }

.menu-item // .menu-item {@extend $block // color: blue;color: blue // }

12 / 43

Page 13: Генерация CSS: от LESS к Stylus

Стандарт кодирования Stylus

• используем пробельные отступы• используем : для разделения свойства и значения(синтаксис позволяет не использовать)

• имена переменных без специальных символов, $ — дляабстрактных классов

• - для разделителей в именах• вызов макросов — в виде свойств• вызов макросов самого верхнего уровня — в виде явноговызова macro()

• внутренние макросы — с префиксом -• список параметров через пробел, если не создает проблем

Главный принцип — семантическое сходство с CSS

13 / 43

Page 14: Генерация CSS: от LESS к Stylus

Новый фреймворк тулкитBare

• набор макросов Stylus, часть взята из Nib• тулкит — (почти) не навязывает свою структуру,предоставляет средства для реализации необходимойструктуры, convention over configuration

• макросы реализуют дополнительных свойств CSS• единое пространство имен с префиксами дополнительныхсвойств и переменных

• responsive design + IE8

Семантически стараемся расширить CSS, а не строить над нимсложную систему макросов.

14 / 43

Page 15: Генерация CSS: от LESS к Stylus

Модульная структура• модуль — отдельный файл .styl• модули могут объединяться в более крупные модели черезrequire в index.styl

• имя модуля — префикс для имен переменных и макросовмодуля (и следовательно, пользовательских CSS-свойств)

• загрузка модуля не приводит к генерации каких-либоCSS-классов, только к загрузке макросов

• генерация классов (если есть) — в виде отдельного макроса• use-имя-модуля — стандартное именования макросагенерации классов

@require ’normalize’ // классы не генерируютсяuse-normalize() // явная генерация классов

15 / 43

Page 16: Генерация CSS: от LESS к Stylus

vendor + css3• просто пишем обычный CSS, без специальных макросов• свойства CSS3 автоматически транслируются вvendor-свойства, если это необходимо

// Stylus /* CSS */.button .button {

border-radius: 4px -webkit-border-radius: 4px;-moz-border-radius: 4px;border-radius: 4px;

}

Реализация:макро border-radius()→ макро vendor()→ vendor.js,при использовании мы даже не замечаем реализации.

16 / 43

Page 17: Генерация CSS: от LESS к Stylus

normalize + resetЧистый reset недостаточно, чистый normalize — избыточныйсброс для элементов, не относящихся к основному контенту.

Используем комбинацию:

• normalize для нормализации различий и устранениямелких проблем

• reset для сброса отступов контентных элементов• для контентных элементов настраиваем типографику так,как нам необходимо

use-normalize() // - генерация правил нормализацииuse-reset() // - генерация правил сброса

// Или просто...use-bare()

17 / 43

Page 18: Генерация CSS: от LESS к Stylus

Вертикальный ритм

aa

margin

padding

• все вертикальные размеры кратны базовому шагу• контент выравнивается за счет кратной высоты строки• border компенсируется корректировкой внутреннегоили внешнего отступа

• вложенный элементы в пределах разной line-heightмогут иметь различную относительную высоту

• display: inline-block может упростить сложныеслучаи

• выравнивание картинок переменного размера —жестко определенный контейнер или JavaScript

• базовый шаг — половина или треть высоты строкибазового шрифта — от 8px до 11px

18 / 43

Page 19: Генерация CSS: от LESS к Stylus

vertical + textВертикальный ритм важен, необходимо упростить реализацию.

vertical-baseline = 8px // определяем вертикальный шаг

Переопределяем margin, padding, height для поддержкиunitless единиц измерений — количества вертикальных единиц:

margin-top: 2 // margin-top: 16px (2*8px)height: 10 // height: 80px (10*8px)padding: 1 20px 2 // padding: 8px 20px 16px

// Если необходимо, отступы можно корректировать:margin-top: 2 2px // margin-top: 14px (2*8px - 2px)

Расширяем CSS вместо громоздкого набора макросов19 / 43

Page 20: Генерация CSS: от LESS к Stylus

vertical + textРитм = кратный line-height + адекватный размер шрифта.

Вместо индивидуального пересчета метрик (как раньше)определим набор текстовых стилей для всего проекта.

sans-medium = { // пример определения текстового стиляfont-family: sans-serif,font-size: 18px, // нормально вписывается в line-heightline-height: 24px, // кратно базовому шагуfont-variant: small-caps

}

.sidebartext-style: sans-normal // применяем стиль целиком

.sidebar-titletext-metrics: sans-medium // применяем метрику, шрифт наследуется

20 / 43

Page 21: Генерация CSS: от LESS к Stylus

vertical + text• стиль определяет не полный внешний вид, а базовуютипографику элемента

• вариации в inline-элементах в пределах line-height —относительные размеры через em

• в процессе дизайна стараемся минимизироватьколичество стилей

• определения стилей могут отличаться для разныхмедиа-вариантов

• при необходимости стиль можно корректировать, добавляяк высоте строки необходимое число базовых единиц

.button // кнопка с большими отступамиtext-metrics: sans-medium 2 // за счет увеличенного line-height

21 / 43

Page 22: Генерация CSS: от LESS к Stylus

fontsОпределение шрифтов — как и раньше, через макро:

// URL файлов шрифтовfont-path ?= ’/fnt’

// %s — переменное расширение шрифтового файлаuse-font-face(’Bitstream Vera Serif Bold’, ’VeraSeBd.%s’)

@font-face {font-family: ’Bitstream Vera Serif Bold’;font-style: normal;font-weight: normal;src: url(/fnt/VeraSeBd.eot?) format(’eot’),

url(/fnt/VeraSeBd.woff) format(’woff’),url(/fnt/VeraSeBd.ttf) format(’truetype’);

}

22 / 43

Page 23: Генерация CSS: от LESS к Stylus

Разноеclearfix, position, text, overflow

clearfix: true // говорит само за себя :)fixed: top // сокращение для позиционированияabsolute: top left // еще сокращение для позиционированияcentered: true // горизонтальное центрирование блокoverflow: ellipsis // показ части текстаtext-hidden: true // скрывает текстовый контент элемента

linear-gradient

background: linear-gradient-image( // => background:40px, // url(’data:image/png;base64, iVB...rgba(255,255,255, .2) 0%,rgba(255,255,255, .2)

)

23 / 43

Page 24: Генерация CSS: от LESS к Stylus

mediaГенерация медиа-вариантов + IE8 (ждать уже не долго2 ,)

• нужно избежать дублирование описаний вариантов• стараемая избежать избыточных @media в CSS• желательно как-то следовать Mobile First

Нужна выборочная генерация для отдельных медиа-вариантов.

// site.styl+media(any, ie) // стили по умолчанию, используются IE8.labeltext-style: sans-small

+media(any) // стили по умолчанию, не используются IE8display:none

+media(above-480, ie) // медиа-вариант, используется IE8display: block

2http://theie8countdown.com/24 / 43

Page 25: Генерация CSS: от LESS к Stylus

media: непосредственная генерация

// Просто загружаем файл .label {@import ’site’ font-family: sans-serif

font-size: 12pxline-heightL: 16px

}.label {

display: none}@media screen and (min-width: 480px) {

.label {display: block;

}}

Проблемы: порядок следования @media, вариант для IEнесовместим с Mobile First, каждый новый +media() —дублирование @media в CSS.

25 / 43

Page 26: Генерация CSS: от LESS к Stylus

media: выборочная генерация

media-query устанавливает вариант, @media не используется:

media-query = above-480 .label {@media above-480 { display: block;@import ’site.styl’ }

}

Для IE8 используем значение второго аргумента +media():

media-query = ie .label {@import ’site.styl’ font-family: sans-serif;

font-size: 12px;line-height: 16px;

}.label {

display: block;}

26 / 43

Page 27: Генерация CSS: от LESS к Stylus

media: итогоИспользование +media() позволяет:

• не думать о порядке следования @media при описаниикомпонентов, главное в итоге сгенерировать их вправильном порядке

• генерировать отдельные файлы для разных вариантов иподключать их в зависимости от возможностей устройства,(например, max-device-width)

• генерировать отдельный legacy-вариант

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

• предопределенные точки соответствуют либо Mobile First(above-*) или Desktop First (below-*)

27 / 43

Page 28: Генерация CSS: от LESS к Stylus

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

• хорошо в адаптивном дизайне, хуже — в responsive• неудобно в ситуациях, предусматривающих flow контента,например, responsive витрина магазина

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

Альтернатива: система блоков по мотивам PocketGrid3

3http://arnaudleray.github.io/pocketgrid/28 / 43

Page 29: Генерация CSS: от LESS к Stylus

blocks: идеяbox-sizing + блоки процентной ширины + естественный flow

• block-group — контейнер для блоков (примерно grid row)• block — блок (примерно grid cell), float: left• по умолчанию все блоки 100% — mobile first!• разная процентная ширина блоков в медиа-вариантах —разные сетки без дополнительных классов.

• блок может содержать вложенную группу блоков• gutter определяется внутренним отступом блоков• gutter фиксированный (в пределах медиа-варианта)• block и block-group — семантические классы,отображение — целиком в CSS

29 / 43

Page 30: Генерация CSS: от LESS к Stylus

blocks: использование

<div class="head block-group">...</div><div class="page block-group">

<div class="page-content block"><h2>Site content</h2><p>...</p>

</div><div class="page-sidebar block">

<h3>Sidebar</h3><p>...</p>

</div></div><div class="foot block-group">...</div>

30 / 43

Page 31: Генерация CSS: от LESS к Stylus

blocks: использование+media(any, ie)

.pageblocks-gutter: 20px // горизонтальный gutter

+media(above-480) // по возможности.page-content // располагаем рядом,

width: 60% // по умолчанию —.page-sidebar // друг под другом

width: 40% // (width: 100%)

+media(above-1024) // на больших разрешениях.page

block-gutter : 40px // увеличиваем gutter

31 / 43

Page 32: Генерация CSS: от LESS к Stylus

blocks: flow<div class="showcase block-group">

<div class="showcase-item block"><h3 class="item-title">Item 1</h3><p class="item-info">Description 2</p>

</div>

<div class="showcase-item block"><h3 class="item-title">Item 2</h3><p class="item-info">Description 2</p>

</div>...

</div>

Разметка не разделяет позиции по горизонтали отдельнымиконтейнерами рядов.

32 / 43

Page 33: Генерация CSS: от LESS к Stylus

blocks: flow+media(any, ie).showcaseblocks-gutter: 20px 2 // 2*8px — вертикальный gutter

+media(above-1024).showcaseblocks-gutter: 40px 3

.showcase-itemwidth: 25% // 4 столбца на десктопе

+media(above-640).showcase-itemwidth: 33.33333% // 3 столбца на планшете

+media(above-480).showcase-itemwidth: 50% // два столбца на смартфоне

Если высота одинакова, блоки переносятся автоматически.33 / 43

Page 34: Генерация CSS: от LESS к Stylus

iconsЕдиный способ подключения иконных шрифтов:

<i class="icon icon--oi" data-glyph="save"></i>

• класс .icon — общий класс для всех иконок• класс .icon–oi — модификатор для конкретного иконногошрифта

• data-glyph="save" — определяет отображаемую иконку

На данный момент включен Open Iconic4: user-icons(’oi’).4https://useiconic.com/open

34 / 43

Page 35: Генерация CSS: от LESS к Stylus

Интерфейсные элементыСтилизация элементов интерфейса — сложная задача:

• использование box-sizing делает жизнь проще• проекты слишком визуально разные для единого решения• существующие фреймворки ограничивают внешний видопределенной моделью

Поэтому:

• normalize + box-sizing — минимальная подготовка• соглашения + абстрактные классы без визуальногооформления в качестве основы

• (возможно) вспомогательные макросы для типовыхвариантов оформления

35 / 43

Page 36: Генерация CSS: от LESS к Stylus

buttons• $buttons-behavior — базовое отображение + поведение• $buttons-button — минимальная геометрия в пределахline-height

• use-buttons() — .button производный от$buttons-button

• inline-block, размеры — относительно контейнера

+media(any).button // настройка в проектеborder: noneborder-radius: 0.5em

.button--defaultcolor: white // - стилизация вида кнопокbackground-color: #999

.button--smallfont-size: 80% // - относительный размер шрифта

36 / 43

Page 37: Генерация CSS: от LESS к Stylus

forms: соглашение по верстке

• .form — контейнер для элементов формы, соответствуетстроке формы или всей форме

• .form-control — сложный элемент управления изнескольких элементов, например, <label> c <inputtype="checkbox"> внутри

• .form-label — метка поля (<label> или контейнер с<label>)

• .form-field — контейнер для полей формы

• .form может использоваться совместно с .block-group• .form-field, .form-label — совместно с .block• результат — можно менять вид формы в медиа-вариантах

37 / 43

Page 38: Генерация CSS: от LESS к Stylus

forms: пример<div class="signup-form">

<div class="form form--aligned block-group"><div class="form-label block"><label for="name">Your name:</label></div><div class="form-field block"><input id="name" class="form-input"></div>

</div>

<div class="form form--stacked block-group"><div class="form-label block"><label for="about">About you:</label></div><div class="form-field block"><textarea id="about"></textarea></div>

</div>

<div class="form form--stacked block-group"><div class="form-field block"><label class="form-control"><input type="checkbox" name="agree">Yes, I agree.

</label></div>

</div>

</div>

38 / 43

Page 39: Генерация CSS: от LESS к Stylus

forms: стилизацияuse-forms() // базовые классы

+media(any) // общие настройки.formblocks-gutter: 40px 2 // отступы между рядами

.form-labeltext-metrics: sans-small 2 // увеличенная высота строкиlabeltext-metrics: sans-small

.form-inputtext-metrics: sans-smallpadding-top-bottom: 1 2px // скорректированный отступpadding-left-right: 0.6emborder: solid 1px #aaawidth: 100%

+media(above-640) // на большом экране.form--aligned // для строк с выравниванием.form-label // устанавливаем горизонтальныеwidth: 10% // размеры

.form-fieldwidth: 70%

39 / 43

Page 40: Генерация CSS: от LESS к Stylus

Структура файловsrc/css/ Исходники для CSS.

site/ Генерация стилей сайта:any.styl - стили для всех вариантовdesktop.styl - стили только для десктопаie.styl - IE8mobile.styl - мобильные стилиstyles/ Исходные таблицы стилей сайта:

common/ Общие стили для всех страницindex.styl Индексный файл для всех модулейpage.styl - стили страницыforms.styl - стили форм... - и т.д.

... Стили для отдельных режимов.index.styl Индексный файл всего сайта.

40 / 43

Page 41: Генерация CSS: от LESS к Stylus

Точки входа// any.styl: общие стили для всех устройствrequire ’../lib’media-query = any // не обращаем внимания на@import ’styles’ // legacy-признак

// mobile.styl: стили для мобильных устройствfor m in above-480 above-320 above-240 // порядок важен!

media-query = m@media m

@import ’styles’

// ie.styl: отдельный CSS для IE8media-query = ie@import ’styles’

41 / 43

Page 42: Генерация CSS: от LESS к Stylus

Самое главноеПри использовании любого CSS-препроцессора:

• даже используя препроцессор, вы пишете CSS• оперируйте в первую очередь понятиями CSS, а непрепроцессора

• старайтесь получить оптимальный CSS, а не красивыйисходный код для препроцессора

• всегда проверяйте генерируемый код

Препроцессор — инструмент для получениякачественного CSS, а не его замена.

42 / 43

Page 43: Генерация CSS: от LESS к Stylus

use-bare()private: https://bitbucket.org/interlabs/bare

43 / 43