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

Автор: @alexnozer
Download Telegram
Улучшения <details>

Недавно я рассказывал о способе создания аккордеонов при помощи элементов <details> и <summary>. Но всё ещё есть некоторые шероховатости при стилизации этих элементов. Команда Chrome в 131-й версии внедряет ряд доработок, которые сглаживают их.

Установка display для <details>

Сейчас установка свойства display со значениями flex или grid для <details> не влияет на отображение. Это ограничивает возможности стилизации. Доработки устраняют ограничения, flex и grid будут работать.

Псевдо-элемент ::details-content

На данный момент нет способа стилизовать контейнер с контентом, который на самом деле есть в Shadow DOM внутри <details>. Это можно решить добавлением обёртки <div>. Новый псевдо-элемент ::details-content позволит стилизовать существующий под капотом контейнер с контентом без добавления обёртки.

Анимации дискретных свойств

Новые функции CSS calc-size(), intetpolate-size: allow-keyword и content-visibility напрямую не относятся к доработкам <details>, но добавляют новые возможности к настройке анимации. Можно будет анимировать свойство display: none, width: auto и height: auto.

***

Пока только Chrome, но я думаю, что другие браузеры тоже скоро подтянутся.
🔥7
Делать ли ещё посты с обзором подобных находок из прошлого?
Anonymous Poll
75%
Да
8%
Нет
17%
Не знаю / смотреть ответы
<datagrid>, который мы потеряли

В недавнем опросе State of HTML был вопрос “если бы вы могли добавить 3 элемента в HTML, что бы это было”. На выбор предлагалось 11 фиксированных вариантов и поле со свободным вводом. Один из вариантов — Data Table with sorting, filtering, etc. Этого элемента чертовски не хватает тем, кто разрабатывает современные бизнес-приложения, где всегда есть интерактивные таблицы с данными.

Разработчикам приходится подключать сторонние библиотеки с таблицами, зачастую очень тяжёлые. Или реализовывать нетривиальную функциональность таблиц самостоятельно. Для специалистов по доступности это тоже вызов, потому что у интерактивных таблиц сложная модель взаимодействия со вспомогательными технологиями. Взгляните на документацию от WAI:

- общее описание паттерна
- свойства таблиц
- пример реализации

Пример WAI достаточно базовый, в реальных приложениях таблицы сложнее. Забавно, что у WAI есть пример сложной интерактивной таблицы, но это страница-заглушка без контента. До недавнего времени некоторые разделы про таблицы содержали пометки TODO. То есть даже в WAI ещё не до конца решили все вопросы с таблицами.

Было бы здорово, чтобы ребята из WHATWG, CSSWG, WAI и браузеров собрались и сделали классный примитив для интерактивных таблиц. Тем временем я обнаружил кое что интересное в первом или одном из первых черновиков спецификации HTML5 от 22 января 2008 года. Это элемент <datagrid>:

The datagrid element represents an interactive representation of tree, list, or tabular data.

<…>

In the datagrid data model, data is structured as a set of rows representing a tree, each row being split into a number of columns. The columns are always present in the data model, although individual columns may be hidden in the presentation.


В далёком 2008 году (почти 17 лет назад) в спецификацию добавили элемент, который представляет интерактивные таблицы и деревья. Согласно спецификации, в <datagrid> можно было вкладывать <table>, <ol>, <select>, <datalist> и другие. В зависимости от вложенных элементов, менялось поведение <datagrid>. Элемент предлагал методы для работы с данными: получение количества строк и столбцов, сортировка столбцов, выделение и редактирование ячеек, контекстное меню строки и т.д.

Мощнейшее предложение, которое удалили из черновика в 2009 году. Представить только, если бы браузеры реализовали это… Кто знает, может быть в ближайшем будущем к <datagrid> вернутся.

Делать ли ещё посты с обзором подобных находок из прошлого?
👍5😭3
Результаты исследований

На прошлой неделе были опубликованы два исследования: результаты опроса State Of HTML 2024 и отчёт Web Almanac 2024.

State Of HTML — это опрос среди разработчиков, который проводится с 2023 года. State Of HTML посвящён HTML, браузерным API, веб-компонентам, доступности и веб-приложениям. Я делал разбор результатов за 2023 год: часть 1 и часть 2.

Web Almanac — это проект HTTP Archive по исследованию состояния веба. Отчёт выходит раз в год, крайний был опубликован в 2022 году. В 2023 году отчёта не было и вот вышел отчёт за 2024 год. Он пока включает не все разделы, но кое что уже можно посмотреть. Web Almanac хорош тем, что собирает данные с миллионов сайтов в интернете и показывает реальное состояние веба. В этом он отличается от того же State Of HTML, который проводится среди активных и осведомлённых разработчиков.

Я планирую детальнее разобраться с результатами и сделать несколько постов с выводами по конкретным направлениям. А пока можете ознакомиться с результатами по ссылкам:

- State Of HTML 2024
- Web Almanac 2024
9🔥2
Синтаксис Custom Properties

Возможно, вы задавались вопросом: почему у custom properties такой странный синтаксис с двумя дефисами в качестве префикса? Почему не использовали символ $, # или какой-то ещё? Всё дело в парсере CSS. Он давно написан, обрабатывает миллиарды сайтов и ломать его не хочется.

Если у custom properties не будет префикса, возникнут конфликты со стандартными свойствами. Символ @ зарезервирован для медиа-выражений и его использование привело бы к неоднозначным ситуациям парсера. Другие символы не поддерживаются, так как свойства могут начинаться только с буквы или тире.

Парсер умеет разбирать вендорные свойства, например:

-webkit-appearance


Они начинаются с дефиса, затем идёт название вендора, затем ещё один дефис и далее название свойства. А если в качестве названия вендора использовать пустую строку?

--appearance


Парсер обработает это как вендорное свойство без имени вендора. Вот и получился синтаксис custom properties, который использует существующий алгоритм парсера и не нарушает синтаксис свойств CSS. По сути, custom properties — это ваши собственные "вендорные" свойства.

На такие компромиссы приходится идти разработчикам спецификаций и парсеров, когда нужно обрабатывать старый CSS, написанный 30 лет назад, параллельно с новым.
👍10🔥6💋2👎1🌚1
Результаты State of HTML 2024

Без лишних предисловий обзор результатов State of HTML 2024.

Демография

В опросе приняло участие 5402 человека, из которых 58% прошли опрос практически полностью. Аудитория достаточно взрослая и опытная: медианный возраст — 35 лет, а опыт — 15 лет. Эти цифры выше, чем в State of CSS и State of JS. 1248 человек отметило те или иные нарушения здоровья.

Список для чтения

Топ 5 фич из список для чтения: Customizable Select, focusgroup attribute, Popover API, EditContext и CSS Custom Highlight API. Интересно, что в опросе были фичи, находящиеся на стадии разработки: DOM Parts, HTML Modules, focusgroup attribute.

Формы

Основные боли, связанные с формами: проблемы со стилизацией и баги элементов форм, валидация, браузерная поддержка и обработка форм. Людям нравится <datalist>, стилизуемый <select> и autocomplete, но многие отмечают наличие проблем с ними.

Интерактивность

Больше всего болей с интерактивностью связано с браузерной поддержкой, элементом <dialog>, анимациями, Popover API и стилизацией. <dialog> и Popover API нравятся людям, но обладают ограниченной браузерной поддержкой.

Контент

При работе с контентом больше всего болей с SVG, менеджментом изображений, интернационализацией, <iframe> и браузерной поддержкой. Content Security Policy и атрибуты изображений srcset и sizes вызывают негативный опыт.

Веб-компоненты

Основные боли при использовании готовых веб-компонентов: стилизация и кастомизация, Shadow DOM, SSR, совместимость с React и доступность. Что касается болей при разработке веб-компонентов, то в топе Shadow DOM, стилизация и кастомизация, чрезмерная сложность и многословность, браузерная поддержка. Shadow DOM и связанные с ним особенности — главная проблема веб-компонентов. Интересно, что среди фреймворков для разработки веб-компонентов на первом месте Svelte.

Доступность

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

Нативные веб-приложения

Из 3560 ответивших, 55% используют JS-фреймворки для разработки нативных приложений, 38% используют нативные и не связанные с JS технологии. Больше всего болей с проблемами на Apple/iOS, проблемами PWA, браузерной поддержкой, пользовательским опытом и производительностью.

Инструменты

Самый популярным генератор сайтов — Next.js, за ним Astro, Nuxt, SvelteKit и Eleventy. Самые популярные валидаторы — W3C Validator и Validator.nu HTML Checker, хотя это одно и то же. Интересно, что больше половины ответивших не используют валидаторы вообще. Среди инструментов производительности в топе Lighthouse, Devtools, PageSpeed Insights, WebPageTest и Pingdom. Для аналитики больше всего используют Google Analytics, Matomo, Datadog, New Relic и Plausible Analytics. Среди браузеров картина стандартная, но интересно разнообразие. Среди ресурсов лидер — MDN, за ним идут Can I Use, Web.dev, W3C и блог WebKit.

Использование

Топ 5 фич, которые разработчики не могут использовать из-за ограниченной поддержки: Popover API, Anchor Positioning, ViewTransition API, <dialog> и PWA. Среди элементов с недостаточной функциональностью <select>, <input type="date">, <dialog>, <datalist> и <details> + <summary>. Список недостающих в HTML элементов не изменился с прошлого года, в топе Data Table, Tabs, Switch, Skeleton, Context menu. Чаще всего HTML используют для веб-приложений, контентных сайтов, маркетинговых сайтов, дизайн-систем и email.

Мнения

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

***

Вот таким был State of HTML 2024. Посмотрим, что изменится в следующем году. А пока предлагаю пройти опрос State of JS 2024, который идёт прямо сейчас.
👍5🌚21
You don't know HTML: autocomplete

Атрибут autocomplete устанавливается у элементов <form>, текстовых полей ввода <input> и <textarea>. Это подсказка для браузера, какие данные ожидаются в полях. Это именно подсказка, полного контроля нет. Браузер сам принимает итоговое решение на основании множества факторов.

Типы полей <input>, значения атрибутов name и id, текст в <label> и placeholder, соседние элементы, иногда даже значения в атрибуте class и некоторые предположения использует браузер, чтобы вычислить данные, потому что формы не всегда спроектированы хорошо. Есть доклад и статья от разработчиков Яндекс Браузера о том, как работает автозаполнение. Так как Яндекс Браузер основан на Chromium, это справедливо для всех браузеров на этом движке. В других движках механизмы схожие.

autocomplete вместе с правильно спроектированной формой ускоряет ввод данных и снижает количество ошибок. Браузеры сохраняют пароли, адреса, данные банковских карт, ФИО и некоторые другие данные при заполнении форм на других сайтах. Данные можно добавить вручную в настройках браузера.

<form action="/register" method="post">
<label for="firstname">Имя</label>
<input type="text" id="firstname" name="firstname" autocomplete="given-name">
<label for="lastname">Фамилия</label>
  <input type="text" id="lastname" name="lastname" autocomplete="family-name">
<label for="phone">Телефон</label>
  <input type="tel" id="phone" name="phone" autocomplete="tel">
<label for="email">Email</label>
  <input type="email" id="email" name="email" autocomplete="email">
<label for="name">Пароль</label>
  <input type="password" id="password" name="password" autocomplete="new-password">
<button>Создать аккаунт</button>
</form>


У autocomplete не очень много значений, но они покрывают наиболее распространённые сценарии форм: логин, регистрация, оформление заказа, обратная связь. Не исключено, что в будущем появятся новые значения. Например, не так давно было добавлено значение webauthn для Web Authentication API.

В качестве значений можно использовать несколько токенов для разграничения, например, адреса доставки и адреса выставления счёта:

<label for="shipping">Адрес доставки</label>
<input type="text" id="shipping" name="shipping" autocomplete="shipping street-address">
<label for="billing">Платёжный адрес</label>
<input type="text" id="billing" name="billing" autocomplete="billing street-address">


Аналогично можно помечать домашний, рабочий и мобильный телефоны (home tel, work tel или mobile tel). Можно добавлять секции (section-*) для разделения комплексных форм, где есть разделы или динамические группы полей.

Если форма размечена корректно, используется autocomplete и у браузера достаточно данных, то он может заполнить всю форму в один клик. Это очень удобно, особенно на мобильных устройствах. Для максимальной точности советуют использовать распространённые значения для атрибутов name и id, соответствующие типы полей и autocomplete одновременно.

Для отладки автозаполнения форм в Chrome 124 добавили новую панель Autofill. Туда можно добавить разные данные и отлаживать, как форма будет заполняться.

#ydkhtml
👍9🔥3🌚1
Зум полей ввода на iOS

В Safari на iOS иногда встречается ситуация, когда при фокусе в поле ввода страница зумится. Тестировщики могут даже завести соответствующий баг. Не стоит сразу бросаться камнями в Safari, как это обычно бывает. В этом месте они поступают разумно.

“Баг” происходит, когда у текстовых полей ввода значение font-size меньше 16px. Это пороговое значение для комфортного чтения. Поэтому при фокусе в поле страница увеличивается для удобства чтения вводимого значения, чтобы компенсировать font-size ниже порогового значения. Такое поведение распространяется на все браузеры под iOS, так как на данный момент там доступен только один браузерный движок — Webkit. С новыми европейскими регуляциями возможно появление альтернативных движков.

Google тоже учитывает слишком маленький размер шрифта, но иначе. В Lighthouse есть проверка в рамках аудита SEO. Она завершается с ошибкой, если у 40% текста на странице font-size меньше 12px. Ранее похожая проверка была в Google Search Console, в разделе Mobile-friendly. Но с 1 декабря 2023 года поддержка этого раздела прекращена в пользу Lighthouse.

Чтобы избежать зума страницы на iOS, достаточно установить для текстовых полей значение font-size больше или равное 16px. И хорошо, чтобы это было минимальным значением в целом, а не только для полей ввода. Не нужно следовать советам, которые предлагают "исправить проблему" путём добавления значение maximum-scale=1 в мета-тег viewport. Такое "исправление" не проходит один из тестов критерия WCAG 1.4.4 Resize Text. Кроме того, браузеры могут игнорировать значения мета-тега viewport, если сочтут нужным.
👍14🔥6🌚2
CSS Wrapped 2024

Команда 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, поэтому можно поизучать исходники.
🔥5🌚1
Размер DOM и доступность

Я уже писал о размере DOM в контексте производительности. Но чрезмерный размер DOM может негативно повлиять и на доступность.

В операционных системах есть дерево доступности. Оно хранит в себе объекты пользовательского интерфейса с их названиями, ролями, свойствами и состояниями. Вспомогательные технологии используют это дерево для получения информации и предоставления её пользователю в том или ином виде. Например, программа чтения с экрана озвучивает элементы и даёт с ними взаимодействовать при помощи горячих клавиш.

У веб-страниц тоже есть дерево доступности, которое можно посмотреть в DevTools. Дерево доступности веб-страницы формируется на основе DOM. Браузер передаёт операционной системе данные о семантике и свойствах элементов, которые определены по умолчанию или заданы разработчиком через ARIA. Поддерево доступности сайта встраивается в общее дерево операционной системы.

При большом размере DOM браузеру нужно передавать операционной системе больше данных. Особенно если DOM постоянно обновляется, что обычное явление в мире фронтенд-фреймворков. Передача и обработка данных происходит не мгновенно.

В итоге программа чтения с экрана, например, может озвучивать информацию с большой задержкой или озвучивать уже неактуальную информацию. Иногда вовсе может прекратить работу и вылететь из-за того, что не хватило ресурсов на обработку большого объёма данных. Об этом рассказал Эрик Бейли, специалист по доступности из GitHub, на конференции performance. now(), которая прошла недавно. Кому интересно, есть запись доклада.
👍7🔥3🌚2
7 функций, которые нужны каждому сайту

Попалось тут мне одно короткое видео, в котором автор перечисляет 7 функций, которые нужны каждому сайту:

- Cookie-баннер, запрашивающий согласие на трекинг для рекламодателей, обязательно с неочевидными вариантами выбора.
- Запрос местоположения через Geolocation API, чтобы точно знать, где находится пользователь.
- Запрос на отправку Push-уведомлений, чтобы пользователь точно был в курсе всех “важных” новостей сайта.
- Всплывающее модальное окно на весь экран сразу после загрузки страницы, требующее ввести email для подписки на бесполезную рассылку.
- Автоматически воспроизводимое видео со скрытыми элементами управления плеером, чтобы остановить его мог только опытный пользователь.
- Сложная CAPTCHA, ведь пользователям нравится несколько раз подряд выбирать светофоры, автобусы и пешеходные переходы.
- Отключение кнопки “назад”, чтобы возникли трудности при попытке вернуться на предыдущую страницу, обязательно с модальным окном, что пользователь не прав.

Шутки шутками, но мы живём в мире, где такие “функции” не редкость. Я делился докладом Виталия Фридмана Privacy UX, где он показывает такие паттерны на реальных сайтах. Пожалуйста, не делайте так.
👍9🌚3
Link Area Delegation

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

<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-элементы с точки зрения семантики лучше подойдут для разметки такого контента:

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>.
👍15🔥2🌚1
You don’t know HTML: слеш в конце элементов

Регулярно в 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% страниц не указан язык в атрибуте 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 вообще.
👍3🔥21
Вишлист 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
Новогодние каникулы

Канал <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.

Всех с наступающими праздниками! Увидимся в Новом Году!
🔥9🎉84👍3🥰1
Возвращение к работе

Новогодние каникулы подошли к концу, а значит пора возвращаться к работе и каналу.

В планах на этот год:

- увеличить частоту и стабильность выхода контента
- запустить несколько новых рубрик
- писать больше о доступности, производительности и веб-компонентах
- попробовать новые форматы постов

А ещё 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.

Таблица стилей создаётся через конструктор 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 и так далее. Параллельно с парсером, используется ещё один механизм — сканер предварительной загрузки. Его задача — искать ресурсы не дожидаясь, пока парсер до них дойдёт.

В конечном итоге все найденные ресурсы передаются в сетевой процесс, где распределяются по приоритету и начинают загружаться. При работе над производительностью сайта часто смотрят на сетевой водопад — график загрузки ресурсов. Некоторые оптимизации заключаются в том, чтобы изменить положение ресурсов в водопаде, сдвинуть их выше, ниже, или вовсе убрать.

Атрибут 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
🔥36👍2🌚1