SlideShare uma empresa Scribd logo
1 de 143
Baixar para ler offline
CSS глазами машин
Роман Дворнов
Avito
Москва 2018
Работаю в Avito
Open source:

basis.js, CSSO, 

component-inspector, 

csstree, rempl и другие
Доклад о том, как машины* 

понимают CSS и обрабатывают его,

какие есть сложности и проблемы
3
* программы для анализа и трансформации CSS
– Андрей Ситник
“Машины должны страдать!”
4
Но сейчас больше 

страдают разработчики
5
Но сейчас больше 

страдают разработчики
5
Сложно обрабатывать CSS,
т.к. очень много нюансов
«создатели»
Но сейчас больше 

страдают разработчики
5
Сложно обрабатывать CSS,
т.к. очень много нюансов
«создатели»
Баги и непредсказуемость
результатов
«пользователи»
Рассказываю, потому что подгорает :)
• CSSO (мейнтейнер) – минификатор CSS
• CSSTree (автор) – набор инструментов по работе
с CSS, включающий parser, walker, lexer,
generator и т.д.
6
Вводная
CSS
#практики #методологии #трюки #тонкости
#возможности #multitarget...
8
Сложности
• Большое количество директив, свойств, функций и т.д.
• Исключения и особые правила
• Белые пятна в спецификациях
• CSS меняется
• Разная поддержка браузерами
• Баги браузеров
• Хаки
9
Проблемы
• К CSS меньше внимания чем к другим веб-технологиям
• Низкий уровень знания CSS
• Препроцессоры
• FCSS (Fantasy CSS из доклада Вадима Макеева)
• Много CSS кода в проектах (мегабайты)
• Недооценивание масштаба проблем (я оптимист!)
10
• Директивы (at-rule) – 40
• Медиа фичи (media feature) – 69
• Псевдо-классы – 125
• Псевдо-элементы – 146
• Свойства – 1150
• Функции – 69
• Единицы измерения (unit) – 30
11
• Цифры включают легаси и
вендорные имена
• Собрано для словарей CSSTree 

в рамках проекта real-web-css
Без машин не справиться!
12
Программы для анализа
и трансформации CSS

#каксейчас #проблемы #вызовы
А вы задумывались ...
• Как машины видят CSS?
• Как понимают его значение?
• Как понимают что правильно, а что нет?
• Что нужно, чтобы объяснить им как должно быть?
• ...
14
Немного терминологии
Rule (правило)
16
.foo, body > .bar:hover
{
color: red;
}
Rule (правило)
16
.foo, body > .bar:hover
{
color: red;
}
Prelude (прелюдия)
Rule (правило)
16
.foo, body > .bar:hover
{
color: red;
}
Prelude (прелюдия)
Block (блок)
Rule (правило)
16
.foo, body > .bar:hover
{
color: red;
}
Prelude (прелюдия)
Block (блок)
Selector (селектор*)
* в докладе термин "селектор" ссылается на complex selector
Rule (правило)
16
.foo, body > .bar:hover
{
color: red;
}
Prelude (прелюдия)
Block (блок)
Declaration (декларация)
Selector (селектор*)
* в докладе термин "селектор" ссылается на complex selector
At-rule (директива*)
17
@media all, (max-width: 800px)
{
...
}
* перевод из словаря терминов по фронтенду
At-rule (директива*)
17
@media all, (max-width: 800px)
{
...
}
At-keyword
(ключ директивы*)
* перевод из словаря терминов по фронтенду
At-rule (директива*)
17
@media all, (max-width: 800px)
{
...
}
Prelude (прелюдия)
At-keyword
(ключ директивы*)
* перевод из словаря терминов по фронтенду
At-rule (директива*)
17
@media all, (max-width: 800px)
{
...
}
Prelude (прелюдия)
Block (блок)
At-keyword
(ключ директивы*)
* перевод из словаря терминов по фронтенду
Как машины видят CSS
19
CSS РезультатПрограмма
Перевод на
«машинный»
Правила
AST*
структура данных 

для представления исходного кода
20
* Abstract Syntax Tree, тот самый «машинный»
21
.foo {
color: red;
}
{
type: "Rule",
prelude: ".foo",
declarations: [
{
type: "Declaration",
property: "color",
value: "red"
}
]
}
Исходный код AST
Строка (набор символов),
сложно определить где какая часть
Структура (дерево), 

все разложено по полочкам
22
Код
(Строка)
РезультатASTParser
Walker
Generator
Lexer
Обход узлов AST
Применение лексических правил
Преобразование

строки в AST
(перевод 

на «машинный»)
Обычно новый
код (строка) 

+ source map
Преобразование

AST в другое 

представление
(обратное к Parser)
Общая схема по работе с кодом
Так работают ...
• Линтеры (проверяют ошибки)
• Минификаторы
• Подсказки в IDE/редакторах
• Программы форматирования кода
• Пре- и пост-процессоры
• Autoprefixer и т.д.
23
Формат AST
Современные JavaScript парсеры

(esprima, acorn, babylon, ...)

используют спецификацию ESTree
для формата AST
25
Современные CSS парсеры

(PostCSS, CSSTree, Gonzales PE...)
используют каждый свой формат AST, 

общей спецификации нет
26
Какие сложности это вызывает
• Нет совместимости между инструментами с разными
парсерами
• Разработчики парсеров решают одни и те же проблемы
• Сложно с именованием типов узлов и их свойств
• Открытые вопросы как представлять разные части CSS
• Конфликт интересов в формате для разных задач
• Не понятно как правильно
27
Спецификации CSS 

не рассматривают формат AST, 

