CSS Wrapped 2024
Команда Chrome DevRel запустила CSS Wrapped 2024. Это лендинг с обзором новых возможностей CSS, выпущенных в Chrome (и не только) в этом году. Можно считать это итогами года для CSS.
В CSS появилось 17 новых возможностей:
-
- Анимация
- Exclusive Accordion
-
- Anchor Positioning
-
- View transitions
- Scroll-driven animations
- Scroll snap events
- Наследование свойств в
-
- @property
- Popover API
- @starting-style
-
-
-
Глядя на этот список и отслеживая новинки для публикации в этот канал, я впечатлён развитием CSS в этом году. Не помню такого количества фич раньше. Осталось дождаться хорошей поддержки всего этого. Тут я тоже настроен позитивно, о чём я уже упоминал. А пока предлагаю перейти на сайт CSS Wrapped 2024 и ознакомиться с демками всех новых возможностей. Особенно через последнюю версию Chrome, в которой все они поддерживается.
На самом сайте при этом во всю используются новые возможности CSS, поэтому можно поизучать исходники.
Команда Chrome DevRel запустила CSS Wrapped 2024. Это лендинг с обзором новых возможностей CSS, выпущенных в Chrome (и не только) в этом году. Можно считать это итогами года для CSS.
В CSS появилось 17 новых возможностей:
-
field-sizing- Анимация
height: auto, calc-size() и interpolate-size- Exclusive Accordion
-
::details-content- Anchor Positioning
-
scrollbar-color и scrollbar-width- View transitions
- Scroll-driven animations
- Scroll snap events
- Наследование свойств в
::backdrop-
light-dark()- @property
- Popover API
- @starting-style
-
ruby-align-
paint-order-
CSSNestedDeclarationsГлядя на этот список и отслеживая новинки для публикации в этот канал, я впечатлён развитием CSS в этом году. Не помню такого количества фич раньше. Осталось дождаться хорошей поддержки всего этого. Тут я тоже настроен позитивно, о чём я уже упоминал. А пока предлагаю перейти на сайт CSS Wrapped 2024 и ознакомиться с демками всех новых возможностей. Особенно через последнюю версию Chrome, в которой все они поддерживается.
На самом сайте при этом во всю используются новые возможности CSS, поэтому можно поизучать исходники.
CSS Wrapped 2024
Join the Chrome DevRel team and a skateboarding Chrome Dino on a journey through the latest CSS launched for Chrome and the web platform in 2024.
🔥5🌚1
Размер DOM и доступность
Я уже писал о размере DOM в контексте производительности. Но чрезмерный размер DOM может негативно повлиять и на доступность.
В операционных системах есть дерево доступности. Оно хранит в себе объекты пользовательского интерфейса с их названиями, ролями, свойствами и состояниями. Вспомогательные технологии используют это дерево для получения информации и предоставления её пользователю в том или ином виде. Например, программа чтения с экрана озвучивает элементы и даёт с ними взаимодействовать при помощи горячих клавиш.
У веб-страниц тоже есть дерево доступности, которое можно посмотреть в DevTools. Дерево доступности веб-страницы формируется на основе DOM. Браузер передаёт операционной системе данные о семантике и свойствах элементов, которые определены по умолчанию или заданы разработчиком через ARIA. Поддерево доступности сайта встраивается в общее дерево операционной системы.
При большом размере DOM браузеру нужно передавать операционной системе больше данных. Особенно если DOM постоянно обновляется, что обычное явление в мире фронтенд-фреймворков. Передача и обработка данных происходит не мгновенно.
В итоге программа чтения с экрана, например, может озвучивать информацию с большой задержкой или озвучивать уже неактуальную информацию. Иногда вовсе может прекратить работу и вылететь из-за того, что не хватило ресурсов на обработку большого объёма данных. Об этом рассказал Эрик Бейли, специалист по доступности из GitHub, на конференции performance. now(), которая прошла недавно. Кому интересно, есть запись доклада.
Я уже писал о размере DOM в контексте производительности. Но чрезмерный размер DOM может негативно повлиять и на доступность.
В операционных системах есть дерево доступности. Оно хранит в себе объекты пользовательского интерфейса с их названиями, ролями, свойствами и состояниями. Вспомогательные технологии используют это дерево для получения информации и предоставления её пользователю в том или ином виде. Например, программа чтения с экрана озвучивает элементы и даёт с ними взаимодействовать при помощи горячих клавиш.
У веб-страниц тоже есть дерево доступности, которое можно посмотреть в DevTools. Дерево доступности веб-страницы формируется на основе DOM. Браузер передаёт операционной системе данные о семантике и свойствах элементов, которые определены по умолчанию или заданы разработчиком через ARIA. Поддерево доступности сайта встраивается в общее дерево операционной системы.
При большом размере DOM браузеру нужно передавать операционной системе больше данных. Особенно если DOM постоянно обновляется, что обычное явление в мире фронтенд-фреймворков. Передача и обработка данных происходит не мгновенно.
В итоге программа чтения с экрана, например, может озвучивать информацию с большой задержкой или озвучивать уже неактуальную информацию. Иногда вовсе может прекратить работу и вылететь из-за того, что не хватило ресурсов на обработку большого объёма данных. Об этом рассказал Эрик Бейли, специалист по доступности из GitHub, на конференции performance. now(), которая прошла недавно. Кому интересно, есть запись доклада.
YouTube
Accessible is Performant | Eric Bailey | performance.now() 2024
Accessibility is a holistic practice, essential to some but useful to all. It is a practice that touches on many aspects of good web design and development, especially performance. This talk will highlight opportunities and techniques to improve your website…
👍7🔥3🌚2
7 функций, которые нужны каждому сайту
Попалось тут мне одно короткое видео, в котором автор перечисляет 7 функций, которые нужны каждому сайту:
- Cookie-баннер, запрашивающий согласие на трекинг для рекламодателей, обязательно с неочевидными вариантами выбора.
- Запрос местоположения через Geolocation API, чтобы точно знать, где находится пользователь.
- Запрос на отправку Push-уведомлений, чтобы пользователь точно был в курсе всех “важных” новостей сайта.
- Всплывающее модальное окно на весь экран сразу после загрузки страницы, требующее ввести email для подписки на бесполезную рассылку.
- Автоматически воспроизводимое видео со скрытыми элементами управления плеером, чтобы остановить его мог только опытный пользователь.
- Сложная CAPTCHA, ведь пользователям нравится несколько раз подряд выбирать светофоры, автобусы и пешеходные переходы.
- Отключение кнопки “назад”, чтобы возникли трудности при попытке вернуться на предыдущую страницу, обязательно с модальным окном, что пользователь не прав.
Шутки шутками, но мы живём в мире, где такие “функции” не редкость. Я делился докладом Виталия Фридмана Privacy UX, где он показывает такие паттерны на реальных сайтах. Пожалуйста, не делайте так.
Попалось тут мне одно короткое видео, в котором автор перечисляет 7 функций, которые нужны каждому сайту:
- Cookie-баннер, запрашивающий согласие на трекинг для рекламодателей, обязательно с неочевидными вариантами выбора.
- Запрос местоположения через Geolocation API, чтобы точно знать, где находится пользователь.
- Запрос на отправку Push-уведомлений, чтобы пользователь точно был в курсе всех “важных” новостей сайта.
- Всплывающее модальное окно на весь экран сразу после загрузки страницы, требующее ввести email для подписки на бесполезную рассылку.
- Автоматически воспроизводимое видео со скрытыми элементами управления плеером, чтобы остановить его мог только опытный пользователь.
- Сложная CAPTCHA, ведь пользователям нравится несколько раз подряд выбирать светофоры, автобусы и пешеходные переходы.
- Отключение кнопки “назад”, чтобы возникли трудности при попытке вернуться на предыдущую страницу, обязательно с модальным окном, что пользователь не прав.
Шутки шутками, но мы живём в мире, где такие “функции” не редкость. Я делился докладом Виталия Фридмана Privacy UX, где он показывает такие паттерны на реальных сайтах. Пожалуйста, не делайте так.
YouTube
7 Функций Сайта, Которые Бесят Всех! 😡 #программирование #вебразработка #сайты
Хотите знать, какие функции делают ваш сайт настоящим кошмаром для пользователей? В этом видео мы расскажем о 7 популярных фишках, которые могут раздражать п...
👍9🌚3
Link Area Delegation
Есть распространённый паттерн карточки товара, статьи и так далее. Обычно это картинка, заголовок, ссылка и дополнительные элементы. Верстают их по-разному, но в целом выработан паттерн, который выглядит примерно так:
Хочется, чтобы при клике в любое место карточки открывалась детальная страница. Пользователи привыкли к этому. В примере попасть на детальную страницу можно только кликнув по заголовку. Фикс часто сводится к оборачиванию всего ссылкой. Спецификация HTML допускает размещение внутри ссылки того, что можно размещать в её родителе.
Но внутри интерактивных элементов нельзя размещать другие интерактивные элементы. В примере это “Add to cart”. Вложенные интерактивные элементы приводят к плохому пользовательскому опыту и проблемам с доступностью. Кроме того, весь текстовый контент ссылки становится её доступным именем, что крайне избыточно. Иногда от ссылки отказываются, меняя на
Хейдон Пикеринг предложил компромиссное решение. Если кратко, то ссылка остаётся внутри заголовка. К ней добавляется псевдо-элемент
Паттерн рабочий, я им пользуюсь, но есть неудобства. Нужно добавлять
Группа OpenUI поделилась идеями по улучшению и выпустила предложение Link Area Delegation. Суть сводится к тому, чтобы предоставить декларативный механизм делегирования кликов с других элементов на ссылку. Предложено несколько вариантов, которые ещё будут прорабатываться.
Вариант 1: атрибуты
Клик по элементу с атрибутом
Вариант 2: новый элемент
Вместо атрибута предлагается элемент
Вариант 3: CSS вместо HTML
Первая ссылка внутри карточки расширяет (
Вариант 4: использование Invokers
Invokers — это декларативный механизм добавления действий к элементам. Я делал пост с обзором ранней версии этого предложения. Частично Invokers уже реализованы в Chrome Canary, Firefox Nightly и Safari TP. В ближайшем будущем стоит ожидать полноценного внедрения в стабильные браузеры.
Я думаю, что у четвёртого варианта больше всего шансов на реализацию. Нужно будет расширить API, которое уже внедряется в браузеры. Но идеи ещё будут обсуждаться и возможны изменения. В целом предложение звучит круто и полезно.
Есть распространённый паттерн карточки товара, статьи и так далее. Обычно это картинка, заголовок, ссылка и дополнительные элементы. Верстают их по-разному, но в целом выработан паттерн, который выглядит примерно так:
<article>
<img src="..." alt="">
<h3>
<a href="/catalog/76345865">Title</a>
</h3>
<p>99$</p>
<p>Denoscription</p>
<a href="/cart/add/76345865">Add to cart</a>
</article>
Хочется, чтобы при клике в любое место карточки открывалась детальная страница. Пользователи привыкли к этому. В примере попасть на детальную страницу можно только кликнув по заголовку. Фикс часто сводится к оборачиванию всего ссылкой. Спецификация HTML допускает размещение внутри ссылки того, что можно размещать в её родителе.
Но внутри интерактивных элементов нельзя размещать другие интерактивные элементы. В примере это “Add to cart”. Вложенные интерактивные элементы приводят к плохому пользовательскому опыту и проблемам с доступностью. Кроме того, весь текстовый контент ссылки становится её доступным именем, что крайне избыточно. Иногда от ссылки отказываются, меняя на
<div> с обработчиками кликов. Тоже плохо.Хейдон Пикеринг предложил компромиссное решение. Если кратко, то ссылка остаётся внутри заголовка. К ней добавляется псевдо-элемент
::before и растягивается на всю карточку. Другие интерактивные элементы поднимаются на слой выше, чем ::before. Клик по псевдо-элементу делегируется ссылке и всё работает.Паттерн рабочий, я им пользуюсь, но есть неудобства. Нужно добавлять
::before, работать с position: absolute и z-index, не забыть поднять другие интерактивные элементы выше, правильно настроить рамку фокуса и т.д.Группа OpenUI поделилась идеями по улучшению и выпустила предложение Link Area Delegation. Суть сводится к тому, чтобы предоставить декларативный механизм делегирования кликов с других элементов на ссылку. Предложено несколько вариантов, которые ещё будут прорабатываться.
Вариант 1: атрибуты
<article linkarea>
...
<h3>
<a href="/catalog/76345865" defaultlink>Title</a>
</h3>
...
</article>
<article linkarea="link_id">
...
<h3>
<a href="/catalog/76345865" id="link_id">Title</a>
</h3>
...
<a href="/cart/add/76345865">Add to cart</a>
</article>
Клик по элементу с атрибутом
linkarea делегируется ссылке с атрибутом defaultlink или ссылке, id которой указан в атрибуте linkarea.Вариант 2: новый элемент
<article>
<linkarea>
...
<h3>
<a href="/catalog/76345865" defaultlink>Title</a>
</h3>
...
<a href="/cart/add/76345865">Add to cart</a>
</linkarea>
</article>
Вместо атрибута предлагается элемент
<linkarea>. Клики по нему делегируются ссылке с атрибутом defaultlink. Это менее удобно, не всегда можно что-то обернуть, например, строку таблицы, у которой жёсткие правила вложенности.Вариант 3: CSS вместо HTML
<article class="card">
...
<h3>
<a href="/catalog/76345865">Title</a>
</h3>
...
<a href="/cart/add/76345865">Add to cart</a>
</article>
<style>
.card {
pointer-area: contain;
}
.card h3 a {
pointer-area: expand;
}
</style>
Первая ссылка внутри карточки расширяет (
pointer-area: expand) свою область клика на элемент, который содержит (pointer-area: contain) расширяемый элемент.Вариант 4: использование Invokers
<article commandfor="link_id" commands="click contextmenu">
...
<h3>
<a href="/catalog/76345865" id="link_id">Title</a>
</h3>
...
<a href="/cart/add/76345865">Add to cart</a>
</article>
Invokers — это декларативный механизм добавления действий к элементам. Я делал пост с обзором ранней версии этого предложения. Частично Invokers уже реализованы в Chrome Canary, Firefox Nightly и Safari TP. В ближайшем будущем стоит ожидать полноценного внедрения в стабильные браузеры.
Я думаю, что у четвёртого варианта больше всего шансов на реализацию. Нужно будет расширить API, которое уже внедряется в браузеры. Но идеи ещё будут обсуждаться и возможны изменения. В целом предложение звучит круто и полезно.
❤16🔥4🌚3👍1
Cписок описаний
На прошлой неделе мне попался твит, в котором автор задавался вопросом, какие HTML-элементы с точки зрения семантики лучше подойдут для разметки такого контента:
Среди вариантов
Если в таблице первая ячейка каждой строки —
Для разметки пар ключ-значение хорошо подходит элемент
В
Как и
На практике
На прошлой неделе мне попался твит, в котором автор задавался вопросом, какие HTML-элементы с точки зрения семантики лучше подойдут для разметки такого контента:
Name: Anton
Email: xx@yy.com
Age: 80
Среди вариантов
<table> и <dl>. Можно использовать <table> и сделать горизонтальную таблицу с заголовочными ячейками в первом столбце:<table>
<tr>
<th scope="row">Name:</th>
<td>Anton</td>
</tr>
<tr>
<th scope="row">Email:</th>
<td>xx@yy.com</td>
</tr>
<tr>
<th scope="row">Age:</th>
<td>80</td>
</tr>
</table>
Если в таблице первая ячейка каждой строки —
<th>, то она действует как заголовок этой строки. Можно явно указать область действия заголовочной ячейки атрибутом scope="row", как в примере. На мой взгляд <table> избыточен для такого контента. Таблицы нужны для объединения однородного набора данных, когда есть группа характеристик, для которых нужны общие заголовки и структурная связь.Для разметки пар ключ-значение хорошо подходит элемент
<dl>. Я решил написать об этом, потому что редко вижу элемент <dl> в разметке и вокруг него есть некоторые мифы. Разметка контента из примера при помощи <dl> будет выглядеть так:<dl>
<div>
<dt>Name:</dt>
<dd>Anton</dd>
</div>
<div>
<dt>Email:</dt>
<dd>xx@yy.com</dd>
</div>
<div>
<dt>Age:</dt>
<dd>80</dd>
</div>
</dl>
<dl> — это список описаний или ассоциативный список. Многие ошибочно считают <dl> списком определений, поэтому применимость ограничивается только терминами и их расшифровками. Такое встречается не часто: на сайтах вроде Википедии, словарях или справочниках. Дело в том, что в HTML4 элемент назывался definition list и действительно был задуман как список определений. В HTML5 семантика <dl> изменилась и с тех пор это denoscription list. Его можно использовать не только для терминов, а для любых пар ключ-значение.В
<dt> описывается термин или ключ, а в <dd> соответствующие данные. Ключей и данных может быть несколько. Одному <dt> может соответствовать несколько <dd> и наоборот. У <dl> особая контентная модель, которая допускает использование <div> на первом уровне вложенности, если внутри него находятся только <dt> и <dd>. При этом <div> можно не использовать и вкладывать <dt> и <dd> напрямую в <dl>. В обычных списках так нельзя.Как и
<ul>, <ol> и <menu>, элемент <dl> — это список. Скринридеры озвучат количество элементов в списке и предоставят дополнительные возможности взаимодействия. В текущей версии ARIA in HTML указано, что у <dl>, <dt> и <dd> нет встроенных ролей. При этом Chrome добавляет свою роль DenoscriptionList для <dl> и роли term и definition для <dt> и <dd> соответственно. В Firefox всё аналогично, кроме роли <dl>, там она указана как definitionlist. Подробнее о взаимодействии скринридеров с элементом можно почитать в статье Адриана Розелли.На практике
<dl> подойдёт для разметки как списка терминов и определений, так и любого набора ключей со значениями. Например, в интернет-магазинах есть блок c характеристиками товара, где сначала идёт название характеристики, а затем значение. Данные в аккаунте пользователя тоже подойдут. Есть реализация паттерна Disclosure FAQ через <dl>. Обычный FAQ без “раскрывашек” тоже можно разметить с помощью <dl>. В целом если что-то выглядит как название свойства и значение, и таких пар несколько, скорее всего, это <dl>.www.w3.org
ARIA in HTML
This specification defines the authoring rules (author conformance requirements) for the use
of Accessible Rich Internet Applications (WAI-ARIA) 1.2 and Digital Publishing WAI-ARIA Module 1.0 attributes on [HTML] elements.
This specification's…
of Accessible Rich Internet Applications (WAI-ARIA) 1.2 and Digital Publishing WAI-ARIA Module 1.0 attributes on [HTML] elements.
This specification's…
👍15🔥2🌚1
You don’t know HTML: слеш в конце элементов
Регулярно в HTML-разметке можно встретить
На данный момент в HTML есть 13 пустых элементов:
-
-
-
-
-
-
-
-
-
-
-
-
-
Слеш в конце пустых HTML-элементов не нужен! Он не несёт никакой полезной нагрузки и игнорируется браузерами. Сделано это ради обратной совместимости. Слеш у пустых элементов пришёл из мира XML, где он строго обязателен. Хотя HTML — это XML-подобный язык и наследует оттуда многие идеи, он не совместим с XML, потому что имеет ряд отличий и использует другой парсер. Одно из таких отличий — не нужен слеш в конце пустых элементов.
Существует строгая, XML-совместимая версия HTML — XHTML. Она поддерживается браузерами, но уже практически нигде не используется. Там слеш нужен, так как этого требуют правила XML, которым следует XHTML. Если вы не пишите на XHTML, а вы на нём не пишите, то не используйте слеши, сэкономите пару байт, а то и килобайт размера документа.
Слеш для пустых элементов требуется в популярном синтаксисе JSX, который используется в React и некоторых других фреймворках. Тут важно понимать, что JSX — это не HTML в JavaScript, а специальный синтаксис (синтаксический сахар), мимикрирующий под HTML. JSX превращается в вызовы функций во время транспиляции исходного кода. В этом синтаксисе действуют свои правила, которые ближе к XML.
Другим источником слешей является Prettier — популярный инструмент форматирования кода. Он автоматически расставляет слеши для пустых элементов при форматировании HTML и HTML-подобных языков. Разработчикам Prettier долго об этом говорили, но они отказывались что-то менять. В итоге такое поведение отключается отдельным плагином.
Ещё один забавный момент со слешами случился во фреймворке Svelte. Его автор, Рич Харрис, был удивлён, что в HTML нельзя закрывать элементы как в XML (
#ydkhtml
Регулярно в HTML-разметке можно встретить
/ в конце пустых элементов, то есть тех, у которых нет закрывающего тега. Наверняка вы видели подобный код:<link rel="stylesheet" href="styles.css" />
<img src="image.jpg" alt="" />
<br />
На данный момент в HTML есть 13 пустых элементов:
-
<base>-
<link>-
<meta>-
<hr>-
<br>-
<wbr>-
<source>-
<img>-
<embed>-
<track>-
<area>-
<col>-
<input>Слеш в конце пустых HTML-элементов не нужен! Он не несёт никакой полезной нагрузки и игнорируется браузерами. Сделано это ради обратной совместимости. Слеш у пустых элементов пришёл из мира XML, где он строго обязателен. Хотя HTML — это XML-подобный язык и наследует оттуда многие идеи, он не совместим с XML, потому что имеет ряд отличий и использует другой парсер. Одно из таких отличий — не нужен слеш в конце пустых элементов.
Существует строгая, XML-совместимая версия HTML — XHTML. Она поддерживается браузерами, но уже практически нигде не используется. Там слеш нужен, так как этого требуют правила XML, которым следует XHTML. Если вы не пишите на XHTML, а вы на нём не пишите, то не используйте слеши, сэкономите пару байт, а то и килобайт размера документа.
Слеш для пустых элементов требуется в популярном синтаксисе JSX, который используется в React и некоторых других фреймворках. Тут важно понимать, что JSX — это не HTML в JavaScript, а специальный синтаксис (синтаксический сахар), мимикрирующий под HTML. JSX превращается в вызовы функций во время транспиляции исходного кода. В этом синтаксисе действуют свои правила, которые ближе к XML.
Другим источником слешей является Prettier — популярный инструмент форматирования кода. Он автоматически расставляет слеши для пустых элементов при форматировании HTML и HTML-подобных языков. Разработчикам Prettier долго об этом говорили, но они отказывались что-то менять. В итоге такое поведение отключается отдельным плагином.
Ещё один забавный момент со слешами случился во фреймворке Svelte. Его автор, Рич Харрис, был удивлён, что в HTML нельзя закрывать элементы как в XML (
<div></div> — <div />), а парсер Svelte такое обрабатывал. Это приводило к некоторым багам из-за того, как браузер обрабатывает ошибки синтаксиса HTML. В итоге было создано issue с вопросом о том, как дальше быть. В Svelte 5 поведение приведено к стандарту HTML.#ydkhtml
❤14👍5👎2😁2
Web Almanac 2024: Markup
Обзор данных из раздела Markup свежего Web Almanac 2024. Подсвечу моменты, которые показались мне интересными.
Общий размер сжатого HTML в этом году вырос и достигает 178кб в 90м перцентиле. Медиана составляет 33кб против 30кб в 2023 году и 31кб в 2022. При этом 11% страниц не используют сжатие. На остальных страницах выросло использование Brotli — 37%, который догоняет и постепенно вытесняет Gzip. Новый алгоритм сжатия Zstandard пока что особо не используется.
На 13% страниц не указан язык в атрибуте
На 86% страниц есть как минимум один HTML-комментарий. При этом 26% страниц используют условные комментарии, которые работают только в старых версиях IE. Это много, учитывая смерть IE11, не говоря уже о его более ранних версиях. По всей видимости, это старые сайты, которые больше не поддерживаются. Комментарии лучше удалять из HTML вне режима разработки.
«Диватоз» всё ещё существует,
Растёт количество пользовательских элементов (веб-компонентов): 7.9% в этом году, 5.4% в 2023 году и 3.6% в 2022 году. Рост частично вызван внедрением пользовательских элементов популярными сервисами: Wix, Revolution Slider в WordPress и Shopify. На страницах с пользовательскими элементами в целом больше JavaScript, потому что он нужен для их инициализации.
Самым распространённый атрибут —
Обзор данных из раздела Markup свежего Web Almanac 2024. Подсвечу моменты, которые показались мне интересными.
Общий размер сжатого HTML в этом году вырос и достигает 178кб в 90м перцентиле. Медиана составляет 33кб против 30кб в 2023 году и 31кб в 2022. При этом 11% страниц не используют сжатие. На остальных страницах выросло использование Brotli — 37%, который догоняет и постепенно вытесняет Gzip. Новый алгоритм сжатия Zstandard пока что особо не используется.
На 13% страниц не указан язык в атрибуте
lang элемента <html>. Самый популярный язык — английский. Но с этим есть интересный момент: часто у страниц указан язык, который не соответствует реальному языку контента. Многие разработчики копируют сниппеты кода, используют стартовые шаблоны, emmet (! + Tab) или генераторы проектов, где по умолчанию стоит lang="en".На 86% страниц есть как минимум один HTML-комментарий. При этом 26% страниц используют условные комментарии, которые работают только в старых версиях IE. Это много, учитывая смерть IE11, не говоря уже о его более ранних версиях. По всей видимости, это старые сайты, которые больше не поддерживаются. Комментарии лучше удалять из HTML вне режима разработки.
«Диватоз» всё ещё существует,
<div> — самый используемый HTML-элемент, 29% всех элементов страниц. Топ-4 популярных элементов остаётся неизменным как минимум с 2021 года, а топ-8 совпадает с прошлым годом. Поменялись местами 9 и 10 места — <path> стал использоваться чаще, чем <meta>, что связано с ростом использования встроенного SVG. В 90м перцентиле на страницах используется 44 разных типов элементов. Общее количество используемых на странице элементов снизилось. Но в 90м перцентиле их всё ещё 1716, что больше рекомендуемого минимума.Растёт количество пользовательских элементов (веб-компонентов): 7.9% в этом году, 5.4% в 2023 году и 3.6% в 2022 году. Рост частично вызван внедрением пользовательских элементов популярными сервисами: Wix, Revolution Slider в WordPress и Shopify. На страницах с пользовательскими элементами в целом больше JavaScript, потому что он нужен для их инициализации.
Самым распространённый атрибут —
class, 33% от всех атрибутов. На 90% всех страниц есть хотя-бы один data-атрибут, самый распространённый — data-id. 14% страниц использует мета-тег viewport со значением, которое блокирует зум, а на 5% страниц этот мета-тег вообще не указан. Самый популярный формат favicon — png, использование выросло с 35% в 2021 году до 42% в 2024. ico постепенно уходит, с 33% в 2021 году до 27% в 2024. 18% страниц не используют favicon вообще.almanac.httparchive.org
Markup | 2024 | The Web Almanac by HTTP Archive
Markup chapter of the 2024 Web Almanac covering document data (doctypes, compression, languages, HTML conformance, document size), the use of HTML elements and attributes, data attributes and social media.
👍3🔥2❤1
Вишлист HTML
Под конец года devrel-ы и авторы контента делятся своими вишлистами. Это список функций, которые авторам хотелось бы видеть в веб-платформе. В 454 выпуске Веб-стандартов обсуждали вишлисты CSS. Прозвучала мысль, что CSS это круто, но вот бы вишлист HTML. Это натолкнуло меня на мысль написать такой.
focusgroup
При разработке доступных компонентов нужно следовать правилам работы с клавиатурой. Предложение focusgroup упростит задачу, перекладывая часть работы на браузер. Достаточно указать атрибут
Invokers
Часто на небольших проектах нужно немного JS вида “при нажатии кнопки открыть диалог/добавить класс/изменить атрибут”. Хотелось бы делать это декларативно и без JS. Как с отправкой формы через
Custom Attributes
Custom Elements позволяет расширять стандартные HTML-элементы через атрибут
Declarative Custom Elements
Справедливое замечание в адрес веб-компонентов в том, что для регистрации требуется JS, даже если нет никакого поведения. Firefox догнал другие браузеры и внедрил Declarative Shadow DOM, теперь можно добавлять Shadow Root без JS. Хотелось бы дальнейшего развития идей Declarative Custom Elements, которые активно обсуждают в сообществе веб-компонентов.
Стилизуемые элементы форм
В браузере есть стандартные элементы форм, но они плохо стилизуются. Ситуация улучшается:
UI-примитивы
Стандартных интерактивных HTML-элементов не достаточно для разработки сайтов и приложений. Существует разрыв между ролями из ARIA и HTML, в котором нет многих аналогов. Первое правило ARIA — не использовать ARIA. Чтобы ему следовать, хотелось бы видеть в браузерах больше базовых UI-примитивов и эквивалентов ARIA-виджетов.
Карусель
В моей работе практически в каждом проекте встречается карусель. Когда-то я использовал Owl Carousel и Slick, затем перешёл на Swiper и его веб-компонент, сейчас по возможности использую Shoelace Carousel. Но каждый раз это сторонняя библиотека, которую нужно устанавливать и настраивать. Мне нравится идея перенести карусель в CSS, расширив уже существующую и хорошо поддерживаемую спецификацию Scroll Snap.
DOM Parts и шаблоны
Одна из задач, которую решают фреймворки — декларативные шаблоны и обновление DOM при изменении данных. Веб-компоненты часто критикуют за отсутствие таких возможностей. Предложение DOM Parts предлагает решение для выделения обновляемых частей DOM. В сочетании с Signals и предложением Template Instantiation получится единый механизм шаблонов. Хотелось бы увидеть реализацию этих идей.
HTML Modules
В ранних спецификациях веб-компонентов был HTML Import, который в итоге был удалён из браузеров по соображениям безопасности. Ему на смену должны прийти HTML Modules, которые базируются на синтаксисе ES Modules и Import Attributes. Это позволит импортировать фрагменты HTML и создавать однофайловые веб-компонентов.
Больше внимания HTML
На самом деле хотелось бы, чтобы разработчики уделяли HTML больше внимания. Это фундаментальная технология веба, на которой всё строится. Используйте семантические элементы, валидируйте разметку, углубитесь в гайды ARIA, следите за чистотой и размером HTML.
Под конец года devrel-ы и авторы контента делятся своими вишлистами. Это список функций, которые авторам хотелось бы видеть в веб-платформе. В 454 выпуске Веб-стандартов обсуждали вишлисты CSS. Прозвучала мысль, что CSS это круто, но вот бы вишлист HTML. Это натолкнуло меня на мысль написать такой.
focusgroup
При разработке доступных компонентов нужно следовать правилам работы с клавиатурой. Предложение focusgroup упростит задачу, перекладывая часть работы на браузер. Достаточно указать атрибут
focusgroup с нужными значениями для реализации roving tabindex, навигации стрелками и горячих клавиш.Invokers
Часто на небольших проектах нужно немного JS вида “при нажатии кнопки открыть диалог/добавить класс/изменить атрибут”. Хотелось бы делать это декларативно и без JS. Как с отправкой формы через
<button type="submit"> внутри <form> или как Popover API. Инициатива Invokers предлагает декларативную привязку базовых действий к кнопкам с возможностью расширения через JS.Custom Attributes
Custom Elements позволяет расширять стандартные HTML-элементы через атрибут
is и наследование. Это давно реализовано в Chromium и Firefox, но в Safari отказались от идеи по ряду причин. Альтернативное предложение — Custom Attributes. Идея в том, чтобы создавать пользовательские атрибуты и добавлять их к элементам, тем самым расширяя их. Вариантов применения много. Также это помогло бы инструментам, которые полагаются на атрибуты, например HTMX, Alpine или Vue.Declarative Custom Elements
Справедливое замечание в адрес веб-компонентов в том, что для регистрации требуется JS, даже если нет никакого поведения. Firefox догнал другие браузеры и внедрил Declarative Shadow DOM, теперь можно добавлять Shadow Root без JS. Хотелось бы дальнейшего развития идей Declarative Custom Elements, которые активно обсуждают в сообществе веб-компонентов.
Стилизуемые элементы форм
В браузере есть стандартные элементы форм, но они плохо стилизуются. Ситуация улучшается:
appearance: none для сброса внешнего вида чекбоксов и радио, а на горизонте кастомизируемый <select>. Предложенный вариант выглядит интересно и хотелось бы, чтобы подобное решение распространилось за пределы <select>, на другие стандартные элементы, например <input type="date">.UI-примитивы
Стандартных интерактивных HTML-элементов не достаточно для разработки сайтов и приложений. Существует разрыв между ролями из ARIA и HTML, в котором нет многих аналогов. Первое правило ARIA — не использовать ARIA. Чтобы ему следовать, хотелось бы видеть в браузерах больше базовых UI-примитивов и эквивалентов ARIA-виджетов.
Карусель
В моей работе практически в каждом проекте встречается карусель. Когда-то я использовал Owl Carousel и Slick, затем перешёл на Swiper и его веб-компонент, сейчас по возможности использую Shoelace Carousel. Но каждый раз это сторонняя библиотека, которую нужно устанавливать и настраивать. Мне нравится идея перенести карусель в CSS, расширив уже существующую и хорошо поддерживаемую спецификацию Scroll Snap.
DOM Parts и шаблоны
Одна из задач, которую решают фреймворки — декларативные шаблоны и обновление DOM при изменении данных. Веб-компоненты часто критикуют за отсутствие таких возможностей. Предложение DOM Parts предлагает решение для выделения обновляемых частей DOM. В сочетании с Signals и предложением Template Instantiation получится единый механизм шаблонов. Хотелось бы увидеть реализацию этих идей.
HTML Modules
В ранних спецификациях веб-компонентов был HTML Import, который в итоге был удалён из браузеров по соображениям безопасности. Ему на смену должны прийти HTML Modules, которые базируются на синтаксисе ES Modules и Import Attributes. Это позволит импортировать фрагменты HTML и создавать однофайловые веб-компонентов.
Больше внимания HTML
На самом деле хотелось бы, чтобы разработчики уделяли HTML больше внимания. Это фундаментальная технология веба, на которой всё строится. Используйте семантические элементы, валидируйте разметку, углубитесь в гайды ARIA, следите за чистотой и размером HTML.
❤4
Реализацию каких функций из вишлиста вы бы хотели?
Anonymous Poll
30%
focusgroup
25%
Invokers
4%
Custom Attributes
13%
Declarative Custom Elements
49%
Стилизуемые элементы форм
36%
UI-примитивы
38%
Карусель
21%
DOM Parts и шаблоны
23%
HTML Modules
11%
Никаких / смотреть ответы
Новогодние каникулы
Канал <divelopers> вместе с его автором уходит на новогодние каникулы и вернётся 9 января с новыми силами и постами. Спасибо что читаете!
Если хочется чего-то почитать на каникулах, предлагаю всю подборку постов You don’t know HTML (особенно если подписались недавно и пропустили). В ней я, вдохновившись серией книг Кайла Симпсона “You don’t know JS”, пишу про разные возможности HTML и Web API:
- You don't know HTML: download
- You don't know HTML: <datalist>
- You don't know HTML: input.showPicker()
- You don't know HTML: Media Capture
- You don't know HTML: inert
- You don't know HTML: <search>
- You don't know HTML: кнопки как ссылки
- You don't know HTML: Exclusive Accordion
- You don't know HTML: noscript и блок данных
- You don't know HTML: autocomplete
- You don’t know HTML: слеш в конце элементов
Если хочется послушать, предлагаю 443й выпуск подкаста “Веб-стандарты”, где я в качестве приглашённого гостя час обсуждаю с ведущими веб-компоненты. А если хочется посмотреть, есть запись доклада “What we do in the Shadow (DOM)” с MinskCSS, где я рассказываю как работает изоляция в Shadow DOM.
Всех с наступающими праздниками! Увидимся в Новом Году!
Канал <divelopers> вместе с его автором уходит на новогодние каникулы и вернётся 9 января с новыми силами и постами. Спасибо что читаете!
Если хочется чего-то почитать на каникулах, предлагаю всю подборку постов You don’t know HTML (особенно если подписались недавно и пропустили). В ней я, вдохновившись серией книг Кайла Симпсона “You don’t know JS”, пишу про разные возможности HTML и Web API:
- You don't know HTML: download
- You don't know HTML: <datalist>
- You don't know HTML: input.showPicker()
- You don't know HTML: Media Capture
- You don't know HTML: inert
- You don't know HTML: <search>
- You don't know HTML: кнопки как ссылки
- You don't know HTML: Exclusive Accordion
- You don't know HTML: noscript и блок данных
- You don't know HTML: autocomplete
- You don’t know HTML: слеш в конце элементов
Если хочется послушать, предлагаю 443й выпуск подкаста “Веб-стандарты”, где я в качестве приглашённого гостя час обсуждаю с ведущими веб-компоненты. А если хочется посмотреть, есть запись доклада “What we do in the Shadow (DOM)” с MinskCSS, где я рассказываю как работает изоляция в Shadow DOM.
Всех с наступающими праздниками! Увидимся в Новом Году!
Telegram
<divelopers>
You don't know HTML
В рамках этого канала я запускаю новую рубрику под названием You don't know HTML. Название вдохновлено серией книг You don't know JS Кайла Симпсона, рекомендую к прочтению.
Посты будут выходить с хештегом #ydkhtml и будут посвящены разным…
В рамках этого канала я запускаю новую рубрику под названием You don't know HTML. Название вдохновлено серией книг You don't know JS Кайла Симпсона, рекомендую к прочтению.
Посты будут выходить с хештегом #ydkhtml и будут посвящены разным…
🔥9🎉8❤4👍3🥰1
Возвращение к работе
Новогодние каникулы подошли к концу, а значит пора возвращаться к работе и каналу.
В планах на этот год:
- увеличить частоту и стабильность выхода контента
- запустить несколько новых рубрик
- писать больше о доступности, производительности и веб-компонентах
- попробовать новые форматы постов
А ещё 5 января у канала был день рождения 🥳 Формально, канал создан 16 декабря 2023 года, но запуск произошёл 5 января 2024 года. За год собралось 434 подписчика и опубликовано 173 поста. Скромно, но у меня нет цели гнаться за цифрами. Канал создан для того, чтобы делиться полезным контентом по HTML, CSS, доступности, производительности, UX и веб-стандартам. Это те темы, которые мне интересны, в которых есть экспертиза и желание делиться.
Спасибо всем, что читаете! Буду рад, если поделитесь ссылкой на канал с коллегами и порепостите посты. Если у вас есть идеи, предложения или вопросы, смело пишите мне в личку.
Новогодние каникулы подошли к концу, а значит пора возвращаться к работе и каналу.
В планах на этот год:
- увеличить частоту и стабильность выхода контента
- запустить несколько новых рубрик
- писать больше о доступности, производительности и веб-компонентах
- попробовать новые форматы постов
А ещё 5 января у канала был день рождения 🥳 Формально, канал создан 16 декабря 2023 года, но запуск произошёл 5 января 2024 года. За год собралось 434 подписчика и опубликовано 173 поста. Скромно, но у меня нет цели гнаться за цифрами. Канал создан для того, чтобы делиться полезным контентом по HTML, CSS, доступности, производительности, UX и веб-стандартам. Это те темы, которые мне интересны, в которых есть экспертиза и желание делиться.
Спасибо всем, что читаете! Буду рад, если поделитесь ссылкой на канал с коллегами и порепостите посты. Если у вас есть идеи, предложения или вопросы, смело пишите мне в личку.
👍16🔥7🎉4🌚2
Встроенный CSS-in-JS
В экосистеме JS-фреймворков распространён подход CSS-in-JS, когда стили пишутся в JS-файлах. В современных браузерах есть встроенный механизм для работы со стилями в JS — Constructable Stylesheets. С его помощью можно создавать таблицы стилей и применять их глобально к документу или Shadow Root.
Таблица стилей создаётся через конструктор
Из объекта
А ещё в JS появились Import Attributes. Можно импортировать стили как ES-модуль, указав тип
Написав небольшую обвязку вокруг этих API, можно получить что-то вроде CSS Modules или Styled Components.
В экосистеме JS-фреймворков распространён подход CSS-in-JS, когда стили пишутся в JS-файлах. В современных браузерах есть встроенный механизм для работы со стилями в JS — Constructable Stylesheets. С его помощью можно создавать таблицы стилей и применять их глобально к документу или Shadow Root.
Таблица стилей создаётся через конструктор
CSSStyleSheet. Методы replace и replaceSync формируют стилевые правила из строки. В массиве adoptedStyleSheets у document или Shadow Root хранятся текущие таблицы стилей, туда же можно добавить созданную через API:const stylesheet = new CSSStyleSheet();
stylesheet.replaceSync(`
.element {
color: #4e4e4e;
text-decoration: underline;
}
`);
/* применение к документу */
document.adoptedStyleSheets.push(stylesheet);
const div = document.createElement('div');
div.attachShadow({ mode: 'open' });
/* применение к Shadow Root */
div.shadowRoot.adoptedStyleSheets.push(stylesheet);
Из объекта
CSSStyleSheet можно получить информацию о стилях: список правил и медиа-запросов, родительскую таблицу стилей (при использовании @import) и т.д. Интерес представляет список правил, с которым можно работать:const firstRule = stylesheet.cssRules[0];
console.log(firstRule.cssText);
// '.element { color: #4e4e4e; text-decoration: underline; }'
console.log(firstRule.selectorText);
// '.element'
console.log(firstRule.style.color);
// '#4e4e4e'
console.log(firstRule.style.textDecoration);
// 'underline'
console.log(firstRule.style.cssText);
// 'color: red; text-decoration: underline;'
А ещё в JS появились Import Attributes. Можно импортировать стили как ES-модуль, указав тип
css через оператор with. При импорте таким образом создаётся экземпляр CSSStyleSheet. Поэтому можно писать стили во внешних файлах и импортировать их в JS:/* styles.css */
.element {
color: #4e4e4e;
text-decoration: underline;
}
import syncStylesheet from '/styles.css' with { type: 'css' };
console.log(syncStylesheet.cssRules[0].cssText);
// '.element { color: #4e4e4e; text-decoration: underline; }'
/* или через динамический импорт */
const dynamicStylesheet = await import('/styles.css', { with: { type: 'css'} });Написав небольшую обвязку вокруг этих API, можно получить что-то вроде CSS Modules или Styled Components.
❤12👍5🔥3
You don't know HTML: fetchpriority
Чтобы нарисовать страницу, браузеру нужно получить все необходимые для этого ресурсы. Первым делом браузер получает HTML и начинает его разбирать. В процессе браузер строит DOM и ищет все ресурсы, которые используются на странице: CSS, JS, изображения, видео, SVG и так далее. Параллельно с парсером, используется ещё один механизм — сканер предварительной загрузки. Его задача — искать ресурсы не дожидаясь, пока парсер до них дойдёт.
В конечном итоге все найденные ресурсы передаются в сетевой процесс, где распределяются по приоритету и начинают загружаться. При работе над производительностью сайта часто смотрят на сетевой водопад — график загрузки ресурсов. Некоторые оптимизации заключаются в том, чтобы изменить положение ресурсов в водопаде, сдвинуть их выше, ниже, или вовсе убрать.
Атрибут
В HTML уже есть некоторые возможности для управления приоритетом, например:
-
-
-
-
- Загрузить важную картинку, которая влияет на LCP, с высоким приоритетом
- Понизить приоритет картинок в карусели, которые отображаются только при переключении слайда
- Предварительно загружать некритические ресурсы с низким приоритетом
- Понизить приоритет классического блокирующего скрипта в конце
- Повысить приоритет асинхронного скрипта
Приоритет также можно указывать в функции
Подробнее о Fetch Priority API можно прочитать в статье на web.dev.
#ydkhtml #html #performance
Чтобы нарисовать страницу, браузеру нужно получить все необходимые для этого ресурсы. Первым делом браузер получает HTML и начинает его разбирать. В процессе браузер строит DOM и ищет все ресурсы, которые используются на странице: CSS, JS, изображения, видео, SVG и так далее. Параллельно с парсером, используется ещё один механизм — сканер предварительной загрузки. Его задача — искать ресурсы не дожидаясь, пока парсер до них дойдёт.
В конечном итоге все найденные ресурсы передаются в сетевой процесс, где распределяются по приоритету и начинают загружаться. При работе над производительностью сайта часто смотрят на сетевой водопад — график загрузки ресурсов. Некоторые оптимизации заключаются в том, чтобы изменить положение ресурсов в водопаде, сдвинуть их выше, ниже, или вовсе убрать.
Атрибут
fetchpriority можно указывать у элементов, которые загружают ресурсы: <link>, <noscript>, <img> и <iframe>. В качестве значений принимаются high, low и auto. Атрибут предназначен для изменения стандартного приоритета загрузки ресурса. Значение high делает ресурс более приоритетным, а low — менее приоритетным. Значение auto возвращает поведение по умолчанию, предоставляя браузеру выбор приоритета.В HTML уже есть некоторые возможности для управления приоритетом, например:
-
loading у <img> и <iframe>-
preload у <video>-
defer, async и type="module" у <noscript>-
<link rel="preload">fetchpriority — ещё одна такая возможность. Какие есть варианты использования:- Загрузить важную картинку, которая влияет на LCP, с высоким приоритетом
- Понизить приоритет картинок в карусели, которые отображаются только при переключении слайда
- Предварительно загружать некритические ресурсы с низким приоритетом
- Понизить приоритет классического блокирующего скрипта в конце
<body>- Повысить приоритет асинхронного скрипта
Приоритет также можно указывать в функции
fetch():const response = await fetch('/resource', { priority: 'low' });Подробнее о Fetch Priority API можно прочитать в статье на web.dev.
#ydkhtml #html #performance
web.dev
Optimize resource loading with the Fetch Priority API | Articles | web.dev
The Fetch Priority API indicates the relative priority of resources to the browser. It can enable optimal loading and improve Core Web Vitals.
🔥36👍2🌚1
Доступность контента в социальных сетях
Доступность важно учитывать не только при разработке сайтов, но и при публикации контента в социальных сетях. Делюсь хорошим сайтом accessible-social.com, на котором собраны гайды по созданию доступного контента и использованию функций доступности в социальных сетях.
Также предлагаю запись вебинара про доступный контент от Глафиры Жур, где можно посмотреть, как использовать те или иные функции доступности социальных сетей.
#a11y
Доступность важно учитывать не только при разработке сайтов, но и при публикации контента в социальных сетях. Делюсь хорошим сайтом accessible-social.com, на котором собраны гайды по созданию доступного контента и использованию функций доступности в социальных сетях.
Также предлагаю запись вебинара про доступный контент от Глафиры Жур, где можно посмотреть, как использовать те или иные функции доступности социальных сетей.
#a11y
Accessible-Social
Accessible Social
Accessible Social is a free resource and education hub that helps marketers and content creators learn about accessibility and how it relates to social media.
👍7❤5🔥5🥰2🌚1
focusgroup
В ARIA существуют некоторые виджеты, для которых нужно реализовывать управление фокусом и навигацию с клавиатуры. При перемещении по интерактивным элементам при помощи
Есть две стратегии реализации:
- виртуальный фокус и атрибут
- техника “Roving Tabindex” и манипуляция атрибутом
Обе техники требуют нетривиальных реализаций на JS с прослушкой множества событий клавиатуры и фокуса. Подводных камней хватает.
Команда Edge в рамках группы OpenUI предложила добавить в браузеры атрибут
При перемещении по странице через клавиатуру, фокус попадёт на первую кнопка в тулбаре, не смотря на
Перемещение между кнопками в тулбаре осуществляется стрелками. “Вверх” и “вправо” — следующая кнопка, “вниз” и “влево” — предыдущая. Кнопка “Home” переносит фокус на первую кнопку, а “End” — на последнюю. Предусмотрен зацикленный переход между первой и последней кнопками при указании
При выходе фокуса из тулбара, браузер сохранит последнюю сфокусированную кнопку и вновь сфокусирует её при возврате фокуса в тулбар. Это отключается, если указать
Значения
Пример тулбара с горизонтальной навигацией, переносом между крайними элементами и без сохранения последнего сфокусированного элемента.
Значение
Значение
Для всех значений атрибута
Есть экспериментальный пользовательский полифилл с поддержкой базовых функций (без табличной навигации и CSS) и демо-страница, на которой его можно опробовать. Также есть оригинальный полифилл от команды Edge, но он разработан для более раннего варианта синтаксиса, который уже изменился.
Статус функции пока не понятен. По результатам State of HTML. в
#html #css #a11y
Дисклеймер: это обзор раннего предложения новой функции. Синтаксис может измениться в будущем или от функции могут вовсе отказаться.
В ARIA существуют некоторые виджеты, для которых нужно реализовывать управление фокусом и навигацию с клавиатуры. При перемещении по интерактивным элементам при помощи
Tab и Shift+Tab, весь виджет должен быть одним шагом в последовательности табуляции. Навигация по внутренним элементам виджета должна осуществляться через клавиши со стрелками и специальные клавиши Home, End, Page Up, Page Down и другие.Есть две стратегии реализации:
- виртуальный фокус и атрибут
aria-activedescendant- техника “Roving Tabindex” и манипуляция атрибутом
tabindexОбе техники требуют нетривиальных реализаций на JS с прослушкой множества событий клавиатуры и фокуса. Подводных камней хватает.
Команда Edge в рамках группы OpenUI предложила добавить в браузеры атрибут
focusgroup для управления фокусом и клавиатурой в виджетах.<div
role="toolbar"
focusgroup
aria-label="Text Formatting"
aria-controls="…"
>
<button
type="button"
aria-pressed="false"
value="bold"
tabindex="-1"
>
Bold
</button>
<button
type="button"
aria-pressed="false"
value="italic"
tabindex="-1"
>
Italic
</button>
<!-- ... -->
</div>
При перемещении по странице через клавиатуру, фокус попадёт на первую кнопка в тулбаре, не смотря на
tabindex="-1". Браузер находит внутри элемента с focusgroup все интерактивные элементы и те, которые отмечены атрибутом tabindex="-1".Перемещение между кнопками в тулбаре осуществляется стрелками. “Вверх” и “вправо” — следующая кнопка, “вниз” и “влево” — предыдущая. Кнопка “Home” переносит фокус на первую кнопку, а “End” — на последнюю. Предусмотрен зацикленный переход между первой и последней кнопками при указании
focusgroup="wrap".При выходе фокуса из тулбара, браузер сохранит последнюю сфокусированную кнопку и вновь сфокусирует её при возврате фокуса в тулбар. Это отключается, если указать
focusgroup="no-memory". Значения
inline и block настраивают направление. inline — навигация стрелками “влево”/“вправо”. block — навигация стрелками “вверх”/“вниз”. При этом учитывается направление письма.<div
role="toolbar"
focusgroup="inline wrap no-memory"
aria-label="Text Formatting"
aria-controls="…"
>
<!-- ... -->
</div>
Пример тулбара с горизонтальной навигацией, переносом между крайними элементами и без сохранения последнего сфокусированного элемента.
Значение
grid включает автоматическую табличную навигацию. Этот режим работает со стандартными HTML-таблицами и табличной раскладкой (display: table-*) для автоматического вычисления порядка фокуса при навигации. Дополнительные значения flow, col-wrap, row-wrap, col-flow и row-flow уточняют, как нужно переносить фокус между столбцами и строками таблицы.Значение
manual-grid включает ручную табличную навигацию. В этом режиме для строк и столбцов нужно дополнительно указать focusgroup со значениями grid-row и grid-cell. Это позволяет добавлять навигацию в пользовательские таблицы на основе <div> + flexbox или grid.Для всех значений атрибута
focusgroup предлагаются аналоги в виде CSS-свойств:.element {
focus-group-type: linear; /* grid | manual-grid |
grid-row | grid-cell */
focus-group-direction: both; /* inline | block */
focus-group-wrap: none; /* wrap | flow | col-wrap |
col-flow | col-none | row-wrap | row-flow | row-none */
focus-group-memory: auto; /* none */
}Есть экспериментальный пользовательский полифилл с поддержкой базовых функций (без табличной навигации и CSS) и демо-страница, на которой его можно опробовать. Также есть оригинальный полифилл от команды Edge, но он разработан для более раннего варианта синтаксиса, который уже изменился.
Статус функции пока не понятен. По результатам State of HTML. в
focusgroup есть заинтересованность со стороны разработчиков. Браузеры, вроде как, тоже относятся положительно. В Chrome были какие-то эксперименты. Работа над предложением продолжается, хотя и не очень активно.#html #css #a11y
❤8🔥7🌚2
JSX из прошлого
React популяризировал синтаксис JSX (JavaScript XML). На первый взгляд выглядит как HTML, но пишется в JS как есть, без кавычек и ближе по правилам к XML.
Но такой код нигде работать не будет. При попытке запустить код в браузере, на первом же символе
Но когда-то похожий код в JS вполне работал. Существует стандарт ECMA-357 (PDF), который описывает расширение синтаксиса JS под названием E4X (ECMAScript for XML). Суть была в том, чтобы добавить в JS поддержку синтаксиса XML и предоставить возможности для работы с ним.
В конце 90-х и 00-x XML был распространённым форматом структурированных данных. Логично, что разработчики хотели удобно работать с ним напрямую в JS. Поддержка E4X была реализована в разных продуктах. Среди них Flash, Thunderbird, Firefox, OpenOffice и другие. Но в Firefox 10 E4X был объявлен устаревшим, а в Firefox 21 поддержка была полностью удалена. Работает ли E4X где-то сегодня, сказать трудно, информации практически нет.
Набор возможностей E4X был достаточно большим: XML-разметка в JS, подстановка данных из переменных, динамические имена элементов и атрибутов, добавление и удаление элементов, итерация по списку элементов, чтение и запись атрибутов, фрагменты, фильтрация по имени элемента и значению атрибута, JS-выражения в фигурных скобках, вызовы функций в разметке, сериализация в XML-строку и так далее. Посмотреть на примеры кода можно в архивных статьях MDN.
Со временем формат JSON вытеснил XML, а DOM API получил развитие и новые возможности. Необходимость в E4X пропала. Если нужно работать с XML, то для этого есть
#js #xml
React популяризировал синтаксис JSX (JavaScript XML). На первый взгляд выглядит как HTML, но пишется в JS как есть, без кавычек и ближе по правилам к XML.
export default function TodoList() {
return (
<>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
className="photo"
/>
<ul>
<li>Invent new traffic lights</li>
<li>Rehearse a movie scene</li>
<li>Improve the spectrum technology</li>
</ul>
</>
);
}Но такой код нигде работать не будет. При попытке запустить код в браузере, на первом же символе
< возникнет ошибка синтаксиса. JSX — это синтаксическое расширение JS. Чтобы код работал в браузере, его необходимо транспилировать. Для этого используются соответствующие инструменты: babel, esbuild, swc, tsc и другие. В процессе вся HTML-подобная разметка заменяется на вызовы функций. JSX разработан для удобства описания разметки и композиции UI в JS.Но когда-то похожий код в JS вполне работал. Существует стандарт ECMA-357 (PDF), который описывает расширение синтаксиса JS под названием E4X (ECMAScript for XML). Суть была в том, чтобы добавить в JS поддержку синтаксиса XML и предоставить возможности для работы с ним.
В конце 90-х и 00-x XML был распространённым форматом структурированных данных. Логично, что разработчики хотели удобно работать с ним напрямую в JS. Поддержка E4X была реализована в разных продуктах. Среди них Flash, Thunderbird, Firefox, OpenOffice и другие. Но в Firefox 10 E4X был объявлен устаревшим, а в Firefox 21 поддержка была полностью удалена. Работает ли E4X где-то сегодня, сказать трудно, информации практически нет.
Набор возможностей E4X был достаточно большим: XML-разметка в JS, подстановка данных из переменных, динамические имена элементов и атрибутов, добавление и удаление элементов, итерация по списку элементов, чтение и запись атрибутов, фрагменты, фильтрация по имени элемента и значению атрибута, JS-выражения в фигурных скобках, вызовы функций в разметке, сериализация в XML-строку и так далее. Посмотреть на примеры кода можно в архивных статьях MDN.
Со временем формат JSON вытеснил XML, а DOM API получил развитие и новые возможности. Необходимость в E4X пропала. Если нужно работать с XML, то для этого есть
DOMParser и DOM API. Интересно, что со временем JSX стал распространённым синтаксисом и даже высказывались предложения по его стандартизации. При этом JSX не связан с E4X и уходит корнями к PHP и синтаксическому расширению XHP.#js #xml
Ecma International
ECMA-357 - Ecma International
ECMAScript for XML (E4x) specification
🤔12🤓4👍3❤2🔥1
user-select
В CSS есть непримечательное свойство
Я иногда использую
Недавно узнал, что у свойства
Тап по тексту на тач-устройстах приводит к тому, что выделяется слово, по которому тапнули. Если слово включает какие-то спецсимволы, например тире или скобки, то выделяется только часть слова без этих символов. Чтобы выделить всё, нужно долгое нажатие и иногда дополнительно подвинуть каретку.
И тут на сцену выходит
Где это может пригодиться:
- Блоки с кодом. Как инлайновые
- Номера телефона, электронная почта. Если по каким-то причинам для их разметки не подходит
- Идентификаторы. Это может быть артикул товара, ID пользователя в системе, штриход, промокод, номер плательщика и так далее. Такие идентификаторы иногда содержат спецсимволы. Да и просто быстро выделить весь идентификатор одним кликом удобно.
Думаю можно ещё придумать места, где это применимо. В целом, если пользователи что-то часто копируют, то это может быть хорошим местом для применения
В каком-то смысле свойство может быть ленивой реализацией кнопки “скопировать”, которую часто делают в блогах про разработку рядом с блоками кода. Нажали на код, выделился весь код в блоке, нажали
Кстати, у Стаса есть канал CSS isn’t magic. Там узнаю интересные штуки. Рекомендую посмотреть.
#css
В CSS есть непримечательное свойство
user-select. Оно управляет тем, как выделяется текст. Это свойство используется крайне редко, потому что к механизму выделения текста по умолчанию все привыкли и обычно менять ничего не нужно.Я иногда использую
user-select: none; чтобы отключить выделение у кнопок. Бывает, что при долгом нажатии на тач-устройствах или при быстром многократном нажатии происходит выделение подписи кнопки. На телефонах при выделении всплывает тулбар с кнопками “копировать”, “перевести”, зумится экран или ещё что-то происходит. Обычно для кнопок этого не хочется.Недавно узнал, что у свойства
user-select есть значение all из статьи Стаса Мельникова. Меня это натолкнуло на некоторые мысли, где и как это можно использовать.Тап по тексту на тач-устройстах приводит к тому, что выделяется слово, по которому тапнули. Если слово включает какие-то спецсимволы, например тире или скобки, то выделяется только часть слова без этих символов. Чтобы выделить всё, нужно долгое нажатие и иногда дополнительно подвинуть каретку.
И тут на сцену выходит
user-select: all;. Свойство включает автоматическое выделение всего, что есть в текущем узле DOM и всех его дочерних узлах. Иными словами будет выделен весь текст узла. Это приводит к тому, что одиночное нажатие или тап выделяет всё сразу, включая спецсимволы и текст вложенных узлов.Где это может пригодиться:
- Блоки с кодом. Как инлайновые
<code>, <samp>, <kbd>, <var>, так и потоковые <pre> часто содержат код с кавычками, скобками, точками и прочим. А в <pre> часто вкладываются <span>-ы для реализации подсветки синтаксиса. К тому же сниппеты кода часто копируются для воспроизведения.- Номера телефона, электронная почта. Если по каким-то причинам для их разметки не подходит
<a> со схемой (tel:, email:), то можно обернуть в <span> с user-select: all;, чтобы номер или почта выделялись целиком в один клик, включая спецсимволы.- Идентификаторы. Это может быть артикул товара, ID пользователя в системе, штриход, промокод, номер плательщика и так далее. Такие идентификаторы иногда содержат спецсимволы. Да и просто быстро выделить весь идентификатор одним кликом удобно.
Думаю можно ещё придумать места, где это применимо. В целом, если пользователи что-то часто копируют, то это может быть хорошим местом для применения
user-select: all;. Думаю, это свойство также могут использовать разработчики WYSIWYG и текстовых редакторов.В каком-то смысле свойство может быть ленивой реализацией кнопки “скопировать”, которую часто делают в блогах про разработку рядом с блоками кода. Нажали на код, выделился весь код в блоке, нажали
Ctrl+C (или тапнули “копировать” на тулбаре). Это не заменяет отдельную кнопку “скопировать”, но будет как прогрессивное улучшение и дополнение к ней.Кстати, у Стаса есть канал CSS isn’t magic. Там узнаю интересные штуки. Рекомендую посмотреть.
#css
Telegram
CSS isn't magic
Развлекательный контент для разработчиков с опытом, показывающий, что CSS — это не магия ✨
🕒 Каждую среду с 17:30 до 18:00
🎅 Автор: @melnik909
✋ Канал публичный. Если не помогаете финансово, однажды доступ закроется
🕒 Каждую среду с 17:30 до 18:00
🎅 Автор: @melnik909
✋ Канал публичный. Если не помогаете финансово, однажды доступ закроется
🔥17👍8❤4🤬1
Улучшения <dialog>
В ноябре прошлого (2024) года команда Chrome поделилась улучшениями <details>, которые сделают его удобнее с точки зрения DX. Теперь представлены улучшения элемента
Декларативное открытие и закрытие
Popover API предлагает декларативное создание кнопки-триггера через атрибуты
Атрибут closedby
Это новый атрибут, который добавлен в спецификацию HTML. Он предназначен для управления механизмом закрытия диалога. При значении
События beforetoggle и toggle
Для диалогов, поповеров и
scrollbar-gutter: stable
Свойство не новое и уже достаточно давно доступно в браузерах (в Safari недавно тоже завезли). Свойство управляет пространством, которое резервируется для скроллбара. Работает только для скроллбаров, которые занимают место, на плавающие скроллбары не влияет. Свойство решает проблему смещения страницы, когда при открытии диалога прокрутка блокируется через
***
Эти нововведения направлены на более удобную работу с элементом
#html
В ноябре прошлого (2024) года команда Chrome поделилась улучшениями <details>, которые сделают его удобнее с точки зрения DX. Теперь представлены улучшения элемента
<dialog>. За последние годы его хорошенько подтянули по функциональности и доступности. Тем не менее, всё ещё есть неудобные моменты. Их и хотят решить новыми функциями.Декларативное открытие и закрытие
Popover API предлагает декларативное создание кнопки-триггера через атрибуты
popovertarget и popovertargetaction. Диалог можно открыть только вызовом методов в JS. Предложение Invokers Command предлагает декларативный способ открытия и закрытия диалогов через атрибуты по аналогии с Popover API. Я делал обзор предложения (со старым синтаксисом invokertarget/invokeraction)<button type="button" commandfor="dialog" command="show-modal">
Show modal
</button>
<dialog id="dialog">
<p>I am some dialog content...</p>
<button type="button" commandfor="dialog" command="close">
Close dialog
</button>
</dialog>
Атрибут closedby
Это новый атрибут, который добавлен в спецификацию HTML. Он предназначен для управления механизмом закрытия диалога. При значении
closerequest диалог закроется кнопкой Esc, жестом «назад», специальными жестами в скринридере, методом close() или командой close в HTML. При значении any, помимо указанных способов, диалог закроется при нажатии за его пределами или по ::backdrop. При значении none закрыть диалог можно будет только программно.События beforetoggle и toggle
Для диалогов, поповеров и
<details> разработаны новые события. beforetoggle происходит перед показом/скрытием элемента, а toggle — после. Оба события предоставляют свойства oldState и newState со значениями "open" или "closed". Так можно определить, элемент показывается или скрывается. preventDefault() в обработчике beforetoggle отменяет показ/скрытие.scrollbar-gutter: stable
Свойство не новое и уже достаточно давно доступно в браузерах (в Safari недавно тоже завезли). Свойство управляет пространством, которое резервируется для скроллбара. Работает только для скроллбаров, которые занимают место, на плавающие скроллбары не влияет. Свойство решает проблему смещения страницы, когда при открытии диалога прокрутка блокируется через
overflow: hidden.***
Эти нововведения направлены на более удобную работу с элементом
<dialog>. Что-то уже реализовано во всех браузерах, что-то частично, а что-то находится за экспериментальными флагами. Постепенно функции появятся во всех браузерах.#html
👍16🔥2🌚2❤1
You don't know HTML: translate
В браузерах есть встроенные функции перевода страницы. Chrome, например, отображает попап и предлагает перевести страницу, если обнаружит, что язык контента не соответствует языку системы.
Переводчики достаточно умные, насколько это возможно при текущем уровне развития технологий. Но порой они переводят то, что переводить не нужно. Я иногда читаю технические статьи на medium, где переводятся в том числе блоки кода. Это не то, что нуждается в переводе.
Избежать этого поможет глобальный атрибут
Значение
При вёрстке полезно указать
Анастасия Батарей поделилась статьёй с примерами использования атрибута в рамках адвент-календаря HTMHell. Также короткой заметкой с примером поделился Стефан Джудис.
#ydkhtml #html
В браузерах есть встроенные функции перевода страницы. Chrome, например, отображает попап и предлагает перевести страницу, если обнаружит, что язык контента не соответствует языку системы.
Переводчики достаточно умные, насколько это возможно при текущем уровне развития технологий. Но порой они переводят то, что переводить не нужно. Я иногда читаю технические статьи на medium, где переводятся в том числе блоки кода. Это не то, что нуждается в переводе.
Избежать этого поможет глобальный атрибут
translate, который можно указывать у любого элемента. Он входит в стандарт HTML и принимает два значения: yes и no. Переводчики учитывают этот атрибут и не переводят текст внутри элементов, у которых установлено translate="no".Значение
yes сообщает переводчикам, что текст перевести нужно. Это может пригодиться в редких случаях, когда переводчик не переводит некоторые слова и фразы, распознавая их как названия брендов, термины или специфические слова.При вёрстке полезно указать
translate="no" для блоков с контентом, который не нужно переводить: ФИО, email (если разделён на несколько частей), специальные названия, фрагменты кода, никнеймы. Важно помимо этого указать правильное значение атрибута lang у <html> и фрагментов контента на других языках.Анастасия Батарей поделилась статьёй с примерами использования атрибута в рамках адвент-календаря HTMHell. Также короткой заметкой с примером поделился Стефан Джудис.
#ydkhtml #html
❤14👍10🔥3😱3🥰1
Анимация ключевых слов
В прошлом году в Chromium браузерах появилась возможность создавать анимацию между значениями длины и специальными ключевыми словами (intrinsic sizing keywords). Значения длины — это
Проблема в том, что браузеру нужно вычислить значение, соответствующее ключевому слову на основе контента. Поэтому не совсем понятно, как анимировать
Включается такое поведение свойством
Классический пример — аккордеон. Нужно, чтобы высота блока с произвольным контентом плавно изменялась от
Другой способ — использовать новую функцию
Особенность
В статье на Chrome for Developers более подробно описано как это всё работает с примерами кода и видео (для браузеров, которые ещё это не поддерживают).
#css
В прошлом году в Chromium браузерах появилась возможность создавать анимацию между значениями длины и специальными ключевыми словами (intrinsic sizing keywords). Значения длины — это
px, rem, % и так далее. Ключевые слова — это auto, min-content, fit-content и другие. Они доступны в качестве значений некоторых свойств, например height.Проблема в том, что браузеру нужно вычислить значение, соответствующее ключевому слову на основе контента. Поэтому не совсем понятно, как анимировать
0px в auto. А auto это сколько? Теперь есть механизм, который включает интерполяцию. Браузер будет вычислять необходимые промежуточные значения и делать переходы между ними.Включается такое поведение свойством
interpolate-size: allow-keywords. Его можно указать у конкретного элемента, где это нужно, или глобально для всей страницы, так как свойство наследуемое.:root {
/* Включение интерполяции для всей страницы */
interpolate-size: allow-keywords;
}
.accordion {
/* Или только для конкретного селектора */
interpolate-size: allow-keywords;
}Классический пример — аккордеон. Нужно, чтобы высота блока с произвольным контентом плавно изменялась от
0 до высоты контента и наоборот. Так как контент произвольный, высота заранее не известна и хотелось бы использовать ключевое слово auto или max-content. Раньше для этого использовался JS, теперь можно сделать на CSS..accordion__content {
height: 0px;
overflow: hidden;
transition: height .5s;
interpolate-size: allow-keywords;
}
.accordion__button[aria-expanded="true"] + .accordion__content {
height: max-content;
/* или auto вместо max-content */
}Другой способ — использовать новую функцию
calc-size(). Это как calc(), только умеет работать с ключевыми словами..accordion__content {
height: 0px;
overflow: hidden;
transition: height .5s;
}
.accordion__button[aria-expanded="true"] + .accordion__content {
height: calc-size(max-content, size);
/* или auto вместо max-content */
}Особенность
calc-size() в том, что ко второму аргументу можно применять математические операции. Можно сделать так, чтобы аккордеон открылся на высоту контента и ещё дополнительные 20px:.accordion__button[aria-expanded="true"] + .accordion__content {
height: calc-size(max-content, size + 20px);
/* или auto вместо max-content */
}В статье на Chrome for Developers более подробно описано как это всё работает с примерами кода и видео (для браузеров, которые ещё это не поддерживают).
#css
Chrome for Developers
Animate to height: auto; (and other intrinsic sizing keywords) in CSS | CSS and UI | Chrome for Developers
Animate to and from intrinsic sizing keywords with `interpolate-size` and `calc-size()`
🔥20👍5🌚2❤1
Техника фасадов
Использование фасадов — это техника оптимизации загрузки виджетов сторонних поставщиков. Речь о виджетах, которые вставляются на страницу через
В случае с
Частично эти проблемы решаются ленивой загрузкой (
Техника фасадов направлена на загрузку ресурсов только при необходимости. Создаётся простая заглушка, которая выглядит как виджет — фасад. Для YouTube это обложка видео и узнаваемая красная кнопка. Для карт это статический скриншот области. Для чата это пульсирующая кнопка с иконкой в углу страницы.
К заглушке (фасаду) добавляются обработчики событий: нажатие, наведение курсора или появления в области просмотра. Событие инициирует загрузку ресурсов и фасад заменяется на настоящий виджет. В итоге ресурсы загружаются только тогда, когда они действительно нужны.
У Вадима Макеева есть видео с реализацией фасада для встраиваемого плеера YouTube. Ролику уже 6 лет, но он всё ещё актуален и хорошо демонстрирует суть (вместо padding-хака для пропорций сейчас стоит использовать свойство
Для плеера YouTube есть готовый веб-компонент с реализацией фасада. В его описании есть ссылки на компоненты для Vimeo и других виджетов. Для Nuxt есть отдельное решение для сторонних скриптов, которое в том числе использует фасады. Lighthouse будет выдавать рекомендацию по использованию фасадов, если обнаружит на странице сторонние виджеты.
#performance
Использование фасадов — это техника оптимизации загрузки виджетов сторонних поставщиков. Речь о виджетах, которые вставляются на страницу через
<iframe> или <noscript> с инициализацией в <div>: карты, плееры YouTube, чат-боты, рейтинги и так далее.В случае с
<iframe> проблема в том, что внутри загружается отдельный документ со своими стилями и скриптами. И это происходит для каждого <iframe>. С <noscript> проблема в том, что код второстепенных виджетов загружает основной поток и конфликтует с более важными скриптами.Частично эти проблемы решаются ленивой загрузкой (
<iframe loading="lazy">) и отложенными скриптами (<noscript defer>). Ещё можно выставить низкий приоритет загрузки. Не смотря на это, ресурсы всё равно загрузятся и обработаются, а пользователь может даже не будет взаимодействовать с виджетом.Техника фасадов направлена на загрузку ресурсов только при необходимости. Создаётся простая заглушка, которая выглядит как виджет — фасад. Для YouTube это обложка видео и узнаваемая красная кнопка. Для карт это статический скриншот области. Для чата это пульсирующая кнопка с иконкой в углу страницы.
К заглушке (фасаду) добавляются обработчики событий: нажатие, наведение курсора или появления в области просмотра. Событие инициирует загрузку ресурсов и фасад заменяется на настоящий виджет. В итоге ресурсы загружаются только тогда, когда они действительно нужны.
У Вадима Макеева есть видео с реализацией фасада для встраиваемого плеера YouTube. Ролику уже 6 лет, но он всё ещё актуален и хорошо демонстрирует суть (вместо padding-хака для пропорций сейчас стоит использовать свойство
aspect-ratio). Для плеера YouTube есть готовый веб-компонент с реализацией фасада. В его описании есть ссылки на компоненты для Vimeo и других виджетов. Для Nuxt есть отдельное решение для сторонних скриптов, которое в том числе использует фасады. Lighthouse будет выдавать рекомендацию по использованию фасадов, если обнаружит на странице сторонние виджеты.
#performance
Chrome for Developers
Lazy load third-party resources with facades | Lighthouse | Chrome for Developers
Learn about the opportunities to lazy load third-party resources with facades.
🔥21👍9❤2🌚2