<divelopers> – Telegram
<divelopers>
1.03K subscribers
21 photos
253 links
Рандомные мысли про HTML, CSS, доступность, пользовательские интерфейсы, производительность, браузеры и веб-стандарты.

Автор: @alexnozer
Download Telegram
Коротко о бигтехах

Холдинг ByteDance Ltd, не может уже который год исправить баг, когда при переходе по ссылке на видео в ТикТок открывается вообще левое видео. И это в проде. Уже пару лет. У бигтеха с 60к сотрудников и 35млрд оборотом. Не баг а фича?
👀3🤯1👨‍💻1
Вечные вопросы

<b> или <strong>? <em> или <i>?


Часто говорят, что нужно использовать <strong> и <em> соответственно, потому что они семантичные, а <b> с <i> - нет. Но на самом деле это не так. Вообще все элементы в HTML имеют семантику, которая определяется спецификацией и встроенной ролью (role). Семантика = смысл, то, что означает контент внутри элемента.

<b> - фрагмент текста, который просто выделен для каких-то целей. Это не обязательно полужирное начертание, можно выделить слово или фразу цветом, другим шрифтом, регистром, тенью, рамкой или ещё как-то - стили можно переопределить. Это могут быть ключевые слова в тексте, акцентное слово в заголовке, название чего-либо в тексте. В общем любой кусок текста, который нужно просто как-то выделить. Часто дизайнеры делают акценты на какие-то слова, стилистически выделяя их.

<strong> - фрагмент текста, который обозначает важность, срочность или серьезность. Так же выделяется полужирным, потому что так в типографике сложилось, но стили, опять же, можно переопределить. Например, это может быть разного рода предупреждающий текст: "Внимание!", "Вы уверены?", "Осторожно!", "Обращаем ваше внимание...". То есть это такой текст, на который пользователь должен обратить особое внимание и прочесть раньше, чем остальной текст.

<i> - фрагмент текста, который отличается от остального текста произношением, интонацией, настроением или как-то еще. То есть это такой текст, который в устной речи бы произносился иначе, чем обычно. Это термины, иностранные слова и фразы, идиомы, транслитерации, таксономии и т.д. Главный признак - в устной речи такой фрагмент текста бы произносился иначе, чем всё остальное.

<em> - это фрагмент текста, на который делается логическое ударение, или иначе это ещё называют эмфазой, от чего и название элемента (em - emphasis). Выделяется курсивом, потому что так принято в типографике. Это слова или фразы, которые произносятся с ударением, экспрессией, восклицанием для повышения эмоциональной выразительности. Часто в таких предложениях присутствует восклицательный знак или же фраза является цитатой (для которых есть свой элемент).

Зачем это? Во-первых это - соглашения типографики. Во-вторых в устной речи часть особого смысла в слова и фразы мы выкладываем за счёт голоса, интонации, скорости и т.д. В разметке у нас только текст, эти элементы задумывались, чтобы помечать то, что в речи мы делаем голосом. Эта информация предназначена в первую очередь для речевых синтезаторов. Если говорить о скринридерах, то пока все плохо: элементы никак дополнительно не озвучиваются почти нигде. Значит всё? Выкинули эти теги и больше не используем? Нет.

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

Поэтому размечайте тексты правильно.
🔥7👍6
Новый элемент <selectmenu>

OpenUI разрабатывает новый элемент - <selectmenu>. Он уже более года доступен в Chrome за флагом. Этот элемент должен решить давнюю проблему - невозможность кастомизации нативного <select>.

<selectmenu>
<button
slot="button"
behavior="button"
>
<span
behavior="selected-value"
></span>
</button>
<option>Option 1</option>
<option>Option 2</option>
</selectmenu>


В чем проблема? Есть нативный <select>, который из коробки доступен, работает с формами и т.д. Но поповер с опциями никак не может быть стилизован, потому что находится на уровне ОС и недоступен для CSS. Да и внешняя часть имеет ограничения стилизации. Это приводит к тому, что вместо нативного <select> используются библиотеки, которые можно подогнать под дизайн и сделать консистентно во всех браузерах. Но это лишний js на клиенте, а во многих решениях доступность вообще не проработана. <selectmenu> - это решение. Это встроенный веб-компонент, который использует Shadow DOM для инкапсуляции разметки и логики внутри себя, slots для проброса произвольной разметки в определённые места и CSS Shadow Parts для стилизации некоторых внутренних частей.

