Atomic CSS: верстка и легкость бытия
Валентин Ульянов
Atomic CSS:
верстка и легкость бытия
Валентин Ульянов
Обо мне
- В IT больше 8 лет
- Делаю бэкенд на Node.js и тулинг
- Разрабатываю open source-проект
- Выступаю на конференциях и веду
IT-сообщество в Питере на 500+ человек
Я и Atomic CSS
- В теме с 2018
- Смотрел все инструменты, у которых >20 звезд на гитхабе
Я и Atomic CSS
- В теме с 2018
- Смотрел все инструменты, у которых >20 звезд на гитхабе
- 3 года карьеры много верстал
Я и Atomic CSS
- В теме с 2018
- Смотрел все инструменты, у которых >20 звезд на гитхабе
- 3 года карьеры много верстал
- В разработку своего инструмента вложил >1000 часов
Содержание
- Проблемы верстки
- Atomic CSS как решение
- Разбор мифов
- Применение на практике
- Заключение
Стандартные вопросы БЭМ
- Блок это или элемент?
- Делать микс или модификатор?
Стандартные вопросы БЭМ
- Блок это или элемент?
- Делать микс или модификатор?
- Структура каталогов?
Продвинутые вопросы БЭМ
- Уровни переопределения
- Собирать много блоков без коллизий
Продвинутые вопросы БЭМ
- Уровни переопределения
- Собирать много блоков без коллизий
- Автоматизация создания сущностей
Современные подходы к CSS
Современные подходы к CSS
Современные подходы к CSS
- Scoped-решения
- CSS-in-JS
- Shadow DOM
Scoped-решения
- Пишем CSS как обычно
- Переключение контекста
Scoped-решения
- Пишем CSS как обычно
- Переключение контекста
- Не для каждого стека
Scoped-решения
- Пишем CSS как обычно
- Переключение контекста
- Не для каждого стека
- Большой бандл CSS*
*Иногда можно сделать аглификацию, но это не точно
CSS-in-JS
- Пишем CSS не как обычно
- Ограничения инструмента, баги, etc.
CSS-in-JS
- Пишем CSS не как обычно
- Ограничения инструмента, баги, etc.
- Не для каждого стека
CSS-in-JS
- Пишем CSS не как обычно
- Ограничения инструмента, баги, etc.
- Не для каждого стека
- Растет размер бандла*
*При рантайм-решениях
Shadow DOM
- Сложности с a11y
- Сильно зависит от стека
Shadow DOM
- Сложности с a11y
- Сильно зависит от стека
- Подводные камни с SSR*
*Declarative shadow DOM поддерживается, но не идеально
Почему Atomic CSS
- Тратим меньше мыслетоплива: названия сущностей, структура каталогов
Почему Atomic CSS
- Тратим меньше мыслетоплива: названия сущностей, структура каталогов
- Меньше CSS на клиенте: стили перестают добавляться
Почему Atomic CSS
- Тратим меньше мыслетоплива: названия сущностей, структура каталогов
- Меньше CSS на клиенте: стили перестают добавляться
- Быстрее пишем стили: короткие классы, переключение файлов
Почему Atomic CSS
- Тратим меньше мыслетоплива: названия сущностей, структура каталогов
- Меньше CSS на клиенте: стили перестают добавляться
- Быстрее пишем стили: короткие классы, переключение файлов
- Stack agnostic: можно применять на любом стеке
Экономия мыслетоплива
Экономия мыслетоплива
forecast-briefly__day-link
Как назвать? 🤔
Как назвать? 🤔
fact__hour
Как назвать? 😉
D-ib Mnw9u P0;9 Txa
Как назвать? 🥲
Как назвать? 🥲
sc-a9fb3bce-4
Atomic CSS toolkit with Sass and ergonomics for creating styles of any complexity
Сокращения
- Лаконичный код
- Удобнее писать
- Чуть меньше вес кода
Сокращения
- Лаконичный код
- Удобнее писать
- Чуть меньше вес кода
- Есть порог входа
- Подойдут не всем
Алгоритм сокращений
- Позволяет избежать коллизий с новыми свойствами/значениями в CSS
Алгоритм сокращений
- Позволяет избежать коллизий с новыми свойствами/значениями в CSS
- Возможность выводить свойства "в голове", а не зазубривать их
Общий алгоритм сокращений кратко
- Находим свойства, которые начинаются с одинаковой буквы
Общий алгоритм сокращений кратко
- Находим свойства, которые начинаются с одинаковой буквы
- Составляем их рейтинг
Общий алгоритм сокращений кратко
- Находим свойства, которые начинаются с одинаковой буквы
- Составляем их рейтинг
- Выделяем группы
Общий алгоритм сокращений кратко
- Находим свойства, которые начинаются с одинаковой буквы
- Составляем их рейтинг
- Выделяем группы
- Составляем сокращения внутри групп
I. Алгоритм сокращения одной сущности
Название сокращаем до первой буквы свойства/значения
color
=> C
II. Алгоритм сокращения одной сущности
Если название из N слов, то берется первая буква из каждого слова
color-adjust
=> Ca
III. Алгоритм сокращения одной сущности
Если два названия имеют одну и ту же начальную букву, то в следующем названии при сортировке их по рейтингу добавляется буква
III. Алгоритм сокращения одной сущности
Если два названия имеют одну и ту же начальную букву, то в следующем названии при сортировке их по рейтингу добавляется буква
color
=> C
cursor
=> Cs
IV. Алгоритм сокращения одной сущности
Если название из N слов, то буква добавляется в соответствующем по порядку слове
IV. Алгоритм сокращения одной сущности
Если название из N слов, то буква добавляется в соответствующем по порядку слове
color
=> C
cursor
=> Cs
color-scheme
=> Csc
I. Порядок добавления буквы
Согласная следующего слога
cursor
=> Cs
I. Порядок добавления буквы
Согласная следующего слога
cursor
=> Cs
Если следующий слог начинается на гласную, то берется ближайшая предыдущая согласная от нее
II. Порядок добавления буквы
Следующая согласная
content
=> Сt
contain
=> Cn
III. Порядок добавления буквы
Следующая гласная (без перескока через согласную)
content
=> Сt
counter-increment
=> Coi
Utility components syntax
Синтаксис, в котором утилита разделяется на компоненты, каждый из которых, соответствует части CSS-правила
Utility components syntax
@:ah_O1_h
Utility components syntax
@:ah_O1_h
=>
@media (any-hover) {
}
Utility components syntax
@:ah_O1_h
=>
@media (any-hover) {
.\@\:ah_O1_h {
}
}
Utility components syntax
@:ah_O1_h
=>
@media (any-hover) {
.\@\:ah_O1_h {
opacity: 1
}
}
Utility components syntax
@:ah_O1_h
=>
@media (any-hover) {
.\@\:ah_O1_h:hover {
opacity: 1
}
}
- CSS at-rule: брейкпоинты, @supports, etc.
- CSS at-rule: брейкпоинты, @supports, etc.
- pre-states — часть селектора перед классом утилиты
- CSS at-rule: брейкпоинты, @supports, etc.
- pre-states — часть селектора перед классом утилиты
- Имя
- Значение
- CSS at-rule: брейкпоинты, @supports, etc.
- pre-states — часть селектора перед классом утилиты
- Имя
- Значение
- post-states — часть селектора после класса утилиты
То же самое, что inline-стили
Это для тех, кто плохо знает CSS
Atomic CSS — низкоуровневый
Чем лучше вы знаете CSS...
- Тем лучше будет ваш код
- Тем больше вы сможете сделать на чистом CSS
❌
❌
✅
❌
❌
❌
.Bgc-red_h\,fv:hover,
.Bgc-red_h\,fv:focus-visible {
background-color: red
}
@s:apcr4/3@:dm_Mxw40u
=>
@supports (aspect-ratio: 4/3) {
}
@s:apcr4/3@:dm_Mxw40u
=>
@supports (aspect-ratio: 4/3) {
@media (display-mode: fullscreen) {
}
}
@s:apcr4/3@:dm_Mxw40u
=>
@supports (aspect-ratio: 4/3) {
@media (display-mode: fullscreen) {
.\@s\:apcr4\/3\@\:dm_Mxw40u {
}
}
}
@s:apcr4/3@:dm_Mxw40u
=>
@supports (aspect-ratio: 4/3) {
@media (display-mode: fullscreen) {
.\@s\:apcr4\/3\@\:dm_Mxw40u {
max-width: 10rem
}
}
}
Проблематично реиспользовать стили, особенно вне компонентов
@apply
❌
Алиасы ✅
Алиасы ✅
Преимущества алиасов
- Существуют только в build-time — реиспользуются имеющиеся утилиты
Преимущества алиасов
- Существуют только в build-time — реиспользуются имеющиеся утилиты
- Меньше чем обычных классов — (почти) нет проблем с неймингом
Преимущества алиасов
- Существуют только в build-time — реиспользуются имеющиеся утилиты
- Меньше чем обычных классов — (почти) нет проблем с неймингом
- Можно редактировать in-place через замену подстрок
Слишком длинные className
Сравнение длины class
Сравнение длины class
Ml32_+:&
=>
.Ml32_\+\:\& {
margin-left: 32px;
}
Ml32_+:&
=>
.Ml32_\+\:\& + .Ml32_\+\:\& {
margin-left: 32px;
}
Best practices
- Custom properties
- Современные возможности CSS
Best practices
- Custom properties
- Современные возможности CSS
- Работа с контекстом
Custom properties
- Прокидывание стилей в компонент
- Цвета и темы
Прокидывание стилей
Bgc-$cardBgc?#ccc
=>
.Bgc-\$cardBgc\?\#ccc {
background-color:
}
Bgc-$cardBgc?#ccc
=>
.Bgc-\$cardBgc\?\#ccc {
background-color: var(--ml-cardBgc, #ccc);
}
Прокидывание стилей
lg_-CardImgWidth350
=>
@media (min-width: 992px) {
}
lg_-CardImgWidth350
=>
@media (min-width: 992px) {
.lg_-CardImgWidth350 {
}
}
lg_-CardImgWidth350
=>
@media (min-width: 992px) {
.lg_-CardImgWidth350 {
--ml-cardImgWidth: 350px;
}
}
Прокидывание стилей
Прокидывание сразу нескольких стилей
Цвета и темы ❌
Цвета и темы ❌
Цвета и темы ✅
Цвета и темы: переключение ✅
Современный CSS
- Container queries
- Псевдокласс
:has()
Container queries
Container queries
Container queries
Container queries
Container queries
@c:w>=520_Gtc-t2
=>
@container (min-width: 520px) {
.\@c\:w\>\=520_Gtc-t2 {
grid-template-columns: repeat(2, minmax(0, 1fr);
}
}
Псевдокласс :has()
Правило с :has()
будет применено, если хотя бы 1 из селекторов, переданных агрументом в :has()
, выберет хотя бы 1 элемент
Псевдокласс :has()
Псевдокласс :has()
Псевдокласс :has()
Псевдокласс :has()
Ol3;red;dh_has(ui)
*Будет доступно в @mlut/core
v2.2.0
Ol3;red;dh_has(ui)
=>
.Ol3\;red\;dh_has\(ui\):has(:user-invalid) {
outline: 3px red dashed;
}
*Будет доступно в @mlut/core
v2.2.0
Работа с контекстом
Контекст — специальная утилита, которая не применяет стили, но с которой удобно комбинировать другие утилиты в сложных селекторах.
Работа с контекстом
Контекст — специальная утилита, которая не применяет стили, но с которой удобно комбинировать другие утилиты в сложных селекторах.
Обозначается как ^
в синтаксисе утилит.
^:lc:>_D-f
=>
.-Ctx:last-child > .\^\:lc\>_D-f {
display: flex
}
Контекст
- Можно использовать с любыми утилитами
Контекст
- Можно использовать с любыми утилитами
- Можно как угодно комбинировать в states
Контекст
- Можно использовать с любыми утилитами
- Можно как угодно комбинировать в states
- Может быть именованным
^one:h_C-red
=>
.-Ctx-one:hover .\^one\:h_C-red {
color: red
}
Техники работы с контекстом
- Group state: hover/focus/etc.
Техники работы с контекстом
- Group state: hover/focus/etc.
- Стилизация элемента компонента
Техники работы с контекстом
- Group state: hover/focus/etc.
- Стилизация элемента компонента
- CSS-only-интерактивность
Group state
Group state
Group state
Group state
Стилизация элемента компонента
Стилизация элемента компонента
Стилизация элемента компонента
CSS-only-интерактивность
CSS-only-интерактивность
CSS-only-интерактивность
Большие проекты на Atomic CSS
Большие проекты на Atomic CSS
Большие проекты на Atomic CSS
Вряд ли подойдет для
- Rich UI — Google docs
- Огромный продукт/экосистема — Яндекс
Альтернативы
- Много динамики: CSS-in-JS
Альтернативы
- Много динамики: CSS-in-JS
- Rich UI: Canvas, WASM, $mol
Альтернативы
- Много динамики: CSS-in-JS
- Rich UI: Canvas, WASM, $mol
- Огромный продукт/экосистема: $mol
Инвестиционная история
Лучше день потерять, потом за 5 минут долететь
Выводы
- Не 1 фреймворк
- Не замена CSS
Выводы
- Не 1 фреймворк
- Не замена CSS
- Методология
Вопросы?
Оцените доклад: