Transcript
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


Top Related