У <selectmenu> есть определённая анатомия. Компонент состоит из кнопки, внутри которой элемент с текстом выбранной опции и иконка-треугольник. За кнопкой располагается поповер, куда попадают опции и который рисуется при открытии селекта. По умолчанию <selectmenu> работает как <select>, а именно служит контейнером для элементов <option>, которые могут быть опционально обернуты в <optgroup>.

<selectmenu>
<option>Опция 1</option>
<option>Опция 2</option>
<optgroup label="Группа">
<option>Опция 3</option>
<option>Опция 4</option>
</optgroup>
</selectmenu>

Благодаря механизму CSS Shadow Parts мы получаем возможность пробиться внутрь Shadow DOM и стилизовать некоторые части <selectmenu> при помощи специального селектора ::part(name), где name - название части: button, selected-value и listbox. Также доступны псевдоклассы :open и :closed для стилизации открытого и закрытого состояний <selectmenu> соответственно. Полезно для стилизации маркера.

selectmenu::part(button) {
/* стили кнопки */
}

selectmenu::part(selected-value) {
/* стили выбранного значения */
}

selectmenu::part(listbox) {
/* стили выпадающего списка */
}

selectmenu:open {
/* стили при открытом выпадающем списке */
}

selectmenu:closed {
/* стили при закрытом выпадающем списке */
}

Можно передавать свою разметку, используя слоты. Доступные слоты: button, selected-value, marker и listbox. Браузер заменит стандартную разметку на ту, что была передана в слот. Атрибут behavior сообщает браузеру поведение, которое нужно добавить элементу. Внутри <option> также можно разместить дополнительную разметку, что позволяет добавить иконки, картинки, многострочный текст и все это стилизовать как нужно.

<selectmenu>
<div slot="button">
<noscript><!-- ... --></noscript>
<button
behavior="button"
></button>
</div>
<option>
<noscript><!-- ... --></noscript>
<span>Опция 3</span>
</option>
<option>
<noscript><!-- ... --></noscript>
<span>Опция 4</span>
</option>
</selectmenu>

В слот listbox можно передать разметку, которая будет использоваться как контейнер для опций. В таком случае нужно указать атрибуты behavior="listbox" и popover="auto" (да, тут используется Popover API). Можно сделать селектор цветов как в MS Word.

Когда эту фичу раскатят - не ясно. Поэтому к релизу синтаксис может немного измениться, но слоты и части останутся в таком виде, поскольку это часть стандарта веб-компонентов. Больше примеров и подробное описание можно найти в предложении OpenUI.

UPD: компонент переименовали в <selectlist>, чтобы не было путаницы с элементом <menu> и паттерном меню.

UPD2: компонент слегка переделали, заменив селектор ::part() на псевдоклассы, а также добавив новые вспомогательные элементы <listbox> и <selectedoption>. Работа активно идёт.
4👍4🔥4
Возвращаясь к Popover API

Если сделать <div popover>, то он так и останется generic-элементом. Роль нужно добавлять вручную в зависимости от типа поповера (menu, dialog, tooltip, listbox, ...). Вот хорошая статья о том, когда и какая роль лучше подойдёт для поповера.
👍3🔥3
Про пользу семантической разметки

Представитель Google, Адам Аргайл, в ходе мероприятия Google I/O заявил, что семантическая разметка важна для нового AI Bard и привёл пример, в котором попросил AI собрать сводку последних постов со своего сайта. Адам отметил, что семантическая разметка помогает AI лучше понимать контент на сайтах. Теперь помимо ассистивных технологий, SEO, режимов чтения, специальных браузеров (браузер в Apple Watch, например) это ещё и для AI полезно. И это логично. Разметка - это текст. Языковые модели работают с текстом. Обученный AI знает про семантику, знает про спецификацию, поэтому может использовать эти знания для более качественного извлечения информации с сайтов.

https://youtu.be/JiVQBqAkkac?t=745s
👍8🔥4🤬1
Продолжаю рассказывать про новые API

На очереди Anchor Positioning API. Это нативная возможность позиционировать один элемент относительно другого без костылей и js. API частично реализован и доступен в Chrome Canary за флагом экспериментальных фич.

<button id="hint">
Подробнее
</button>
<div class="tooltip" anchor="info">
Подробная информация
</div>

<style>
.tooltip {
top: anchor(--info bottom);
left: anchor(--info center);
}
</style>


Например, нужно сделать тултип, который привязан к какому-то элементу. Для этого нужна обертка с position: relative, внутри которой элемент с position: absolute, его нужно спозиционировать, и ещё js для переворачивания и прочих edge-кейсов. Либо использовать библиотеки Popper или Floating UI. Anchor Position API предлагает ряд новых возможностей в CSS и HTML, которые позволят решить эту задачу. Кроме того, при помощи этого API можно будет позиционировать выпадающие меню, списки опций селекта, автокомплит, всплывающие подсказки и другие UI-элементы.

Прежде всего, надо привязать один элемент к другому. Предлагается 2 способа. Первый - указать атрибут anchor, в котором будет id элемента, к которому нужно привязаться. Второй - указать CSS-свойство anchor-name со значением типа dash-indent (как custom properties).

<button id="hint" class="anchor">
Подробнее
</button>
<div class="tooltip" anchor="info">
Подробная информация
</div>

<!-- или -->
<style>
.anchor {
anchor-name: --hint;
}
</style>


После создания якоря можно использовать CSS-функцию anchor(), с 3я аргументами:
- имя якоря
- сторона (top, right, bottom, left, center) или процент
- фоллбэк
Имя якоря можно не указывать, если он создан при помощи anchor в HTML или указано свойство anchor-default. Что делает функция anchor()? Она возвращает координату указанной стороны элемента-якоря, которую можно использовать как значение в свойствах top, right, bottom, left и inset, тем самым позиционируя один элемент относительно другого. Функцию также можно использовать внутри calc().

.anchor {
anchor-name: --hint;
}

.tooltip {
top: anchor(--hint bottom);
left: anchor(--hint center);
}


Другая полезная функция - anchor-size(). Она принимает имя якоря и width/height. Таким образом, можно получить размеры элемента-якоря и использовать их для вычисления положения или размера привязанного к якорю элемента.

.anchor {
anchor-name: --hint;
}

.tooltip {
width: calc(4 * anchor-size(--info width));
}


Ещё планируется функционал автоматического позиционирования в зависимости от наличия свободного места. Для этого в свойствах top, right, bottom, left и в функции anchor() можно будет указывать значение auto. Переворачивание можно будет реализовать при помощи свойства position-fallback и специального @-правила с одноимённым названием. В try-блоках указываются варианты, которые браузер будет пробовать, чтобы подобрать наиболее подходящее позиционирование.

.anchor {
anchor-name: --hint;
}

.tooltip {
anchor-default: --hint;
position-fallback: --flip;
}

@position-fallback {
@try {
bottom: anchor(top);
left: anchor(center);
}

@try {
top: anchor(bottom);
left: anchor(center);
}
}


Пока это экспериментальная возможность, синтаксис может измениться. Также есть баги и не все фичи на данный момент можно потрогать даже за флагами. Однако работа над API идёт, потому что это очень востребованная фича, которая тесно связана с Popover API и <selectlist>.
🔥74😍1
Интерфейс Chrome DevTools

Интересный факт, о котором, возможно, все знают, но тем не менее: интерфейс Chrome DevTools сделан на HTML, CSS и JS. На скриншоте слева DevTools, открытые на ютубе, а справа DevTools, открытые для DevTools слева. Можно увидеть разметку кастомного свойства панели Styles.

То есть все кнопки, вкладки, поля ввода, селекторы цветов, инспектор DOM и CSS, все панели и т.д. - сделаны на нативных веб-технологиях. И все это можно изучить, открыв DevTools для DevTools (хоть и не просто так). Для меня это стало небольшим открытием. В принципе бОльшая часть UI хрома сделана на нативных технологиях: стартовый экран, настройки, магазин расширений. Получается, что программа, которая отображает веб сама сделана на вебе. Что, на мой взгляд, довольно интересно. Также интересно взглянуть на некоторые технические решения, применяемые в DevTools, потому что это, по сути, веб-приложение с довольно нетривиальным функционалом.
👍7🥰1
Лучшее объяснение Web 3.0, которое я видел

https://briefs.video/videos/what-is-web-3.0/
👍3🤔2😁1
Альт картинки:
Лучшие сокращения в CSS

1) min()
width: 100px;
min-width: 50px;
может быть записано как
width: min(100px, 50px);
2) clamp()
font-size: 16px;
max-font-size: 20px;
min-font-size: 12px;
может быть записано как
font-size: clamp(12px, 1rem, 20px);
3) repeat()
background-image: url('image.png');
background-repeat: repeat-x;
может быть записано как
background-image: repeat-x(url('image.png'));
4) calc()
width: 100%;
padding: 20px;
может быть записано как
width: calc(100% - 40px);
"Лучшие" сокращения в CSS ⬆️