так как они нацелены на браузеры
28
Что получается у меня:
29
Формат AST в CSSTree
По прежнему есть открытые вопросы :(
Уровень деталей
Пример
31
width: 100px
Пример
31
width: 100px
PostCSS
"100px"
не разбирает значения
Пример
31
width: 100px
PostCSS
"100px"
не разбирает значения
CSSTree
{
type: "Dimension",
value: "100",
unit: "px"
}
1 узел
Пример
31
width: 100px
PostCSS
"100px"
не разбирает значения
CSSTree
{
type: "Dimension",
value: "100",
unit: "px"
}
1 узел
Gonzales-pe
{
type: "dimension",
content: [{
type: "number",
content: "100"
}, {
type: "ident",
content: "px"
}]
}
3 узла
Детальность
32
Меньше Больше
• Больше типов узлов
• Больше памяти на хранение узлов
• Больше времени на обход дерева
• Необходим дополнительный разбор
• Так как "доразбор" на стороне
пользователя: больше зависимостей
и шансов сломаться
Пример: перевод px в rem
33
// !singlequotes|!doublequotes|!url()|pixelunit
var pxRegex = /"[^"]+"|'[^']+'|url([^)]+)|(d*.?d+)px/ig;
ast.walkDecls(function (decl, i) {
...
decl.value = decl.value.replace(pxRegex, function (m, $1) {
// 16px -> 1rem
});
});
postcss-pxtorem (PostCSS плагин)
(недетальное AST)
Та же задача с детальным AST
34
csstree.walk(ast, function (node) {
...
if (node.type === 'Dimension' && node.unit === 'px') {
// ... вычисление нового значения (newValue)
node.value = newValue;
node.unit = 'rem';
}
});
(как мог бы выглядеть плагин на CSSTree)
Пример: подсчет specificity
35
...
attributeRegex = /([[^]]+])/g,
idRegex = /(#[^#s+>~.[:]+)/g,
classRegex = /(.[^s+>~.[:]+)/g,
pseudoElementRegex = /(::[^s+>~.[:]+|:first-line|:first-letter|:before|:after)/gi,
pseudoClassWithBracketsRegex = /(:[w-]+([^)]*))/gi,
pseudoClassRegex = /(:[^s+>~.[:]+)/g,
elementRegex = /([^s+>~.[:]+)/g;
...
specificity (1.2M downloads/month, 32 dependants)
(не детальное AST)
Пример: подсчет specificity
36
...
var A = 0, B = 0, C = 0;
simpleSelector.children.each(function walk(node) {
switch (node.type) {
case 'SelectorList':
case 'Selector':
node.children.each(walk); break;
case 'IdSelector':
A++; break;
case 'ClassSelector':
case 'AttributeSelector':
B++; break;
...
модуль подсчета
specificity в CSSO
(57 SLOC)
(детальное AST)
Детальность AST
• Нужный уровень детальности зависит от задачи 

(например, если обрабатываются только селекторы, 

не нужно разбирать значения деклараций)
• Уровень детализации зависит от парсера
• В некоторых парсерах можно управлять
уровнем детализации
37
Несколько примеров
• PostCSS

Не разбирает (оставляет строкой): прелюдии у директив и правил
(selector list), значения деклараций. Детализация не настраивается
• CSSTree

Не разбирает значения custom properties, но можно включить
настройкой парсера. Можно отключить разбор прелюдий и значений
деклараций
• Gonzales PE

Самой большой уровень детализации. Детализация не настраивается
38
Детальность в CSSTree
39
csstree.parse('@example 1 2;');
{
"type": "Atrule",
"prelude": {
"type": "AtrulePrelude",
"children": [
{ "type": "Number", "value": "1" },
{ "type": "WhiteSpace", "value": " " },
{ "type": "Number", "value": "2" }
]
},
"block": null
}
Детальность в CSSTree
40
csstree.parse('@example 1 2;', {
parseAtrulePrelude: false
});
{
"type": "Atrule",
"prelude": {
"type": "Raw",
"value": "1 2"
},
"block": null
}
Паритет CSSTree с PostCSS
41
csstree.parse(css, {
positions: true,
parseAtrulePrelude: false,
parseRulePrelude: false,
parseValue: false
});
Разбор
CSS is hard
• at-rules @media, @supports, @font-face, …
• необязательные кавычки url(…), [name=value], …
• сложные функции calc(), var(), attr(), …
• экранирование
• bad-url, bad-string…
• …
43
44
#31  + 2 {
content: "hello
world";
background: url(p(4).jpg);
}
Экранирование
drafts.csswg.org/cssom/#the-css.escape()-method
В идентификаторах можно
использовать любые
символы, если экранировать;
в браузерах есть метод для
этого – CSS.escape()
CSS.escape('1 + 2') === '31  + 2'
45
#31  + 2 {
content: "hello
world";
background: url(p(4).jpg);
}
Экранирование
www.w3.org/TR/CSS22/grammar.html#grammar
Можно экранировать
перевод строки в строках, 

как в JavaScript
46
#31 +2 {
content: "hello
world";
background: url(p(4).jpg);
}
Экранирование
www.w3.org/TR/CSS22/grammar.html#grammar
Можно экранировать
специальные символы 

в url()
47
Экранирование
Браузер поймет правильно
Когда парсер плох (Chrome DevTools)
48
@supports (display: flex) {
.simple {
display: flex;
}
}
@supports
49
@supports (display: flex) {
.simple {
display: flex;
}
}
@supports
Декларация
50
@supports (display: flex) {
.simple {
display: flex;
}
}
@supports
Декларация
Тоже декларация
51
@supports (background: top calc(25% + 2px) !important) {
…
}
@supports
С точки зрения спецификаций разрешается все, 

что можно в декларации, даже !important
www.w3.org/TR/css3-conditional/#at-supports
CSS Syntax Module Level 3
Когда возникает ошибка в CSS, парсер постепенно
восстанавливается, выкидывая минимальное количество
контента перед возвращением к разбору в обычном режиме.
Это связано с тем, что ошибки не всегда являются ошибками –
новый синтаксис выглядит как ошибка для старых парсеров, и
это полезно для добавления нового синтаксиса в язык ...
52
§ 2.2. Error Handling
Парсеры CSS толерантные к ошибкам
• CSSTree – толерантный к ошибкам согласно
спецификации
• PostCSS – толерантен к ошибкам, если используется
postcss-safe-parser вместо стандартного парсера.
Соответствие спецификации не известно
• Это все варианты, что я знаю...
53
* парсеры написанные на JavaScript
Итоги
Ключевое
• Нет общего формата AST для CSS
• Уровень детализации AST может быть разный
• Детальное AST может требовать больше ресурсов, 

но удобнее для анализа и трансформации
• Парсинг CSS в AST сложная задача, много нюансов
• CSS парсер должен быть толерантным к ошибкам
55
Формат AST и его свойства,

определяют что и как 

машины могут делать с CSS
56
Обход и поиск
Обход осуществляет walker, обходит все
узлы дерева и вызывает функцию
обработчик
58
Обход
Сложности: декларация
60
@supports (display: flex) {
.foo {
font-family: "Open Sans";
}
}
@font-face {
font-family: "Open Sans";
}
Сложности: декларация
61
@supports (display: flex) {
.foo {
font-family: "Open Sans";
}
}
@font-face {
font-family: "Open Sans";
}
В CSSTree это все декларации
(тип узла Declaration):
• Декларации внутри @supports
обычно обходить не нужно, их
приходится игнорировать (а если
нужны?)
• Внутри @font-face на самом деле не
декларация, а дескриптор
(decscriptor); для них, например,
нельзя применять !important (будет
считать ошибкой и браузер
проигнорирует дескриптор)
Сложности: селекторы
62
@page :first {
...
}
@keyframes name {
from { ... }
25%, 75% { ... }
to { ... }
}
.foo {
...
}
Сложности: селекторы
63
@page :first {
...
}
@keyframes name {
from { ... }
25%, 75% { ... }
to { ... }
}
.foo {
...
}
В CSSTree это все селекторы
(тип узла SelectorList):
• Но обходить селекторы в @page
обычно не нужно; да и по спеке это
<page-selector-list>
• Внутри @keyframes это не обычные
селекторы – <keyframe-selector>; а
блок <keyframe-block>, хотя внутри
все те же декларации
• Все это подталкивает к новым
типам узлов, усложнению парсера и
волкера
Поиск «правильного» формата AST 

и правил обхода – 

сложный процесс проб и ошибок
64
Поиск
Давайте найдем 

все значения цвета?
66
Цвет это ...
• HexColor
• rgb(), rgba(), hls(), hlsa()
• named colors
• deprecated system colors
• vendor named colors
• ...
• CSS Color Module Level 4
• изменения HexColor, rgb(a)/hls(a)
• новое: hwb(), lab(), lch(), color(), color-mod(), device-cmyk()
67
В целом, можно победить – ведь ищем
один узел... если бы не семантика
68
Поиск цвета
69
selector {
font: 10px arial black;
animation-name: red;
whatever: green;
width: blue;
color: superpurple;
}
Сколько значений цвета?
Поиск цвета
70
selector {
font: 10px arial black;
animation-name: red;
whatever: green;
width: blue;
color: superpurple;
}
Ни одного!
Часть имени шрифта

"arial black"
Имя анимации
Неизвестное свойство
В width нельзя указывать цвет
Нет такого цвета
Повышаем ставки – давайте
найдем имена анимаций
71
Типичная задача для удаления не используемых @keyframes
Поиск имени анимации
72
Что является именем анимации?
selector {
animation: infinite forwards normal forwards;
animation: reverse normal forwards;
animation: "reverse" normal forwards;
animation: reverse rotate normal;
animation: "reverse" normal rotate;
}
Поиск имени анимации
73
selector {
animation: infinite forwards normal forwards;
animation: reverse normal forwards;
animation: "reverse" normal forwards;
animation: reverse rotate normal;
animation: "reverse" normal rotate;
}
Сдавайтесь! Это нетривиальная задача
Нет времени объяснять (с) 

тут могут помочь только машины, об этом дальше
Короче, чтобы решать такие задачи
нужно понимать лексическое значение
74
Лексическое значение
76
background: top 100% url(..) no-repeat #008800;
Identifier Url Identifier HexColorPercentage
AST – абстрактные узлы
77
background: top 100% url(..) no-repeat #008800;
Лексическое значение
77
background: top 100% url(..) no-repeat #008800;
background-position
background-image
background-repeat
background-color
Лексическое значение
Как вы поняли что означает

та или иная часть значения?
78
А как должна понять машина?
79
В спецификации
80
В спецификации
80
Грамматика

CSS Values and Units Module
похоже на RegExp, но немного проще
81
drafts.csswg.org/css-values/#value-defs
Шаг первый
Идея, которая поменяла мир (немного)
Идея!
• Собрать синтаксисы в словарь
• Разобрать
• Научиться мапить на AST
• ...
• PROFIT!!!
83
В 2016м нашелся готовый словарь
Mozilla Template:CSSData
84
Таблицы описания свойств из спецификаций
в формате JSON;
использовалось для генерации страниц
developer.mozilla.org
Реализовал разбор грамматики,
загрузил словари, построил граф
зависимостей и тут...
85
CSSData был составлен людьми,
и использовался для генерации страниц для людей
(developer.mozilla.org)
86
😱
О – открытие
Хьюстон, у нас проблемы!
• Ошибки в синтаксисе (нельзя разобрать)
• Некоторые синтаксисы ссылались 

на несуществующие определения
• ...
• Люди не замечали это годами...
87
Я погуглил, пофиксил, 

часть законтрибьютил в CSSData 

(через bugtracker, sic!)
88
Забегая вперед
• Mozilla Template:CSSData – был служебным шаблоном в недрах MDN
• 20 сентября 2016 – дискуссия в багтреке CSSTree относительно словарей
• Призвали ребят из MDN
• Пропушили их разместить CSSData на github
• 19 октября 2016 появился репозиторий mdn/data
• Запушил большую часть фиксов из CSSTree, добавил JSON Schema
• 22 июня 2017 ребята из MDN опубликовали пакет mdn-data 1.0 на npm
• 🎉
89
Словарь mdn/data (CSSData)
стал пригодным для машин
90
🤖
До CSSTree никто не парсил синтаксисы
из спек, авторы спецификаций (пока) не
автоматизируют проверку
91
О – открытие #2
Исправлены ошибки и неточности 

не только в словаре, но и в спецификациях
92
93
background-image: image-set( "foo.png" 1x,
"foo-2x.png" 2x,
"foo-print.png" 600dpi );
Поддерживается в Chrome и Safari
94
background-image: image-set( "foo.png" 1x,
"foo-2x.png" 2x,
"foo-print.png" 600dpi );
Поддерживается в Chrome и Safari
WTF?!
Clarification `Nx` as <resolution>
• Пример нельзя было провалидировать
• Не нашел в спецификациях об этом
• Создал тикет 

https://github.com/w3c/csswg-drafts/issues/461
• В CSS Working Group обсудили вопрос
• Внесены изменения CSS Values and Units Module Level 4
• Роботы победили! 🤖
95
96
Маленькая но важная правка
Спецификации не идеальны,

каждый может помочь сделать их лучше
97
Возможное будущее:
спецификации
адаптированы для машин
98
Сегодня:
спецификации
написаны людьми для людей
Шаг второй
Валидация и побочные продукты
Сразу не получилось полноценно матчить
AST узлы на синтаксисы,
но получилось валидировать
100
Инструменты «хелперы»
на CSSTree для нужд CSSTree
101
102
csstree.github.io/docs/syntax.html
Документация CSS синтаксиса
103
csstree.github.io/docs/validator.html
Валидатор CSS (пока только значения)
Прикладное применение
104
Плагины/пакеты
• csstree-validator – npm пакет + консольная команда
• stylelint-csstree-validator – плагин для stylelint
• gulp-csstree – плагин для gulp
• SublimeLinter-contrib-csstree – плагин для Sublime Text
• vscode-csstree – плагин для VS Code
• atom-plugin – плагин для Atom
105
Огромное спасибо Сергею Мелюкову за его вклад и поддержку!
Шаг третий
Кто ищет – тот найдет
Доработка матчинга – 

новые возможности
107
Вспомним пример ...
108
Теперь CSSTree так видит значение 🤘
Можно трассировать каждый узел
109
Узнать у CSSTree лексический тип
110
csstree.lexer
.matchDeclaration(this.declaration)
.isType(node, 'color')
Используется в CSSO при минификации значений цвета
Синтаксис цвета (без L4)
Синтаксис свойства animation
Поиск с CSSTree
113
// найти все цвета
csstree.lexer.matchAllFragments(ast, 'Type', 'color')
// ... имена анимаций
csstree.lexer.matchAllFragments(ast, 'Type', 'keyframes-name')
// ... имена шрифтов
csstree.lexer.matchAllFragments(ast, 'Type', 'family-name')
Что дальше?
Чтобы добавить новые свойства и
синтаксисы – не нужно менять код, 

достаточно обновить словарь
115
Возможность экспериментировать с новыми синтаксисами,

создавать свои синтаксисы
Решение других задач
• Разворачивание и свертка shorthand-свойств

(например, background <-> background-*)
• Мапинг значения на initial value
• Применение не только для значений деклараций
• Исправить проблемы для сложных случаев
• ...
116
Почему стоит начать изучать грамматику 

CSS Values and Units Module
уже сегодня
117
CSS Properties and Values API Level 1
Позволит задавать свой синтаксис 

для ваших Custom properties
Итоги
Ключевое
• Появился инструмент для работы с грамматикой 

CSS Values and Units Module, которая может стать прикладной
• Приведен в порядок словарь mdn/data (теперь для машин)
• Можно искать фрагменты значений по лексическому типу
• Несколько действительно полезных инструментов –
информационных и прикладных (пощупайте!)
• Новые возможности для ваших идей
119
Словари
Дальнейшее совершенствование
инструментов не возможно без словарей
для машин
121
Словари
• mdn/data – описание свойств (таблицы из спек),
директив, селекторов и т.д.
• mdn/browser-compat-data – поддержка разных
возможностей (JS/CSS/API) браузерами
• known-css-properties – список известных свойств
• caniuse – поддержка браузерами некоторых частей CSS
122
CSS свойств
•mdn/data – 367
•Alexa Top 250 – 483
•Известных свойств – 1150
Что можно сделать:
• найти неописанное свойство
• нагуглить описание
• сделать PR с описанием в JSON
real-web-css
124
real-web-css
125
Заключение
• Всё сложно
• Много нерешенный вопросов в обработке CSS
• Инструменты совершенствуются и переходят на
новый уровень
• Новые возможности
• Словари наше всё
• Вы можете помочь!
127
Обратите внимание на CSS
Роман Дворнов
@rdvornov
rdvornov@gmail.com
Спасибо!
CSSTree
github.com/csstree

Mais conteúdo relacionado

Mais procurados

Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".
Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".
Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".Badoo Development
 
Web осень 2013 лекция 4
Web осень 2013 лекция 4Web осень 2013 лекция 4
Web осень 2013 лекция 4Technopark
 
Баба Яга против!
Баба Яга против!Баба Яга против!
Баба Яга против!Roman Dvornov
 
Basis.js – «под капотом»
Basis.js – «под капотом»Basis.js – «под капотом»
Basis.js – «под капотом»Roman Dvornov
 
Web осень 2013 лекция 2
Web осень 2013 лекция 2Web осень 2013 лекция 2
Web осень 2013 лекция 2Technopark
 
React со скоростью света: не совсем обычный серверный рендеринг
React со скоростью света: не совсем обычный серверный рендерингReact со скоростью света: не совсем обычный серверный рендеринг
React со скоростью света: не совсем обычный серверный рендерингTimophy Chaptykov
 
Web осень 2013 лекция 6
Web осень 2013 лекция 6Web осень 2013 лекция 6
Web осень 2013 лекция 6Technopark
 
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)Roman Dvornov
 
Систематизация экспрешнов в IE
Систематизация экспрешнов в IEСистематизация экспрешнов в IE
Систематизация экспрешнов в IERoman Komarov
 
basis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворкbasis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворкRoman Dvornov
 
SPA инструменты
SPA инструментыSPA инструменты
SPA инструментыRoman Dvornov
 
Профилирование и отладка Django
Профилирование и отладка DjangoПрофилирование и отладка Django
Профилирование и отладка DjangoVladimir Rudnyh
 
Web осень 2013 лекция 8
Web осень 2013 лекция 8Web осень 2013 лекция 8
Web осень 2013 лекция 8Technopark
 
Взломать сайт на ASP.NET
Взломать сайт на ASP.NETВзломать сайт на ASP.NET
Взломать сайт на ASP.NETPositive Hack Days
 
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOSКурсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOSГлеб Тарасов
 
Web осень 2013 лекция 9
Web осень 2013 лекция 9Web осень 2013 лекция 9
Web осень 2013 лекция 9Technopark
 
Оптимизация производительности Python
Оптимизация производительности PythonОптимизация производительности Python
Оптимизация производительности PythonPyNSK
 
Максим Щепелин. "Unittesting. Как?"
Максим Щепелин. "Unittesting. Как?"Максим Щепелин. "Unittesting. Как?"
Максим Щепелин. "Unittesting. Как?"Python Meetup
 

Mais procurados (20)

Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".
Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".
Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".
 
Web осень 2013 лекция 4
Web осень 2013 лекция 4Web осень 2013 лекция 4
Web осень 2013 лекция 4
 
Баба Яга против!
Баба Яга против!Баба Яга против!
Баба Яга против!
 
Basis.js – «под капотом»
Basis.js – «под капотом»Basis.js – «под капотом»
Basis.js – «под капотом»
 
Javascript
JavascriptJavascript
Javascript
 
Web осень 2013 лекция 2
Web осень 2013 лекция 2Web осень 2013 лекция 2
Web осень 2013 лекция 2
 
React со скоростью света: не совсем обычный серверный рендеринг
React со скоростью света: не совсем обычный серверный рендерингReact со скоростью света: не совсем обычный серверный рендеринг
React со скоростью света: не совсем обычный серверный рендеринг
 
Web осень 2013 лекция 6
Web осень 2013 лекция 6Web осень 2013 лекция 6
Web осень 2013 лекция 6
 
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
 
Систематизация экспрешнов в IE
Систематизация экспрешнов в IEСистематизация экспрешнов в IE
Систематизация экспрешнов в IE
 
Шаблонизация
ШаблонизацияШаблонизация
Шаблонизация
 
basis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворкbasis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворк
 
SPA инструменты
SPA инструментыSPA инструменты
SPA инструменты
 
Профилирование и отладка Django
Профилирование и отладка DjangoПрофилирование и отладка Django
Профилирование и отладка Django
 
Web осень 2013 лекция 8
Web осень 2013 лекция 8Web осень 2013 лекция 8
Web осень 2013 лекция 8
 
Взломать сайт на ASP.NET
Взломать сайт на ASP.NETВзломать сайт на ASP.NET
Взломать сайт на ASP.NET
 
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOSКурсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
 
Web осень 2013 лекция 9
Web осень 2013 лекция 9Web осень 2013 лекция 9
Web осень 2013 лекция 9
 
Оптимизация производительности Python
Оптимизация производительности PythonОптимизация производительности Python
Оптимизация производительности Python
 
Максим Щепелин. "Unittesting. Как?"
Максим Щепелин. "Unittesting. Как?"Максим Щепелин. "Unittesting. Как?"
Максим Щепелин. "Unittesting. Как?"
 

Semelhante a CSS глазами машин

Верстка_Лекция_3
Верстка_Лекция_3Верстка_Лекция_3
Верстка_Лекция_3itc73
 
Технологии анализа бинарного кода приложений: требования, проблемы, инструменты
Технологии анализа бинарного кода приложений: требования, проблемы, инструментыТехнологии анализа бинарного кода приложений: требования, проблемы, инструменты
Технологии анализа бинарного кода приложений: требования, проблемы, инструментыPositive Development User Group
 
Парсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricksПарсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricksRoman Dvornov
 
Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3Яковенко Кирилл
 
Интервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ Library
Интервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ LibraryИнтервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ Library
Интервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ LibraryTatyanazaxarova
 
Present forms&css
Present forms&cssPresent forms&css
Present forms&cssitc73
 
Web осень 2012 лекция 8
Web осень 2012 лекция 8Web осень 2012 лекция 8
Web осень 2012 лекция 8Technopark
 
Дмитрий Прокопцев "Memory-mapped storage: ещё один подход к сериализации данных"
Дмитрий Прокопцев "Memory-mapped storage: ещё один подход к сериализации данных"Дмитрий Прокопцев "Memory-mapped storage: ещё один подход к сериализации данных"
Дмитрий Прокопцев "Memory-mapped storage: ещё один подход к сериализации данных"Yandex
 
Crossbrowser Css layout
Crossbrowser Css layoutCrossbrowser Css layout
Crossbrowser Css layoutDarkestMaster
 
презентация 4. введение в css
презентация 4. введение в cssпрезентация 4. введение в css
презентация 4. введение в cssRusov1
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?Vasil Remeniuk
 
Компонентная разработка на Stylus, Jade, Typescript - Леонид Ширманов
Компонентная разработка на Stylus, Jade, Typescript - Леонид ШирмановКомпонентная разработка на Stylus, Jade, Typescript - Леонид Ширманов
Компонентная разработка на Stylus, Jade, Typescript - Леонид ШирмановMoscowJS
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибкиAndrey Karpov
 
Мировые информационные ресурсы. Лекция 4
Мировые информационные ресурсы. Лекция 4Мировые информационные ресурсы. Лекция 4
Мировые информационные ресурсы. Лекция 4Dmitriy Krukov
 

Semelhante a CSS глазами машин (20)

Верстка_Лекция_3
Верстка_Лекция_3Верстка_Лекция_3
Верстка_Лекция_3
 
Технологии анализа бинарного кода приложений: требования, проблемы, инструменты
Технологии анализа бинарного кода приложений: требования, проблемы, инструментыТехнологии анализа бинарного кода приложений: требования, проблемы, инструменты
Технологии анализа бинарного кода приложений: требования, проблемы, инструменты
 
Парсим CSS
Парсим CSSПарсим CSS
Парсим CSS
 
Парсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricksПарсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricks
 
Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3
 
Интервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ Library
Интервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ LibraryИнтервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ Library
Интервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ Library
 
Present forms&css
Present forms&cssPresent forms&css
Present forms&css
 
Web осень 2012 лекция 8
Web осень 2012 лекция 8Web осень 2012 лекция 8
Web осень 2012 лекция 8
 
Jquery
JqueryJquery
Jquery
 
Дмитрий Прокопцев "Memory-mapped storage: ещё один подход к сериализации данных"
Дмитрий Прокопцев "Memory-mapped storage: ещё один подход к сериализации данных"Дмитрий Прокопцев "Memory-mapped storage: ещё один подход к сериализации данных"
Дмитрий Прокопцев "Memory-mapped storage: ещё один подход к сериализации данных"
 
Crossbrowser Css layout
Crossbrowser Css layoutCrossbrowser Css layout
Crossbrowser Css layout
 
презентация 4. введение в css
презентация 4. введение в cssпрезентация 4. введение в css
презентация 4. введение в css
 
Js fuckworks
Js fuckworksJs fuckworks
Js fuckworks
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
 
Rgsu04
Rgsu04Rgsu04
Rgsu04
 
Rgsu04
Rgsu04Rgsu04
Rgsu04
 
Компонентная разработка на Stylus, Jade, Typescript - Леонид Ширманов
Компонентная разработка на Stylus, Jade, Typescript - Леонид ШирмановКомпонентная разработка на Stylus, Jade, Typescript - Леонид Ширманов
Компонентная разработка на Stylus, Jade, Typescript - Леонид Ширманов
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
 
Мировые информационные ресурсы. Лекция 4
Мировые информационные ресурсы. Лекция 4Мировые информационные ресурсы. Лекция 4
Мировые информационные ресурсы. Лекция 4
 

Mais de Roman Dvornov

Unit-тестирование скриншотами: преодолеваем звуковой барьер
Unit-тестирование скриншотами: преодолеваем звуковой барьерUnit-тестирование скриншотами: преодолеваем звуковой барьер
Unit-тестирование скриншотами: преодолеваем звуковой барьерRoman Dvornov
 
Масштабируемая архитектура фронтенда
Масштабируемая архитектура фронтендаМасштабируемая архитектура фронтенда
Масштабируемая архитектура фронтендаRoman Dvornov
 
My Open Source (Sept 2017)
My Open Source (Sept 2017)My Open Source (Sept 2017)
My Open Source (Sept 2017)Roman Dvornov
 
Rempl – крутая платформа для крутых инструментов
Rempl – крутая платформа для крутых инструментовRempl – крутая платформа для крутых инструментов
Rempl – крутая платформа для крутых инструментовRoman Dvornov
 
Remote (dev)tools своими руками
Remote (dev)tools своими рукамиRemote (dev)tools своими руками
Remote (dev)tools своими рукамиRoman Dvornov
 
Как сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееКак сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееRoman Dvornov
 
CSS parsing: performance tips & tricks
CSS parsing: performance tips & tricksCSS parsing: performance tips & tricks
CSS parsing: performance tips & tricksRoman Dvornov
 
CSSO – compress CSS (english version)
CSSO – compress CSS (english version)CSSO – compress CSS (english version)
CSSO – compress CSS (english version)Roman Dvornov
 
CSSO — сжимаем CSS (часть 2)
CSSO — сжимаем CSS (часть 2)CSSO — сжимаем CSS (часть 2)
CSSO — сжимаем CSS (часть 2)Roman Dvornov
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
Жизнь в изоляции
Жизнь в изоляцииЖизнь в изоляции
Жизнь в изоляцииRoman Dvornov
 
Инструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныИнструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныRoman Dvornov
 
Карточный домик
Карточный домикКарточный домик
Карточный домикRoman Dvornov
 
Компонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективноКомпонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективноRoman Dvornov
 

Mais de Roman Dvornov (15)

Unit-тестирование скриншотами: преодолеваем звуковой барьер
Unit-тестирование скриншотами: преодолеваем звуковой барьерUnit-тестирование скриншотами: преодолеваем звуковой барьер
Unit-тестирование скриншотами: преодолеваем звуковой барьер
 
Масштабируемая архитектура фронтенда
Масштабируемая архитектура фронтендаМасштабируемая архитектура фронтенда
Масштабируемая архитектура фронтенда
 
My Open Source (Sept 2017)
My Open Source (Sept 2017)My Open Source (Sept 2017)
My Open Source (Sept 2017)
 
Rempl – крутая платформа для крутых инструментов
Rempl – крутая платформа для крутых инструментовRempl – крутая платформа для крутых инструментов
Rempl – крутая платформа для крутых инструментов
 
Remote (dev)tools своими руками
Remote (dev)tools своими рукамиRemote (dev)tools своими руками
Remote (dev)tools своими руками
 
Как сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееКак сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрее
 
CSS parsing: performance tips & tricks
CSS parsing: performance tips & tricksCSS parsing: performance tips & tricks
CSS parsing: performance tips & tricks
 
CSSO – compress CSS (english version)
CSSO – compress CSS (english version)CSSO – compress CSS (english version)
CSSO – compress CSS (english version)
 
CSSO — сжимаем CSS (часть 2)
CSSO — сжимаем CSS (часть 2)CSSO — сжимаем CSS (часть 2)
CSSO — сжимаем CSS (часть 2)
 
Component Inspector
Component InspectorComponent Inspector
Component Inspector
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
Жизнь в изоляции
Жизнь в изоляцииЖизнь в изоляции
Жизнь в изоляции
 
Инструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныИнструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важны
 
Карточный домик
Карточный домикКарточный домик
Карточный домик
 
Компонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективноКомпонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективно
 

CSS глазами машин

  • 1. CSS глазами машин Роман Дворнов Avito Москва 2018
  • 2. Работаю в Avito Open source:
 basis.js, CSSO, 
 component-inspector, 
 csstree, rempl и другие
  • 3. Доклад о том, как машины* 
 понимают CSS и обрабатывают его,
 какие есть сложности и проблемы 3 * программы для анализа и трансформации CSS
  • 4. – Андрей Ситник “Машины должны страдать!” 4
  • 5. Но сейчас больше 
 страдают разработчики 5
  • 6. Но сейчас больше 
 страдают разработчики 5 Сложно обрабатывать CSS, т.к. очень много нюансов «создатели»
  • 7. Но сейчас больше 
 страдают разработчики 5 Сложно обрабатывать CSS, т.к. очень много нюансов «создатели» Баги и непредсказуемость результатов «пользователи»
  • 8. Рассказываю, потому что подгорает :) • CSSO (мейнтейнер) – минификатор CSS • CSSTree (автор) – набор инструментов по работе с CSS, включающий parser, walker, lexer, generator и т.д. 6
  • 10. CSS #практики #методологии #трюки #тонкости #возможности #multitarget... 8
  • 11. Сложности • Большое количество директив, свойств, функций и т.д. • Исключения и особые правила • Белые пятна в спецификациях • CSS меняется • Разная поддержка браузерами • Баги браузеров • Хаки 9
  • 12. Проблемы • К CSS меньше внимания чем к другим веб-технологиям • Низкий уровень знания CSS • Препроцессоры • FCSS (Fantasy CSS из доклада Вадима Макеева) • Много CSS кода в проектах (мегабайты) • Недооценивание масштаба проблем (я оптимист!) 10
  • 13. • Директивы (at-rule) – 40 • Медиа фичи (media feature) – 69 • Псевдо-классы – 125 • Псевдо-элементы – 146 • Свойства – 1150 • Функции – 69 • Единицы измерения (unit) – 30 11 • Цифры включают легаси и вендорные имена • Собрано для словарей CSSTree 
 в рамках проекта real-web-css
  • 14. Без машин не справиться! 12
  • 15. Программы для анализа и трансформации CSS
 #каксейчас #проблемы #вызовы
  • 16. А вы задумывались ... • Как машины видят CSS? • Как понимают его значение? • Как понимают что правильно, а что нет? • Что нужно, чтобы объяснить им как должно быть? • ... 14
  • 18. Rule (правило) 16 .foo, body > .bar:hover { color: red; }
  • 19. Rule (правило) 16 .foo, body > .bar:hover { color: red; } Prelude (прелюдия)
  • 20. Rule (правило) 16 .foo, body > .bar:hover { color: red; } Prelude (прелюдия) Block (блок)
  • 21. Rule (правило) 16 .foo, body > .bar:hover { color: red; } Prelude (прелюдия) Block (блок) Selector (селектор*) * в докладе термин "селектор" ссылается на complex selector
  • 22. Rule (правило) 16 .foo, body > .bar:hover { color: red; } Prelude (прелюдия) Block (блок) Declaration (декларация) Selector (селектор*) * в докладе термин "селектор" ссылается на complex selector
  • 23. At-rule (директива*) 17 @media all, (max-width: 800px) { ... } * перевод из словаря терминов по фронтенду
  • 24. At-rule (директива*) 17 @media all, (max-width: 800px) { ... } At-keyword (ключ директивы*) * перевод из словаря терминов по фронтенду
  • 25. At-rule (директива*) 17 @media all, (max-width: 800px) { ... } Prelude (прелюдия) At-keyword (ключ директивы*) * перевод из словаря терминов по фронтенду
  • 26. At-rule (директива*) 17 @media all, (max-width: 800px) { ... } Prelude (прелюдия) Block (блок) At-keyword (ключ директивы*) * перевод из словаря терминов по фронтенду
  • 29. AST* структура данных 
 для представления исходного кода 20 * Abstract Syntax Tree, тот самый «машинный»
  • 30. 21 .foo { color: red; } { type: "Rule", prelude: ".foo", declarations: [ { type: "Declaration", property: "color", value: "red" } ] } Исходный код AST Строка (набор символов), сложно определить где какая часть Структура (дерево), 
 все разложено по полочкам
  • 31. 22 Код (Строка) РезультатASTParser Walker Generator Lexer Обход узлов AST Применение лексических правил Преобразование
 строки в AST (перевод 
 на «машинный») Обычно новый код (строка) 
 + source map Преобразование
 AST в другое 
 представление (обратное к Parser) Общая схема по работе с кодом
  • 32. Так работают ... • Линтеры (проверяют ошибки) • Минификаторы • Подсказки в IDE/редакторах • Программы форматирования кода • Пре- и пост-процессоры • Autoprefixer и т.д. 23
  • 34. Современные JavaScript парсеры
 (esprima, acorn, babylon, ...)
 используют спецификацию ESTree для формата AST 25
  • 35. Современные CSS парсеры
 (PostCSS, CSSTree, Gonzales PE...) используют каждый свой формат AST, 
 общей спецификации нет 26
  • 36. Какие сложности это вызывает • Нет совместимости между инструментами с разными парсерами • Разработчики парсеров решают одни и те же проблемы • Сложно с именованием типов узлов и их свойств • Открытые вопросы как представлять разные части CSS • Конфликт интересов в формате для разных задач • Не понятно как правильно 27
  • 37. Спецификации CSS 
 не рассматривают формат AST, 
 так как они нацелены на браузеры 28
  • 38. Что получается у меня: 29 Формат AST в CSSTree По прежнему есть открытые вопросы :(
  • 42. Пример 31 width: 100px PostCSS "100px" не разбирает значения CSSTree { type: "Dimension", value: "100", unit: "px" } 1 узел
  • 43. Пример 31 width: 100px PostCSS "100px" не разбирает значения CSSTree { type: "Dimension", value: "100", unit: "px" } 1 узел Gonzales-pe { type: "dimension", content: [{ type: "number", content: "100" }, { type: "ident", content: "px" }] } 3 узла
  • 44. Детальность 32 Меньше Больше • Больше типов узлов • Больше памяти на хранение узлов • Больше времени на обход дерева • Необходим дополнительный разбор • Так как "доразбор" на стороне пользователя: больше зависимостей и шансов сломаться
  • 45. Пример: перевод px в rem 33 // !singlequotes|!doublequotes|!url()|pixelunit var pxRegex = /"[^"]+"|'[^']+'|url([^)]+)|(d*.?d+)px/ig; ast.walkDecls(function (decl, i) { ... decl.value = decl.value.replace(pxRegex, function (m, $1) { // 16px -> 1rem }); }); postcss-pxtorem (PostCSS плагин) (недетальное AST)
  • 46. Та же задача с детальным AST 34 csstree.walk(ast, function (node) { ... if (node.type === 'Dimension' && node.unit === 'px') { // ... вычисление нового значения (newValue) node.value = newValue; node.unit = 'rem'; } }); (как мог бы выглядеть плагин на CSSTree)
  • 47. Пример: подсчет specificity 35 ... attributeRegex = /([[^]]+])/g, idRegex = /(#[^#s+>~.[:]+)/g, classRegex = /(.[^s+>~.[:]+)/g, pseudoElementRegex = /(::[^s+>~.[:]+|:first-line|:first-letter|:before|:after)/gi, pseudoClassWithBracketsRegex = /(:[w-]+([^)]*))/gi, pseudoClassRegex = /(:[^s+>~.[:]+)/g, elementRegex = /([^s+>~.[:]+)/g; ... specificity (1.2M downloads/month, 32 dependants) (не детальное AST)
  • 48. Пример: подсчет specificity 36 ... var A = 0, B = 0, C = 0; simpleSelector.children.each(function walk(node) { switch (node.type) { case 'SelectorList': case 'Selector': node.children.each(walk); break; case 'IdSelector': A++; break; case 'ClassSelector': case 'AttributeSelector': B++; break; ... модуль подсчета specificity в CSSO (57 SLOC) (детальное AST)
  • 49. Детальность AST • Нужный уровень детальности зависит от задачи 
 (например, если обрабатываются только селекторы, 
 не нужно разбирать значения деклараций) • Уровень детализации зависит от парсера • В некоторых парсерах можно управлять уровнем детализации 37
  • 50. Несколько примеров • PostCSS
 Не разбирает (оставляет строкой): прелюдии у директив и правил (selector list), значения деклараций. Детализация не настраивается • CSSTree
 Не разбирает значения custom properties, но можно включить настройкой парсера. Можно отключить разбор прелюдий и значений деклараций • Gonzales PE
 Самой большой уровень детализации. Детализация не настраивается 38
  • 51. Детальность в CSSTree 39 csstree.parse('@example 1 2;'); { "type": "Atrule", "prelude": { "type": "AtrulePrelude", "children": [ { "type": "Number", "value": "1" }, { "type": "WhiteSpace", "value": " " }, { "type": "Number", "value": "2" } ] }, "block": null }
  • 52. Детальность в CSSTree 40 csstree.parse('@example 1 2;', { parseAtrulePrelude: false }); { "type": "Atrule", "prelude": { "type": "Raw", "value": "1 2" }, "block": null }
  • 53. Паритет CSSTree с PostCSS 41 csstree.parse(css, { positions: true, parseAtrulePrelude: false, parseRulePrelude: false, parseValue: false });
  • 55. CSS is hard • at-rules @media, @supports, @font-face, … • необязательные кавычки url(…), [name=value], … • сложные функции calc(), var(), attr(), … • экранирование • bad-url, bad-string… • … 43
  • 56. 44 #31 + 2 { content: "hello world"; background: url(p(4).jpg); } Экранирование drafts.csswg.org/cssom/#the-css.escape()-method В идентификаторах можно использовать любые символы, если экранировать; в браузерах есть метод для этого – CSS.escape() CSS.escape('1 + 2') === '31 + 2'
  • 57. 45 #31 + 2 { content: "hello world"; background: url(p(4).jpg); } Экранирование www.w3.org/TR/CSS22/grammar.html#grammar Можно экранировать перевод строки в строках, 
 как в JavaScript
  • 58. 46 #31 +2 { content: "hello world"; background: url(p(4).jpg); } Экранирование www.w3.org/TR/CSS22/grammar.html#grammar Можно экранировать специальные символы 
 в url()
  • 60. 48 @supports (display: flex) { .simple { display: flex; } } @supports
  • 61. 49 @supports (display: flex) { .simple { display: flex; } } @supports Декларация
  • 62. 50 @supports (display: flex) { .simple { display: flex; } } @supports Декларация Тоже декларация
  • 63. 51 @supports (background: top calc(25% + 2px) !important) { … } @supports С точки зрения спецификаций разрешается все, 
 что можно в декларации, даже !important www.w3.org/TR/css3-conditional/#at-supports
  • 64. CSS Syntax Module Level 3 Когда возникает ошибка в CSS, парсер постепенно восстанавливается, выкидывая минимальное количество контента перед возвращением к разбору в обычном режиме. Это связано с тем, что ошибки не всегда являются ошибками – новый синтаксис выглядит как ошибка для старых парсеров, и это полезно для добавления нового синтаксиса в язык ... 52 § 2.2. Error Handling
  • 65. Парсеры CSS толерантные к ошибкам • CSSTree – толерантный к ошибкам согласно спецификации • PostCSS – толерантен к ошибкам, если используется postcss-safe-parser вместо стандартного парсера. Соответствие спецификации не известно • Это все варианты, что я знаю... 53 * парсеры написанные на JavaScript
  • 67. Ключевое • Нет общего формата AST для CSS • Уровень детализации AST может быть разный • Детальное AST может требовать больше ресурсов, 
 но удобнее для анализа и трансформации • Парсинг CSS в AST сложная задача, много нюансов • CSS парсер должен быть толерантным к ошибкам 55
  • 68. Формат AST и его свойства,
 определяют что и как 
 машины могут делать с CSS 56
  • 70. Обход осуществляет walker, обходит все узлы дерева и вызывает функцию обработчик 58
  • 72. Сложности: декларация 60 @supports (display: flex) { .foo { font-family: "Open Sans"; } } @font-face { font-family: "Open Sans"; }
  • 73. Сложности: декларация 61 @supports (display: flex) { .foo { font-family: "Open Sans"; } } @font-face { font-family: "Open Sans"; } В CSSTree это все декларации (тип узла Declaration): • Декларации внутри @supports обычно обходить не нужно, их приходится игнорировать (а если нужны?) • Внутри @font-face на самом деле не декларация, а дескриптор (decscriptor); для них, например, нельзя применять !important (будет считать ошибкой и браузер проигнорирует дескриптор)
  • 74. Сложности: селекторы 62 @page :first { ... } @keyframes name { from { ... } 25%, 75% { ... } to { ... } } .foo { ... }
  • 75. Сложности: селекторы 63 @page :first { ... } @keyframes name { from { ... } 25%, 75% { ... } to { ... } } .foo { ... } В CSSTree это все селекторы (тип узла SelectorList): • Но обходить селекторы в @page обычно не нужно; да и по спеке это <page-selector-list> • Внутри @keyframes это не обычные селекторы – <keyframe-selector>; а блок <keyframe-block>, хотя внутри все те же декларации • Все это подталкивает к новым типам узлов, усложнению парсера и волкера
  • 76. Поиск «правильного» формата AST 
 и правил обхода – 
 сложный процесс проб и ошибок 64
  • 78. Давайте найдем 
 все значения цвета? 66
  • 79. Цвет это ... • HexColor • rgb(), rgba(), hls(), hlsa() • named colors • deprecated system colors • vendor named colors • ... • CSS Color Module Level 4 • изменения HexColor, rgb(a)/hls(a) • новое: hwb(), lab(), lch(), color(), color-mod(), device-cmyk() 67
  • 80. В целом, можно победить – ведь ищем один узел... если бы не семантика 68
  • 81. Поиск цвета 69 selector { font: 10px arial black; animation-name: red; whatever: green; width: blue; color: superpurple; } Сколько значений цвета?
  • 82. Поиск цвета 70 selector { font: 10px arial black; animation-name: red; whatever: green; width: blue; color: superpurple; } Ни одного! Часть имени шрифта
 "arial black" Имя анимации Неизвестное свойство В width нельзя указывать цвет Нет такого цвета
  • 83. Повышаем ставки – давайте найдем имена анимаций 71 Типичная задача для удаления не используемых @keyframes
  • 84. Поиск имени анимации 72 Что является именем анимации? selector { animation: infinite forwards normal forwards; animation: reverse normal forwards; animation: "reverse" normal forwards; animation: reverse rotate normal; animation: "reverse" normal rotate; }
  • 85. Поиск имени анимации 73 selector { animation: infinite forwards normal forwards; animation: reverse normal forwards; animation: "reverse" normal forwards; animation: reverse rotate normal; animation: "reverse" normal rotate; } Сдавайтесь! Это нетривиальная задача Нет времени объяснять (с) 
 тут могут помочь только машины, об этом дальше
  • 86. Короче, чтобы решать такие задачи нужно понимать лексическое значение 74
  • 88. 76 background: top 100% url(..) no-repeat #008800; Identifier Url Identifier HexColorPercentage AST – абстрактные узлы
  • 89. 77 background: top 100% url(..) no-repeat #008800; Лексическое значение
  • 90. 77 background: top 100% url(..) no-repeat #008800; background-position background-image background-repeat background-color Лексическое значение
  • 91. Как вы поняли что означает
 та или иная часть значения? 78
  • 92. А как должна понять машина? 79
  • 95. Грамматика
 CSS Values and Units Module похоже на RegExp, но немного проще 81 drafts.csswg.org/css-values/#value-defs
  • 96. Шаг первый Идея, которая поменяла мир (немного)
  • 97. Идея! • Собрать синтаксисы в словарь • Разобрать • Научиться мапить на AST • ... • PROFIT!!! 83
  • 98. В 2016м нашелся готовый словарь Mozilla Template:CSSData 84 Таблицы описания свойств из спецификаций в формате JSON; использовалось для генерации страниц developer.mozilla.org
  • 99. Реализовал разбор грамматики, загрузил словари, построил граф зависимостей и тут... 85
  • 100. CSSData был составлен людьми, и использовался для генерации страниц для людей (developer.mozilla.org) 86 😱 О – открытие
  • 101. Хьюстон, у нас проблемы! • Ошибки в синтаксисе (нельзя разобрать) • Некоторые синтаксисы ссылались 
 на несуществующие определения • ... • Люди не замечали это годами... 87
  • 102. Я погуглил, пофиксил, 
 часть законтрибьютил в CSSData 
 (через bugtracker, sic!) 88
  • 103. Забегая вперед • Mozilla Template:CSSData – был служебным шаблоном в недрах MDN • 20 сентября 2016 – дискуссия в багтреке CSSTree относительно словарей • Призвали ребят из MDN • Пропушили их разместить CSSData на github • 19 октября 2016 появился репозиторий mdn/data • Запушил большую часть фиксов из CSSTree, добавил JSON Schema • 22 июня 2017 ребята из MDN опубликовали пакет mdn-data 1.0 на npm • 🎉 89
  • 104. Словарь mdn/data (CSSData) стал пригодным для машин 90 🤖
  • 105. До CSSTree никто не парсил синтаксисы из спек, авторы спецификаций (пока) не автоматизируют проверку 91 О – открытие #2
  • 106. Исправлены ошибки и неточности 
 не только в словаре, но и в спецификациях 92
  • 107. 93 background-image: image-set( "foo.png" 1x, "foo-2x.png" 2x, "foo-print.png" 600dpi ); Поддерживается в Chrome и Safari
  • 108. 94 background-image: image-set( "foo.png" 1x, "foo-2x.png" 2x, "foo-print.png" 600dpi ); Поддерживается в Chrome и Safari WTF?!
  • 109. Clarification `Nx` as <resolution> • Пример нельзя было провалидировать • Не нашел в спецификациях об этом • Создал тикет 
 https://github.com/w3c/csswg-drafts/issues/461 • В CSS Working Group обсудили вопрос • Внесены изменения CSS Values and Units Module Level 4 • Роботы победили! 🤖 95
  • 111. Спецификации не идеальны,
 каждый может помочь сделать их лучше 97
  • 112. Возможное будущее: спецификации адаптированы для машин 98 Сегодня: спецификации написаны людьми для людей
  • 113. Шаг второй Валидация и побочные продукты
  • 114. Сразу не получилось полноценно матчить AST узлы на синтаксисы, но получилось валидировать 100
  • 119. Плагины/пакеты • csstree-validator – npm пакет + консольная команда • stylelint-csstree-validator – плагин для stylelint • gulp-csstree – плагин для gulp • SublimeLinter-contrib-csstree – плагин для Sublime Text • vscode-csstree – плагин для VS Code • atom-plugin – плагин для Atom 105 Огромное спасибо Сергею Мелюкову за его вклад и поддержку!
  • 120. Шаг третий Кто ищет – тот найдет
  • 121. Доработка матчинга – 
 новые возможности 107
  • 122. Вспомним пример ... 108 Теперь CSSTree так видит значение 🤘
  • 124. Узнать у CSSTree лексический тип 110 csstree.lexer .matchDeclaration(this.declaration) .isType(node, 'color') Используется в CSSO при минификации значений цвета
  • 127. Поиск с CSSTree 113 // найти все цвета csstree.lexer.matchAllFragments(ast, 'Type', 'color') // ... имена анимаций csstree.lexer.matchAllFragments(ast, 'Type', 'keyframes-name') // ... имена шрифтов csstree.lexer.matchAllFragments(ast, 'Type', 'family-name')
  • 129. Чтобы добавить новые свойства и синтаксисы – не нужно менять код, 
 достаточно обновить словарь 115 Возможность экспериментировать с новыми синтаксисами,
 создавать свои синтаксисы
  • 130. Решение других задач • Разворачивание и свертка shorthand-свойств
 (например, background <-> background-*) • Мапинг значения на initial value • Применение не только для значений деклараций • Исправить проблемы для сложных случаев • ... 116
  • 131. Почему стоит начать изучать грамматику 
 CSS Values and Units Module уже сегодня 117 CSS Properties and Values API Level 1 Позволит задавать свой синтаксис 
 для ваших Custom properties
  • 133. Ключевое • Появился инструмент для работы с грамматикой 
 CSS Values and Units Module, которая может стать прикладной • Приведен в порядок словарь mdn/data (теперь для машин) • Можно искать фрагменты значений по лексическому типу • Несколько действительно полезных инструментов – информационных и прикладных (пощупайте!) • Новые возможности для ваших идей 119
  • 135. Дальнейшее совершенствование инструментов не возможно без словарей для машин 121
  • 136. Словари • mdn/data – описание свойств (таблицы из спек), директив, селекторов и т.д. • mdn/browser-compat-data – поддержка разных возможностей (JS/CSS/API) браузерами • known-css-properties – список известных свойств • caniuse – поддержка браузерами некоторых частей CSS 122
  • 137. CSS свойств •mdn/data – 367 •Alexa Top 250 – 483 •Известных свойств – 1150 Что можно сделать: • найти неописанное свойство • нагуглить описание • сделать PR с описанием в JSON
  • 141. • Всё сложно • Много нерешенный вопросов в обработке CSS • Инструменты совершенствуются и переходят на новый уровень • Новые возможности • Словари наше всё • Вы можете помочь! 127