Как же я обожаю подобную инфографику от разного рода индусов. "Лучшие сокращения CSS" - смотрите и запоминайте! 🤦‍♂️

В первом случае результаты не эквивалентны. В случае с width + min-width итоговая ширина будет 100px, а с min() итоговая ширина будет 50px, потому что min() возвращает наименьшее из двух значений.

Второй пример вообще шикарен: автор придумал сокращение через clamp() для несуществующих свойств min-font-size и max-font-size! Видимо, хотел показать fluid font size, только вот размер шрифта в примере всегда будет 1rem, для правильной работы нужны динамические единицы.

Третий пример должен был нам продемонстрировать применение функции repeat(). Только вот в примере функция repeat-x() в свойстве background-image, что не является валидный кодом. repeat-x() не существует, а функция repeat() предназначена для гридов, а не фона.

Ну и последний пример показывает нам, как вместо ширины элемента с padding использовать calc(), что не является эквивалентной заменой от слова совсем. Как минимум padding задаёт внутренние отступы, влияющие на размер элемента, в том числе и на его высоту.

Такой вот "полезный контент", как пишут некоторые люди с опытом разработки в комментариях к этой картинке. М-да уж...
🙈9👏1
Да они там кнопки красят!

Тем временем: сижу на созвоне, где 9 человек (дизайнеры, фронты, a11y-специалисты, аналитики) проектируют компонент выбора диапазона дат с календарём, инпутами, выбором месяца и года, пресетами, валидацией и тд. Лучше бы кнопки красил 😅

Мне нравится работать с UX, проектировать компоненты и делать их доступными. Но иногда случается подрыв мозга, когда много сценариев, сложного взаимодействия, а это все нужно сделать удобным и доступным для всех.
8🤯3💅1
SPA на контентных сайтах

Не понимаю, зачем делать обычные сайты, документацию, блоги и другие content-first проекты на фреймворках в виде SPA с JS-роутингом? Чтобы работало без перезагрузки с анимациями? Так ведь нет, на средних и слабых устройствах фризы, а анимаций на большинстве проектов нет. Что вообще плохого в перезагрузке? Если грамотно использовать современные возможности нативного HTML и CSS, не подключать npm-пакеты на клиент по любому чиху, не подключать десяток трекеров и оптимизировать ресурсы, то перезагрузка будет почти мгновенной.

А красивые переходы скоро можно будет делать при помощи View Transition API (уже можно в Chrome). На контентные сайты люди приходят за контентом, в документацию за примерами кода и описанием API. Для этого не нужны фреймворки, JS-роутинг, рантайм вебпака и сотни кб JS-а.

Тред навеян несколькими твитами из ленты. В одном показано, что в документации Vue router и Pinia в Firefox не работал сайдбар с ссылками. Другой про миграцию сайта на Angular. Кроме того, я участвую в разработке нескольких сайтов на Angular и не вижу там необходимости в нем.
👍5💯2🤓1
Нативная изоляция стилей в CSS

@scope (.card) {
.noscript { /* ... */ }
.image { /* ... */ }
.link { /* ... */ }
}


В CSS всегда была проблема с изоляцией стилей, особенно на больших проектах. Её решают по-разному: префиксы, конвенции по именованию классов (БЭМ), CSS-modules, scoped styles (Vue) и т.д. Все это - попытки решить проблему. На самом деле решение есть - Shadow DOM, который обеспечивает изоляцию разметки и стилей в отдельном поддереве DOM. Причём Shadow DOM это не эксклюзивная возможность веб-компонентов. Её можно использовать и для обычных элементов. Однако в таком виде не прижилось. Нужен более простой механизм для создания областей видимости, который был бы доступен в CSS. Этим механизмом в скором времени станет директива @scope. Поддержка этой директивы будет добавлена в Chrome 117. Safari и Firefox идею поддержали и обсуждают детали реализации.

Директива @scope позволяет задать селектор элемента, который будет создавать область видимости. Внутри @scope можно указывать стили, которые будут применяться только в этой области видимости. В примере стили применятся только к тем img, которые находятся внутри .media-block:

<style>
@scope (.media-block) {
img {
border-radius: 50%;
}
}
</style>
<div class="media-block">
<!-- стили применяются -->
<img src="..." alt="...">
</div>

<!-- стили не применяются -->
<img src="..." alt="...">


Если @scope указан в HTML и при этом не указан селектор, то ближайший родитель элемента <style> будет использоваться как корень для создания области видимости:

<div> <!-- корень области видимости -->
<style>
@scope {
p {
color: red;
}
}
</style>
<p>Красный</p>
</div>

<p>Не красный</p>


Опционально можно указать второй селектор после ключевого слова to. Это задаёт границу области видимости. Таким образом, можно задавать область видимости не на все дочерние узлы, а только на конкретную часть поддерева:

<style>
@scope (.media-block) to (.content) {
img {
border-radius: 50%;
}
}
</style>
<div class="media-block">
<!-- стили применяются -->
<img src="..." alt="...">
<div class="content">
<!-- стили не применяются -->
<img src="..." alt="...">
</div>
</div>


Специальный псевдоселектор :scope позволяет обращаться к корню области видимости и стилизовать сам корень или его дочерние элементы в зависимости от контекста:

<style>
@scope (.media-block) {
:scope { /* .media-block */ }
:scope img { /* .media-block img */ }
aside:scope { /* aside.media-block */ }
}
</style>
<div class="media-block">
<img src="..." alt="...">
</div>


Эта штука вполне может вытеснить БЭМ и различные библиотеки, когда появится полноценная поддержка. Ждём. А пока подробнее про @scope с примерами и нюансами можно почитать в черновике спецификации.

PS. Поддержка @scope была добавлена в Chrome 117 за флагом, а в 118 включили полную поддержку для всех. Также поддержку добавили в Safari TP 185
🔥9
Никто не знает HTML

Как мы дошли до того, что фундаментальную технологию веба никто не знает и не валидирует? Ана Тюдор изучила демки челленджа на кодпене и поделилась результатами.

В докладе Андрея Смирнова с YLF2023 была серия слайдов с результатами опроса "какие темы интересны разработчикам на конференции Frontendconf". В целом HTML и CSS практически никому не интересен.

На сайте Йенса Мейерта говорится, что в 2022 году у 0 из 100 популярных сайтов валидный HTML. В 2021 году этот показатель был 2 из 100. Среднее количество ошибок - 125.63. И это сайты многомилионных компаний.

Я сейчас работаю на финтех проекте, где занимаюсь внедрением доступности. На проекте много опытных фронтов. Однако из раза в раз приходится делать правки в HTML: недопустимая вложенность, отсутствие ориентиров, неправильная семантика, переизбыток элементов и т.д.

Как так получилось? Ну да, ведь интересно говорить про типы, микрофронтенды, фреймворки, сборщики, архитектуры, всякие модные аббревиатуры. Какое дело до этого вашего HTML...
😭7💯32😁2🔥1
Главное ИИ затащить в проект

Под любым видом, в любое место, главное наличие ИИ. MDN, но вы то куда? Мировой технический справочник по вебу. Должна же быть какая-то социальная ответственность?

https://github.com/mdn/yari/issues/9208
👍1👎1🙈1
Про поля ввода

Читал комментарии под одной из статей на хабре. И я чертовски согласен с мнением пользователей nronnie и Fines_Unes. Каких только извращений в простых текстбоксах не встретишь на просторах интернета...

Например, селект с флагом страны и телефонным кодом. Сервису действительно нужен выбор среди 213 кодов? Много ли жителей с кодом Конго покупают билеты в кинотеатры РБ? Да сервис, скорее всего, даже СМС не обработает и не вышлет на номер с таким кодом. Зачем? А все эти маски ввода и префиксы с кодом, которые нельзя удалить? Хочешь зарегистрироваться? Нет, сначала купи симку с номером на +7. А ещё это ломает автодополнение браузера, вставку номера из телефонной книги, вставку из буфера обмена. Зачем ломать стандартные функции?

Бывает, ставишь курсор в поле, ещё не начал вводить, а все уже красное, ошибка! Да я ещё не ввёл ничего, какая ошибка? А ошибка "Неверный ввод". Почему неверный? Сделайте задержку валидации, выведите информативные сообщения об ошибках, приведите пример ожидаемых данных. А ещё календари для ввода даты рождения, которые начинаются с текущего дня текущего года и не имеют возможности ввода с клавиатуры. Сиди и отлистывай пару десятков лет. Посмотрите метрику и поставьте начальную дату исходя из среднего возраста основной ЦА.

На мой взгляд лучшее решение:
- обычное текстовое поле с нужным типом и/или клавиатурой
- отдельный лейбл к нему (сверху или сбоку)
- placeholder с примером данных
- небольшой раскрывающийся блок или тултип с пояснением по формату данных и особенностям ввода. Простое поле. Без масок, селектов с кодами, автокорректировок, валидации по странным правилам и тд. Пользователь, которому важно, чтобы ему пришло СМС с кодом, прислали счёт на почту или перезвонили для уточнения деталей сам заинтересован в том, чтобы ввести корректные данные.

Советую доклад Виталия Фридмана про формы, а также другие его доклады про UX. И в целом подписаться на него в соц. сетях, если вы занимаетесь пользовательскими интерфейсами.
💯8
Видео на ютубе. Автор сталкивается с проблемой: при клике по кнопке происходит отправка формы вместо нужного действия. Решение: добавить preventDefault() на клик по кнопке или на отправку формы. А можно просто добавить type="button" в HTML и никакие preventDefault() и js не понадобятся.

Твит с кодом: кнопка с плавной прокруткой к элементу. Решение: <button> с onClick, в обработчике вызов scrollIntoView с ref элемента. А можно добавить элементу id, сделать <a href="#element">, а в CSS добавить scroll-behavior: smooth. И не нужны клики, ref и вызовы прокрутки.

Задача: нужно хранить кусок разметки в HTML для дальнейшего использования. Решение: <noscript> с разметкой, чтение строки и парсинг при помощи DOMParser. А можно положить разметку в <template>, из которого можно сразу достать фрагмент DOM без парсинга.

И т.д. Многие задачи могут быть легко решены при помощи простых элементов, атрибутов и CSS-свойств вместо скриптов.
🔥42👍2
WordPress moment

Небольшой сайт на Elementor, несколько страниц, ничего сложного, минимум плагинов, минимум контента, нет сложных интерактивных элементов, немного анимаций. На главной странице больше 200 запросов за ресурсами! Это на странице из 5 экранов. Из них более сотни - стили и скрипты хрен пойми чего, что не используется на странице. Ну и задачка - оптимизировать метрики PageSpeed. Ага. Лучшая оптимизация метрик PageSpeed для сайта на WordPress это удалить WordPress и сделать нормально... За эту тему для WordPress клиент заплатил около 80 баксов, а в рекламе заявляется про high performance. Вижу я, какой там хай перформанс...
😢81👍1
CSS vs SCSS

Мне кажется, что миксины - это та фича, из-за которой многие все ещё предпочитают использовать препроцессоры вместо нативного CSS. Все остальные фичи, можно сказать, уже есть в платформе.

Переменные

С нами уже очень давно. Причём они гораздо мощнее переменных SCSS, потому что работают в рантайме, наследуются, проникают в Shadow DOM и позволяют делать разные динамические штуки. Но и как хранилище для переиспользуемых токенов тоже хорошо работают.

Вложенность

Вложенность (nesting) уже поддерживается во всех актуальных браузерах. Да, там есть нюансы, вложенность работает не совсем так, как в препроцессорах. В этом есть как плюсы, так и минусы. Лично мне вложенность не особо нужна, но она есть в платформе.

Цветовые функции

Функции color() и color-mix() в сочетании с переменными и новыми цветовыми пространствами позволяют конвертировать цвета, смешивать их, работать с прозрачностью, яркостью, насыщенностью и т.д. Таким образом в CSS можно реализовывать динамические палитры.

Математика

Представлена в CSS функцией calc(), а также min(), max(), clamp(). Не так давно список пополнили тригонометрические функции и на подходе функции round(), mod(), rem(), abs(), sign() и куча других (уже доступны в Safari 15.4 и Firefox 118). Это позволяет реализовать любую математику.

Условия и циклы

Пока что в CSS этого нет, но ходят обсуждения и есть черновики с предложениями. Я не знаю, насколько это вообще нужно. Видел в функциях SCSS, но крайне редко. Тут лучше ждать внедрения Houdini API и возможности создавать свои функции для CSS.

Миксины

Этого тоже пока нет и вот пошли обсуждения. Хотя вопрос добавления нативных миксинов поднимался году в 2016. На мой взгляд это то, чего не хватает в CSS, чтобы перейти с SCSS. Ждём.
👍41🤓1