"Новый критерий WCAG"
Со мной поделились ссылкой на новый критерий WCAG 2.2. И я считаю, что он очень важен!
P.S. Эта страница выполнена в стиле спецификаций W3C, но является шуткой. Авторы предлагают новый "критерий", который в ироничном виде и с использованием ненормативной лексики призывает делать интерфейсы доступными.
Со мной поделились ссылкой на новый критерий WCAG 2.2. И я считаю, что он очень важен!
P.S. Эта страница выполнена в стиле спецификаций W3C, но является шуткой. Авторы предлагают новый "критерий", который в ироничном виде и с использованием ненормативной лексики призывает делать интерфейсы доступными.
😁7❤🔥4
Про меню
Что такое меню в пользовательских интерфейсах? Набор горизонтальных ссылок в шапке сайта — меню. Вертикальный набор ссылок, переключающих экраны в мобильном приложении — меню. Список действий над файлом в верхней части приложения (например, File -> Save As...) — меню. Раскрывающийся при нажатии на иконку-бургер список категорий товаров в магазине — меню.
В спецификации ARIA есть роли
Согласно спецификации,
Вспомните любое десктопное приложение, например Photoshop, Figma, VSCode, Word, Paint. У всех них в верхней части есть горизонтальное меню — это
Согласно той же спецификации, внутри
А вот типичный блок с ссылками на сайте не является меню в контексте спецификации. Об этом пишут и в ARIA практиках. Набор ссылок на сайте — это навигация. Поэтому паттерн меню в таком случае не применим. Навигация — это про страницы, URL-адреса и фрагменты (якори). Меню — это про вызов действий в приложении. Это очень похоже на вопрос "кнопка или ссылка".
Так вот: если при нажатии на элемент происходит переход на другую страницу (или перерисовка с изменением URL в SPA), переход к разделу на странице (якорь), страницу можно открыть в новой вкладке, новом окне, в инкогнито, ссылку можно скопировать, сохранить в закладки, поделиться, ссылка должна индексироваться — это навигация. Для этого нужно использовать элементы с ролями
Если при нажатии на пункт открывается вложенное меню, диалоговое окно, меняется часть интерфейса приложения, происходит какое-то действие с данными, меняются настройки, режим работы и т.д. — это меню. Для этого нужно использовать паттерны
Контекстные меню, открываемые щелчком правой кнопкой мыши по элементу или при помощи сочетания
Что такое меню в пользовательских интерфейсах? Набор горизонтальных ссылок в шапке сайта — меню. Вертикальный набор ссылок, переключающих экраны в мобильном приложении — меню. Список действий над файлом в верхней части приложения (например, File -> Save As...) — меню. Раскрывающийся при нажатии на иконку-бургер список категорий товаров в магазине — меню.
В спецификации ARIA есть роли
menu и menubar, а в спецификации WHATWG есть элемент <menu>. Есть большой соблазн использовать их не по назначению. Периодически я встречаю такое. Давайте разбираться.Согласно спецификации,
menu и menubar — это виджеты, которые предлагают список действий или функций, которые пользователь может вызвать. Эта роль уместна для меню, которые похожи на меню в десктопных приложениях. Что особенного в меню десктопных приложений? Дело в том, что в таких приложениях нет понятия "страница" и "URL-адрес". Пункты меню в десктопных приложениях выполняют какие-то действия, но не меняют URL.Вспомните любое десктопное приложение, например Photoshop, Figma, VSCode, Word, Paint. У всех них в верхней части есть горизонтальное меню — это
menubar. При нажатии пункта в этих меню происходит действие — открытие выпадающего вертикального меню — это и есть menu. Разница между menubar и menu в значении aria-orientation по умолчанию: horizontal для menubar и vertical для menu. Пользователи ожидают от menu и menubar возможности навигации между пунктами при помощи клавиш со стрелками, Home и End. От menu ожидается навигация стрелками вверх/вниз, а от menubar — влево/вправо.Согласно той же спецификации, внутри
menu и menubar могут располагаться только элементы с ролями menuitem, menuitemcheckbox и menuitemradio. Также элементы можно группировать при помощи роли group и разделять при помощи separator (в ARIA 1.3).А вот типичный блок с ссылками на сайте не является меню в контексте спецификации. Об этом пишут и в ARIA практиках. Набор ссылок на сайте — это навигация. Поэтому паттерн меню в таком случае не применим. Навигация — это про страницы, URL-адреса и фрагменты (якори). Меню — это про вызов действий в приложении. Это очень похоже на вопрос "кнопка или ссылка".
Так вот: если при нажатии на элемент происходит переход на другую страницу (или перерисовка с изменением URL в SPA), переход к разделу на странице (якорь), страницу можно открыть в новой вкладке, новом окне, в инкогнито, ссылку можно скопировать, сохранить в закладки, поделиться, ссылка должна индексироваться — это навигация. Для этого нужно использовать элементы с ролями
navigation и link, то есть встроенные элементы <nav> и <a>. Можно добавить список, если элементов больше 3-4.<nav aria-label="Main">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/products">Products</a></li>
<li><a href="/pricing">Pricing</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
Если при нажатии на пункт открывается вложенное меню, диалоговое окно, меняется часть интерфейса приложения, происходит какое-то действие с данными, меняются настройки, режим работы и т.д. — это меню. Для этого нужно использовать паттерны
menu и menubar. Так как встроенных в HTML аналогов нет, то меню можно сконструировать из семантически-нейтральных элементов и соответствующих ролей. Часто его делают из списка. В этом есть смысл, но я предпочитаю использовать кнопки с ролями, так как они сами по себе интерактивные, в отличие от элементов списка.<div role="menu">
<button type="button" role="menuitem">Save...</button>
<button type="button" role="menuitem">Save As...</button>
<button type="button" role="menuitemcheckbox" aria-checked="false">Autosave</button>
<button type="button" role="menuitem">Open</button>
<button type="button" role="menuitem">Undo</button>
<button type="button" role="menuitem">Rendo</button>
</div>
Контекстные меню, открываемые щелчком правой кнопкой мыши по элементу или при помощи сочетания
Shift+F10 на Windows — это тоже меню. Но не используйте роли menu и menubar для навигации на сайте.🔥13👏2❤1👍1
Роли-контейнеры: toolbar.
В предыдущем посте я рассказал о ролях
Есть и другие роли-контейнеры для интерактивных элементов, например
В качестве примеров: панель инструментов в текстовом или графическом редакторе.
Есть некоторые интерактивные элементы, которые используют стрелки в своих нуждах. Например,
Для
Скринридеры озвучивают роль и имя (если оно есть), а также выход за пределы
Кейсы использования:
- панель инструментов в редакторе чего-либо
- группировка связанных по смыслу интерактивных элементов в приложениях с большим количеством таких элементов.
Описание паттерна
Пример реализации
Спецификация роли
В предыдущем посте я рассказал о ролях
menu и menubar. Напомню: это роли-контейнеры для элементов menuitem, menuitemradio и menuitemcheckbox. По функционалу это набор каких-то действий и функций, которые может вызвать пользователь. Но это не набор навигационных ссылок. Предполагается горизонтальная (для menubar) и вертикальная (для menu) стрелочная навигация.Есть и другие роли-контейнеры для интерактивных элементов, например
toolbar.toolbar — контейнер для интерактивных элементов, таких как кнопки, чекбоксы, переключатели и т.д. toolbar предназначен для группировки набора интерактивных элементов, которые визуально сгруппированы и для уменьшения количества шагов табуляции.В качестве примеров: панель инструментов в текстовом или графическом редакторе.
toolbar очень похож на menubar, оба горизонтальные и предполагают навигацию стрелками влево/вправо. Разница между ними в том, что внутри menubar могут быть только элементы с определёнными ролями, а у toolbar таких ограничений нет. Внутри toolbar можно расположить любые интерактивные элементы с одной оговоркой.Есть некоторые интерактивные элементы, которые используют стрелки в своих нуждах. Например,
<input type="number">. При попадании фокуса стрелки вверх/вниз увеличивают/уменьшают значение, а стрелки влево/вправо перемещают каретку. Такие элементы не рекомендуется использовать внутри toolbar, чтобы избежать конфликтов со стрелками и не сломать навигацию. Но такие элементы можно использовать в конце toolbar, если их избежать не получается.Для
toolbar подразумевается aria-orientation="horizontal", то есть элементы расположены горизонтально и есть стрелочная навигации между элементами. Это можно переопределить, указав атрибут с другим значением. Если на странице более одного toolbar, то всем им нужно добавить имя при помощи aria-label или aria-labelledby. Использовать toolbar стоит только когда элементов 3 и более.Скринридеры озвучивают роль и имя (если оно есть), а также выход за пределы
toolbar:<div role="toolbar" aria-label="Text settings">При последовательной навигации это будет зачитано так:
<button type="button" aria-label="Bold"></button>
<button type="button" aria-label="Italic"></button>
<button type="button" aria-label="Underline"></button>
</div>
Text settings toolbar
Bold button
Italic button
Underline button
Out of toolbar
Кейсы использования:
- панель инструментов в редакторе чего-либо
- группировка связанных по смыслу интерактивных элементов в приложениях с большим количеством таких элементов.
Описание паттерна
toolbar.Пример реализации
toolbar в текстовом редакторе. Обратите внимание на то, что внутри toolbar различные элементы и паттерны.Спецификация роли
toolbar.❤9👍3🔥3
CSS isn't magic
Мой коллега по цеху, Стас (кому-то может быть знаком по статьям на хабре), завёл канал CSS isn't magic. В нём он стремится показать, что CSS не является магией и рассказать о способах решения старых задач при помощи новых возможностей. Если вам интересен CSS, то рекомендую подписаться.
Мой коллега по цеху, Стас (кому-то может быть знаком по статьям на хабре), завёл канал CSS isn't magic. В нём он стремится показать, что CSS не является магией и рассказать о способах решения старых задач при помощи новых возможностей. Если вам интересен CSS, то рекомендую подписаться.
Telegram
CSS isn't magic
Развлекательный контент для разработчиков с опытом, показывающий, что CSS — это не магия ✨
🕒 Каждую среду с 17:30 до 18:00
🎅 Автор: @melnik909
✋ Канал публичный. В нем всегда один пост. Доступ ко всему контенту можно купить. Напишите мне, я помогу
🕒 Каждую среду с 17:30 до 18:00
🎅 Автор: @melnik909
✋ Канал публичный. В нем всегда один пост. Доступ ко всему контенту можно купить. Напишите мне, я помогу
👍2❤1
Прозрачность в hex
Формат
Но бывало же такое, что дизайнер в макете везде использовал hex, но в одном месте захотел сделать прозрачность? В итоге все цвета задаются в
Так вот, уже достаточно давно в
В hex альфа-канал задаётся добавлением в конец шестнадцатеричных чисел. То есть формат записи следующий:
То есть:
Формат
hex при указании цветов в CSS, пожалуй, является самым популярным. Формат с нами давно, к нему все привыкли, он идёт по умолчанию практически во всех редакторах, есть куча инструментов для трансформации, он самый короткий (короче только некоторые именованные цвета). Если не стоит задача делать динамические палитры в браузере, поддерживать мониторы с широким охватом цветов, использовать математику для расчёта цветов, то hex — это самый очевидный выбор.Но бывало же такое, что дизайнер в макете везде использовал hex, но в одном месте захотел сделать прозрачность? В итоге все цвета задаются в
hex, а цвет с прозрачностью приходится писать в rgba. В этот момент разрушается единообразие формата указания цветов. Появляются как минимум две разные нотации, а rgba ещё и кучей разных способов можно записать, но об этом в другой раз.Так вот, уже достаточно давно в
hex можно указывать прозрачность, но почему-то я ещё ни разу не видел, чтобы этим кто-то пользовался. Возможно, потому что это не удобно: представьте себе 60% прозрачности в шестнадцатеричном формате? Это будет 99, а не 3C, как можно было подумать 🤯В hex альфа-канал задаётся добавлением в конец шестнадцатеричных чисел. То есть формат записи следующий:
#RRGGBBAA или #RGBA.То есть:
#000, #000F, #000000 и #000000FF — чёрный непрозрачный, то же самое, что rgb(0 0 0) и rgb(0 0 0 / 1)#0000 и #00000000 — чёрный прозрачный, то же самое, что rgb(0 0 0 / 0)#000C и #000000CC — чёрный с 80% прозрачности, то же самое, что rgb(0 0 0 / 0.8)#00000040 — чёрный с 25% прозрачности, тоже самое, что rgb(0 0 0 / 0.25)Caniuse
#rrggbbaa hex color notation | Can I use... Support tables for HTML5, CSS3, etc
"Can I use" provides up-to-date browser support tables for support of front-end web technologies on desktop and mobile web browsers.
👍5🔥1
Семантика заголовка с подзаголовками
Kevin Powell, известный по ютуб-каналу про CSS, задал в твиттере вопрос: как семантически разметить заголовок как на фото? Есть верхний текст, основной заголовок и нижний текст. Весь этот текст объединён в один смысловой блок. Так как же это лучше сверстать?
Так как текст связан, тут хорошо подойдёт роль
<hgroup> в спецификации HTML.
Kevin Powell, известный по ютуб-каналу про CSS, задал в твиттере вопрос: как семантически разметить заголовок как на фото? Есть верхний текст, основной заголовок и нижний текст. Весь этот текст объединён в один смысловой блок. Так как же это лучше сверстать?
Так как текст связан, тут хорошо подойдёт роль
group. Также вспоминаем первое правило ARIA: не использовать ARIA. Поэтому подбираем элемент с ролью group, который есть в HTML. И такой существует как раз для нашей задачи — <hgroup>:<hgroup>
<p>Plant parenting simplified</p>
<h1>From wilted to wow: Plant care made easy</h1>
<p>Tired of drooping leaves? Learn how to revive your plants and create a thriving indoor oasis.</p>
</hgroup>
<hgroup> в спецификации HTML.
👍5❤4👏1
Alt картинки:
Скриншот блока на сайте. Он состоит из текста "Plant parenting simplified" перед заголовком, текстом "From wilted to wow: Plant care made easy" самого заголовка, текста "Tired of drooping leaves? Learn how to revive your plants and create a thriving indoor oasis" после заголовка и кнопки-ссылки "Get Started".
Скриншот блока на сайте. Он состоит из текста "Plant parenting simplified" перед заголовком, текстом "From wilted to wow: Plant care made easy" самого заголовка, текста "Tired of drooping leaves? Learn how to revive your plants and create a thriving indoor oasis" после заголовка и кнопки-ссылки "Get Started".
🤨1
Роли-контейнеры: group
Продолжаю рассказывать про роли-контейнеры. На очереди
Что за объекты пользовательского интерфейса? Это любые элементы, будь то интерактивные или неинтерактивные. Это отличает
Группируемые при помощи
Группировать при помощи
В HTML есть встроенные элементы с ролью
Где применять на практике? В первую очередь стоит использовать встроенные элементы HTML вместо ARIA-ролей. Если встроенные элементы не подходят, тогда можно указать роль
Варианты использования:
- группировка связанных полей (
- группировка контактных данных (
- группировка заголовка и подзаголовка (
- группировка второстепеного, менее актуального или скрываемого контента (
- группировка опций (
- группировка
- группировка
- группировка
- группировка любых других связанных элементов интерфейса (
Спецификация роли group.
Продолжаю рассказывать про роли-контейнеры. На очереди
group. Эта роль предназначена для группировки объектов пользовательского интерфейса, которые не должны попадать в список содержимого. Давайте разбираться.Что за объекты пользовательского интерфейса? Это любые элементы, будь то интерактивные или неинтерактивные. Это отличает
group, например, от рассмотреных ранее menu, menubar и toolbar, которые предназначены для интерактивных элементов.Группируемые при помощи
group элементы не попадают в список содержимого. Речь о функции в скринридерах, которая позволяет открыть окно со списком всех ссылок, кнопок, списков, заголовков и ориентиров. Это отличает group от region, который попадает в список ориентиров, если для него задано имя.group не подразумевает никакую клавиатурную навигацию, а служит только для группировки частей интерфейса. Добавить клавиатурную навигацию можно, однако об этом нужно предупредить пользователей, которые не ожидают от group такого поведения. Для group также нужно задавать имя при помощи aria-label или aria-labelledby.Группировать при помощи
group можно не только произвольный набор элементов на странице, но и элементы внутри некоторых виджетов. Так, внутри menu и menubar можно группировать menuitem, menuitemcheckbox и menuitemradio. В combobox и listbox можно группировать option. А в tree можно группировать treeitem.В HTML есть встроенные элементы с ролью
group. Элемент <fieldset> представляет group. Если внутри есть <legend>, то его текст будет использован как имя для <fieldset>. Элементы <hgroup>, <address>, <details> и <optgroup> также представляют group в дереве доступности, поэтому вручную задавать роль group им не рекомендуется.Где применять на практике? В первую очередь стоит использовать встроенные элементы HTML вместо ARIA-ролей. Если встроенные элементы не подходят, тогда можно указать роль
group на семантически нейтральных элементах <div> или <span>:<div role="group" aria-label="Галерея">
<img src="img1.jpg" alt="Описание...">
<img src="img2.jpg" alt="Описание...">
<img src="img3.jpg" alt="Описание...">
</div>
Варианты использования:
- группировка связанных полей (
<fieldset> + <legend>)- группировка контактных данных (
<address>)- группировка заголовка и подзаголовка (
<hgroup> + <h*> + <p>)- группировка второстепеного, менее актуального или скрываемого контента (
<details> + <summary>)- группировка опций (
<select> или <datalist> + <optgroup> + <option>)- группировка
menuitem, menuitemradio и menuitemcheckbox в menu и menubar- группировка
option в listbox и combobox- группировка
treeitem в tree- группировка любых других связанных элементов интерфейса (
<div> или <span> + role="group")Спецификация роли group.
🔥8❤1🤩1
The WebAIM Million
Вышели результаты ежегодного исследования от WebAIM. В этом исследовании анализируется миллион домашних страниц сайтов на предмет наличия различных ошибок доступности.
Анализ проводится при помощи инструмента WAVE, а по объёмам это самое большое исследование доступности сайтов. Поэтому можно сказать, что оно в каком-то виде отражает состояние доступности сайтов по интернету.
С результатами можно ознакомиться в отчёте на сайте WebAIM. Интересной особенностью является возможность вбить домен вашего сайта и выяснить, попал ли он в выборку для исследования.
Вышели результаты ежегодного исследования от WebAIM. В этом исследовании анализируется миллион домашних страниц сайтов на предмет наличия различных ошибок доступности.
Анализ проводится при помощи инструмента WAVE, а по объёмам это самое большое исследование доступности сайтов. Поэтому можно сказать, что оно в каком-то виде отражает состояние доступности сайтов по интернету.
С результатами можно ознакомиться в отчёте на сайте WebAIM. Интересной особенностью является возможность вбить домен вашего сайта и выяснить, попал ли он в выборку для исследования.
🔥2👍1
Gulp 5.0
Как-то раз я делал пост про Gulp, в котором рассказывал, что он давно не обновлялся, многие зависимости и плагины устарели и предлагал варианты для замены. Но на днях, спустя почти 5 лет, у gulp произошёл релиз версии 5.0.
Так как это мажорная версия, то не обошлось без breaking changes. Отказались от поддержки Node <10.13, унифицировали механизм работы с glob, удалили старые флаги, уменьшили количество зависимостей и обновили оставшиеся, изменили библиотеку для работы со стримами и кучу всего другого.
Некоторые старые зависимости, которые используются под капотом и не обновляются, команда gulp взяла под свой неймспейс и также обновила их. Поэтому другие пакеты могут теперь использовать обновлённые версии от gulp.
В общем gulp жив, внезапно. Другой вопрос к экосистеме плагинов, за которую команда gulp не отвечает. Многие плагины тоже стоило бы обновить. Также вопрос в актуальности: функционал gulp практически полностью замещается parcel или CLI-инструментами, не говоря уже о сборщиках вроде Vite.
Как-то раз я делал пост про Gulp, в котором рассказывал, что он давно не обновлялся, многие зависимости и плагины устарели и предлагал варианты для замены. Но на днях, спустя почти 5 лет, у gulp произошёл релиз версии 5.0.
Так как это мажорная версия, то не обошлось без breaking changes. Отказались от поддержки Node <10.13, унифицировали механизм работы с glob, удалили старые флаги, уменьшили количество зависимостей и обновили оставшиеся, изменили библиотеку для работы со стримами и кучу всего другого.
Некоторые старые зависимости, которые используются под капотом и не обновляются, команда gulp взяла под свой неймспейс и также обновила их. Поэтому другие пакеты могут теперь использовать обновлённые версии от gulp.
В общем gulp жив, внезапно. Другой вопрос к экосистеме плагинов, за которую команда gulp не отвечает. Многие плагины тоже стоило бы обновить. Также вопрос в актуальности: функционал gulp практически полностью замещается parcel или CLI-инструментами, не говоря уже о сборщиках вроде Vite.
Telegram
<divelopers>
Про Gulp 🥤
Посмотрел один видео-гайд от автора с 70к подписчиков. Утверждается, что это полный гайд по gulp 4 с современным синтаксисом. Я понимаю, что контент для новичков и подаётся простыми словами, но гайд не соответствует заявленному и вводит в заблуждение.…
Посмотрел один видео-гайд от автора с 70к подписчиков. Утверждается, что это полный гайд по gulp 4 с современным синтаксисом. Я понимаю, что контент для новичков и подаётся простыми словами, но гайд не соответствует заявленному и вводит в заблуждение.…
👍9
Статья про семантику
На Доке вышла статья про семантическую вёрстку в HTML. Это одна из моих любимых тем. Также это одна из спорных и не очевидных тем. Я, конечно же, не могу пройти мимо. На мой взгляд статья содержит ряд неточностей. Дам свои комментарии по этим моментам.
Это не особый способ разметки, а стандартный, страницы должны правильно размечаться. Смысловое содержание и предназначение блока — это одно и то же. Семантика элемента буквально несёт информацию о смысле контента, который в нём находится и как он связан с другим контентом.
Один из самых распространённых стереотипов, наряду с картинкой о разметке классической страницы.
В спецификации есть примечание, что в
Это верно только в том случае, когда они относятся к основному разделу страницы
Доступность не является фактором ранжирования. В официальных источниках от Google и Yandex такой информации нет. Core Web Vitals оказывает небольшое влияние. Оценка доступности хоть и отображается в Lighthouse, но это информационный показатель, он не входит в Core Web Vitals.
Роботы понимают текст и контекст, причём в первую очередь. Иначе куча сайтов с вёрсткой на
Семантические элементы помогают алгоритмам чуть лучше понять контент и его взаимосвязи, но гораздо менее важны, чем сам текст. Сайт в любом случае будет проиндексирован. Хороший текст с плохой разметкой будет выше в выдаче, чем плохой текст с хорошей разметкой.
Семантические элементы действительно влияют на построение сниппетов, но больше влияния на это оказывает микроразметка.
Этот совет работает не всегда.
На Доке вышла статья про семантическую вёрстку в HTML. Это одна из моих любимых тем. Также это одна из спорных и не очевидных тем. Я, конечно же, не могу пройти мимо. На мой взгляд статья содержит ряд неточностей. Дам свои комментарии по этим моментам.
Семантическая вёрстка — особый подход к написанию HTML-разметки страниц. При этом подходе разработчик опирается не на содержание сайта, а на смысловое предназначение каждого блока и логическую структуру страницы.
Это не особый способ разметки, а стандартный, страницы должны правильно размечаться. Смысловое содержание и предназначение блока — это одно и то же. Семантика элемента буквально несёт информацию о смысле контента, который в нём находится и как он связан с другим контентом.
<aside> — тег для дополнительного контента, используется для создания «сайдбара» или бокового меню на сайтах.
Один из самых распространённых стереотипов, наряду с картинкой о разметке классической страницы.
<aside> — это не боковая колонка! <aside> — это второстепенный контент, который связан с окружающим контентом. Кажется мне стоит сделать отдельный, более подробный пост про этот элемент.<nav> — контейнер для навигации со ссылками на другие страницы и разделы сайта
В спецификации есть примечание, что в
<nav> не стоит заворачивать любую навигацию, а только основную. Если на странице несколько <nav>, то каждому из них нужно задавать имя.Теги вроде <header> и <footer> — ориентиры.
Это верно только в том случае, когда они относятся к основному разделу страницы
<body>. То есть между <body> и этими элементами нет других секционных элементов (<section>, <article>, <aside>, <nav>).Уровень доступности сайта сам по себе — один из факторов ранжирования в поисковых системах.
Доступность не является фактором ранжирования. В официальных источниках от Google и Yandex такой информации нет. Core Web Vitals оказывает небольшое влияние. Оценка доступности хоть и отображается в Lighthouse, но это информационный показатель, он не входит в Core Web Vitals.
Семантическая вёрстка помогают и самим поисковым движкам. Они не понимают сам текст, его контекст и то, насколько он важен.
Роботы понимают текст и контекст, причём в первую очередь. Иначе куча сайтов с вёрсткой на
<div>-ах бы не оказалась в топах поисковой выдачи. Качество текста, его смысл, связь с другим текстом на странице — один из решающих показателей при ранжировании. Об этом достаточно много упоминается в документации Google Search.Семантические теги дают поисковым системам нужный контекст, помогают понять содержимое сайта и проиндексировать его относительно других со схожей тематикой.
Семантические элементы помогают алгоритмам чуть лучше понять контент и его взаимосвязи, но гораздо менее важны, чем сам текст. Сайт в любом случае будет проиндексирован. Хороший текст с плохой разметкой будет выше в выдаче, чем плохой текст с хорошей разметкой.
Например, в Google под название сайта попадают заголовки второго уровня, если используете тег <h2>.
Семантические элементы действительно влияют на построение сниппетов, но больше влияния на это оказывает микроразметка.
Если тянет добавить к <div> классы вроде header, sidebar, content, post и footer, лучше использовать теги <header>, <aside>, <main>, <article> и <footer>.
Этот совет работает не всегда.
sidebar не всегда <aside>, content не всегда <main>, post не всегда <article>. Иногда лучше написать <div> с одним из этих классов, чем использовать созвучный с классом элемент.Дока
Что такое семантика? — HTML — Дока
Как работает семантика в HTML и зачем она вообще нужна.
👍13❤7
Фронтенд-фантазии
Наткнулся в твиттере на пост, что в следующей версии Bun можно будет писать комментарии в файле
Также недавно Рич Харрис, автор Svelte, был крайне удивлён: оказывается, конструкция
Это всё натолкнуло меня на одну мысль: во фронтенде очень много придуманного "синтаксического сахара", который не является стандартизированным и валидным для того языка, в котором используется. И этот синтаксис придуман и внедрен авторами инструментов. В итоге получается забавная ситуация: мы вроде бы пишем код на HTML, CSS и JS, но в то же время пишем какой-то придуманный синтаксис, используем надмножества языков.
Но такой код:
- не является валидным с точки зрения спецификаций языков
- требует дополнительных инструментов для преобразования
- требует плагинов IDE для подсветки синтаксиса, автодополнения и подсказок
- требует изучения дополнительной документации
- усложняет новичкам порог входа в проект и в профессию в целом
- может конфликтовать с будущими внедрениями в язык или не позволять эти внедрения сделать
- теряет совместимость с другими инструментами
Я придерживаюсь мнения, что нужно всегда оставаться как можно ближе к веб-платформе. Иными словами я за стандарты. Возможно, это мнение не популярно, хотя есть немало сторонников этой идеи, некоторые даже пишут статьи по этой теме. У меня назрела идея тоже написать статью с разбором и примерами на эту тему.
Наткнулся в твиттере на пост, что в следующей версии Bun можно будет писать комментарии в файле
package.json и Bun не будет выдавать ошибок. На самом деле возможность хорошая, иной раз хочется добавить комментарий к npm-скрипту или пакету. Но, всё-таки, это формат json, со своей спецификацией и правилами, комментарии там запрещены синтаксисом. Bun мог бы реализовать поддержку существующих форматов json5 или jsonc, где комментарии разрешены.Также недавно Рич Харрис, автор Svelte, был крайне удивлён: оказывается, конструкция
<div /> не является валидной в HTML и не является сокращением для <div></div>. При этом в Svelte такая конструкция работает и было принято решение это исправить и привести парсер в соответствие со стандартом. А ещё подобная конструкция есть в JSX, наряду с бесполезными слешами в конце тегов.Это всё натолкнуло меня на одну мысль: во фронтенде очень много придуманного "синтаксического сахара", который не является стандартизированным и валидным для того языка, в котором используется. И этот синтаксис придуман и внедрен авторами инструментов. В итоге получается забавная ситуация: мы вроде бы пишем код на HTML, CSS и JS, но в то же время пишем какой-то придуманный синтаксис, используем надмножества языков.
Но такой код:
- не является валидным с точки зрения спецификаций языков
- требует дополнительных инструментов для преобразования
- требует плагинов IDE для подсветки синтаксиса, автодополнения и подсказок
- требует изучения дополнительной документации
- усложняет новичкам порог входа в проект и в профессию в целом
- может конфликтовать с будущими внедрениями в язык или не позволять эти внедрения сделать
- теряет совместимость с другими инструментами
Я придерживаюсь мнения, что нужно всегда оставаться как можно ближе к веб-платформе. Иными словами я за стандарты. Возможно, это мнение не популярно, хотя есть немало сторонников этой идеи, некоторые даже пишут статьи по этой теме. У меня назрела идея тоже написать статью с разбором и примерами на эту тему.
👍7
<divelopers>
Нативные поповеры! В Chrome 114, который вышел в конце мая 2023, завезли Popover API. Firefox и Safari поддержали этот API и должны выкатить в ближайшее время. И это крутая новость! <button popovertarget="note"> Подробнее </button> <div id="note" popover>…
Шнурки
Последнее время на многих проектах я использую библиотеку UI-компонентов shoelace.style. Поэтому хочу поделиться опытом.
Библиотека построена на базе веб-стандартов и под капотом использует Lit. Каждый UI-компонент поставляется в виде веб-компонента. Это делает библиотеку независимой от фреймворков, что отличает её от таких решений, как MUI, Vuetify, Angular Material и т.д. При этом компоненты Shoelace можно использовать во Vue и Angular. С 19 версии React их полноценно можно будет использовать и там, а пока автор предоставляет для React компоненты-обёртки.
Другой особенностью Shoelace является устройство стилей. Библиотека предоставляет базовую светлую и тёмную темы. Это CSS-файлы, в которых содержатся токены в виде пользовательских свойств CSS (палитра, отступы, размеры, закругления, тени и т.д.) и несколько служебных классов. В остальном там нет никаких других стилей.
Все необходимые стили содержатся в Shadow DOM у каждого UI-компонента. Эти стили изолированы от внешнего воздействия, но по правилам Shadow DOM они наследуют значения наследуемых свойств и видят внешние пользовательские свойства CSS. Если подключена тема, то компоненты будут использовать объявленные в ней свойства. Если тема не подключена, компоненты будут работать, но потеряют свой внешний вид.
Можно создать свою тему, подключив CSS-файл со своими значениями пользовательских свойств. Такой вариант подойдёт, когда библиотека используются в качестве UI kit, то есть интерфейс приложения будет полностью построен на компонентах этой библиотеки.
Но можно использовать компоненты точечно. Если в проекте нужна только карусель и диалоговое окно, библиотека позволяет взять только эти компоненты и не тянуть лишнее. Самый простой способ — воспользоваться автозагрузчиком. Он ищет на странице компоненты и сам подгружает нужные для их работы модули. Можно подключить нужный компонент самостоятельно через
Библиотека также поставляет API к каждому компоненту в виде атрибутов, свойств, методов, событий, пользовательских свойств CSS, слотов и частей (CSS Shadow Parts). Благодаря этому компоненты можно стилизовать практически как угодно. Это большой плюс, потому что некоторые библиотеки крайне сложно кастомизировать.
В основном над Shoelace работает один человек — Cory LaViska. Он активно развивает библиотеку и выпускает новые версии. Одни раз я столкнулся с багом и создал issue на github, которое было решено в течении нескольких дней. Также автор уделяет большое внимание доступности. При разработке компонентов он опирается на рекомендации WCAG и ARIA практики. В общем рекомендую взглянуть на эту библиотеку.
Последнее время на многих проектах я использую библиотеку UI-компонентов shoelace.style. Поэтому хочу поделиться опытом.
Библиотека построена на базе веб-стандартов и под капотом использует Lit. Каждый UI-компонент поставляется в виде веб-компонента. Это делает библиотеку независимой от фреймворков, что отличает её от таких решений, как MUI, Vuetify, Angular Material и т.д. При этом компоненты Shoelace можно использовать во Vue и Angular. С 19 версии React их полноценно можно будет использовать и там, а пока автор предоставляет для React компоненты-обёртки.
Другой особенностью Shoelace является устройство стилей. Библиотека предоставляет базовую светлую и тёмную темы. Это CSS-файлы, в которых содержатся токены в виде пользовательских свойств CSS (палитра, отступы, размеры, закругления, тени и т.д.) и несколько служебных классов. В остальном там нет никаких других стилей.
Все необходимые стили содержатся в Shadow DOM у каждого UI-компонента. Эти стили изолированы от внешнего воздействия, но по правилам Shadow DOM они наследуют значения наследуемых свойств и видят внешние пользовательские свойства CSS. Если подключена тема, то компоненты будут использовать объявленные в ней свойства. Если тема не подключена, компоненты будут работать, но потеряют свой внешний вид.
Можно создать свою тему, подключив CSS-файл со своими значениями пользовательских свойств. Такой вариант подойдёт, когда библиотека используются в качестве UI kit, то есть интерфейс приложения будет полностью построен на компонентах этой библиотеки.
Но можно использовать компоненты точечно. Если в проекте нужна только карусель и диалоговое окно, библиотека позволяет взять только эти компоненты и не тянуть лишнее. Самый простой способ — воспользоваться автозагрузчиком. Он ищет на странице компоненты и сам подгружает нужные для их работы модули. Можно подключить нужный компонент самостоятельно через
<noscript>, как в старые добрые времена, или импортировать модуль в JS при помощи import или import().Библиотека также поставляет API к каждому компоненту в виде атрибутов, свойств, методов, событий, пользовательских свойств CSS, слотов и частей (CSS Shadow Parts). Благодаря этому компоненты можно стилизовать практически как угодно. Это большой плюс, потому что некоторые библиотеки крайне сложно кастомизировать.
В основном над Shoelace работает один человек — Cory LaViska. Он активно развивает библиотеку и выпускает новые версии. Одни раз я столкнулся с багом и создал issue на github, которое было решено в течении нескольких дней. Также автор уделяет большое внимание доступности. При разработке компонентов он опирается на рекомендации WCAG и ARIA практики. В общем рекомендую взглянуть на эту библиотеку.
shoelace.style
Shoelace: A forward-thinking library of web components.
Hand-crafted custom elements for any occasion.
👍7🔥5🐳1
You don't know HTML
В рамках этого канала я запускаю новую рубрику под названием You don't know HTML. Название вдохновлено серией книг You don't know JS Кайла Симпсона, рекомендую к прочтению.
Посты будут выходить с хештегом #ydkhtml и будут посвящены разным тонкостям и интересным моментам из спецификации HTML. Я считаю, что HTML недооценён, его часто считают чем-то простым и базовым, уделяют мало времени для изучения и быстрее двигаются дальше, к CSS и Javanoscript. В итоге качество разметки в интернете в целом очень плохое.
Между тем, HTML является фундаментальной технологией веба, она содержит в себе множество возможностей, которые порой позволяют решать задачи максимально простым и декларативным способом. Ну и, в конце концов, надо как-то оправдывать то время, которое я когда-то потратил на изучение спецификации WHATWG HTML 😁
В общем, скоро появятся посты из этой рубрики. Постараюсь приносить какие-то интересные факты и возможности, которые вы могли не знать.
В рамках этого канала я запускаю новую рубрику под названием You don't know HTML. Название вдохновлено серией книг You don't know JS Кайла Симпсона, рекомендую к прочтению.
Посты будут выходить с хештегом #ydkhtml и будут посвящены разным тонкостям и интересным моментам из спецификации HTML. Я считаю, что HTML недооценён, его часто считают чем-то простым и базовым, уделяют мало времени для изучения и быстрее двигаются дальше, к CSS и Javanoscript. В итоге качество разметки в интернете в целом очень плохое.
Между тем, HTML является фундаментальной технологией веба, она содержит в себе множество возможностей, которые порой позволяют решать задачи максимально простым и декларативным способом. Ну и, в конце концов, надо как-то оправдывать то время, которое я когда-то потратил на изучение спецификации WHATWG HTML 😁
В общем, скоро появятся посты из этой рубрики. Постараюсь приносить какие-то интересные факты и возможности, которые вы могли не знать.
🔥17👍7❤5
You don't know HTML: download
Иногда нужно сделать ссылку для загрузки файла: отчёт, документ, фото, счёт, инструкция и т.д. В HTML для этого есть атрибут
При клике по такой ссылке начнётся загрузка файла, указанного в
Итоговое название файла генерируется на основе разных источников, в основном это название из
Также можно загружать небольшие файлы, встроенные через
Загрузить файл можно и без атрибута
#ydkhtml
Иногда нужно сделать ссылку для загрузки файла: отчёт, документ, фото, счёт, инструкция и т.д. В HTML для этого есть атрибут
download у элементов <a> и <area>:<a href="report.pdf" download>
Скачать отчёт
</a>
При клике по такой ссылке начнётся загрузка файла, указанного в
href. Если в href указан адрес страницы, то будет загружен html-файл этой страницы. Итоговое название файла генерируется на основе разных источников, в основном это название из
href. Но у атрибута download можно указать значение: произвольную строку с рекомендуемым именем файла. Это имя будет подставлено в системное окно сохранения файла вместо его названия из href. Это удобно, когда имя файла генерируется случайным образом:<a href="b3f7be5pc3b8w24q6g.pdf" download="Заказ №5241836">Скачать детали заказа</a>
Также можно загружать небольшие файлы, встроенные через
data URL:<a href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAA..." download="Логотип">Скачать логотип</a>
Загрузить файл можно и без атрибута
download. Если в href указать ссылку на файл, который браузер не может отобразить, то автоматически начнётся загрузка.<a href="prices.xlsx">Прайслист</a>
#ydkhtml
👍8🔥6🗿2
О валидности разметки
На хабре вышла статья про отрисовку таблиц при помощи Symbiote.js. Это фреймворк, который базируются на веб-стандартах и активно использует API веб-компонентов. За это авторам отдельный респект, потому что мне нравится идея максимально близких к платформе инструментов, полагающихся на стандарты.
В статье описывается работа с таблицами при помощи этого фреймворка. Всё бы хорошо, но приводятся примеры итоговой сгенерированной разметки:
В примере кода из статьи внутрь
Фреймворк добавляет таким элементам свойство
Чем такая невалидная разметка чревата? Страница будет невалидной, валидатор не сможет полностью проверить страницу, ассистивные технологии, парсеры и поисковые роботы не распознают данные из таблицы, перестанут работать API-методы таблиц (добавление строк, получение данных и т.д.).
Как в этой ситуации поступить? Раз инструмент полагается на кастомные элементы, то всю таблицу стоит делать при помощи них и добавлять дополнительную семантику при помощи ARIA-атрибутов как рекомендуется в WAI-ARIA практиках для таблиц.
На хабре вышла статья про отрисовку таблиц при помощи Symbiote.js. Это фреймворк, который базируются на веб-стандартах и активно использует API веб-компонентов. За это авторам отдельный респект, потому что мне нравится идея максимально близких к платформе инструментов, полагающихся на стандарты.
В статье описывается работа с таблицами при помощи этого фреймворка. Всё бы хорошо, но приводятся примеры итоговой сгенерированной разметки:
<my-table>Этот фрагмент разметки не является валидным. Дело в том, что по спецификации внутри
<table>
<table-row>
<td>Row number: 1</td>
<td>Date: 1714405915233</td>
</table-row>
<table-row>
<td>Row number: 2</td>
<td>Date: 1714405915233</td>
</table-row>
<table-row>
<td>Row number: 3</td>
<td>Date: 1714405915233</td>
</table-row>
</table>
</my-table>
<table> разрешено вкладывать только <caption>, <colgroup>, <thead>, <tbody>, <tfoot>, <tr>, <noscript> и <template>. Причём не просто вкладывать в произвольно порядке, а по определённым правилам.В примере кода из статьи внутрь
<table> вкладываются кастомные элементы <table-row>, что недопустимо. На этом этапе валидатор бросает критическую ошибку и прекращает дальнейший разбор разметки.Фреймворк добавляет таким элементам свойство
display: contents, которое делает кастомный элемент "прозрачным" при построении раскладки и не учитывает его. Но физически элемент всё равно остаётся в DOM и AOM, поэтому свойство проблему не решает.Чем такая невалидная разметка чревата? Страница будет невалидной, валидатор не сможет полностью проверить страницу, ассистивные технологии, парсеры и поисковые роботы не распознают данные из таблицы, перестанут работать API-методы таблиц (добавление строк, получение данных и т.д.).
Как в этой ситуации поступить? Раз инструмент полагается на кастомные элементы, то всю таблицу стоит делать при помощи них и добавлять дополнительную семантику при помощи ARIA-атрибутов как рекомендуется в WAI-ARIA практиках для таблиц.
<my-table role="table" aria-rowcount="3" aria-colcount="2">
<table-row role="row">
<table-cell role="rowheader">Row number: 1</table-cell>
<table-cell role="cell">Date: 1714405915233</table-cell>
</table-row>
<table-row role="row">
<table-cell role="rowheader">Row number: 2</table-cell>
<table-cell role="cell">Date: 1714405915233</table-cell>
</table-row>
<table-row role="row">
<table-cell role="rowheader">Row number: 3</table-cell>
<table-cell role="cell">Date: 1714405915233</table-cell>
</table-row>
</my-table>
Web Accessibility Initiative (WAI)
Table Example
Accessibility resources free online from the international standards organization: W3C Web Accessibility Initiative (WAI).
❤8👍5
Новости веб-компонентов
На днях прошли ежеквартальные встречи членов комьюнити группы веб-компонентов (WCCG). Среди них люди из разных компаний и независимые эксперты, которые вместе определяют направление развития веб-компонентов.
На этот раз обсуждались следующие темы:
- Scoped Element Registries
- ARIA Reference Target
- Open Stylable Shadow Roots
- DOM Scheduler API
- Declarative Custom Elements
- HTML Modules
Из интересного, показали презентацию с примером веб-компонента, который демонстрирует возможности Declarative Custom Elements (кастомные элементы, создаваемые в HTML без Javanoscript). Вполне возможно, что в похожем виде в будущем это заедет в браузеры.
Демонстрируемый компонент
Это хороший пример того, как при помощи веб-компонентов можно создавать демонстрационные решения, полифилы и proof of concept для будущих решений.
На днях прошли ежеквартальные встречи членов комьюнити группы веб-компонентов (WCCG). Среди них люди из разных компаний и независимые эксперты, которые вместе определяют направление развития веб-компонентов.
На этот раз обсуждались следующие темы:
- Scoped Element Registries
- ARIA Reference Target
- Open Stylable Shadow Roots
- DOM Scheduler API
- Declarative Custom Elements
- HTML Modules
Из интересного, показали презентацию с примером веб-компонента, который демонстрирует возможности Declarative Custom Elements (кастомные элементы, создаваемые в HTML без Javanoscript). Вполне возможно, что в похожем виде в будущем это заедет в браузеры.
Демонстрируемый компонент
<stampino-element> позволяет определять новый пользовательский элемент, добавлять стили через Constructed Stylesheet, определять шаблон с выражениями (как планируется в API Template Instantiation), определять атрибуты и свойства, наследоваться от других элементов и добавляет новые методы жизненного цикла.Это хороший пример того, как при помощи веб-компонентов можно создавать демонстрационные решения, полифилы и proof of concept для будущих решений.
Google Docs
Declarative Custom Elements with Stampino
Stampino Element @justinfagnani
🔥5
Сброс стилей
Довольно частое явление в интерфейсах — псевдокнопки. Я думаю, что многие могли видеть подобный код:
Конечно, так делать не стоит, это плохая практика. Для кнопок существует элемент
Почему же тогда делают
В итоге нужно либо подключать reset, либо переопределять стили. Тащить reset не всегда хочется, к тому же это лишний CSS. А при переопределении стилей есть риск забыть про какие-то частные случаи. Поэтому проще взять стилистически нейтральный
Но есть другое решение — свойство
Что тут происходит? Ключевое слово
А таким образом можно в 3 строки сделать сброс всех свойств для всех элементов:
Но как в этом примере, сбрасывать все стили для всех элементов, всё-таки, я не рекомендую. А вот с кнопкой вполне себе вариант.
Довольно частое явление в интерфейсах — псевдокнопки. Я думаю, что многие могли видеть подобный код:
<div role="button" tabindex="-1">Button</div>
Конечно, так делать не стоит, это плохая практика. Для кнопок существует элемент
<button>. У него есть встроенная роль, семантика, скринридеры правильно озвучивают, есть встроенная реакция на нажатие Enter и Space и много чего ещё.Почему же тогда делают
<div>? Одна из причин — встроенные браузерные стили: рамка, фон, внутренние отступы, шрифт и т.д. Причём в каждом браузере свой набор этих встроенных стилей и кнопки выглядит по-разному. В итоге нужно либо подключать reset, либо переопределять стили. Тащить reset не всегда хочется, к тому же это лишний CSS. А при переопределении стилей есть риск забыть про какие-то частные случаи. Поэтому проще взять стилистически нейтральный
<div> и сделать из него кнопку.Но есть другое решение — свойство
all. Это псевдоним для всех свойств CSS, кроме direction и unicode-bidi. Эти два свойства, прямо скажем, редкие гости, поэтому можно считать, что all — синоним для всех свойств. Поэтому можно сделать так:button {
all: unset;
/* далее нужные стили кнопки */
}
Что тут происходит? Ключевое слово
unset сбрасывает значение всех CSS-свойств до inherit (если свойство наследуемое) или initial (если не наследуемое). Иными словами, приводит их к значениям по умолчанию. Получаем кнопку, у которой все свойства имеют значения по умолчанию, прямо как у <div>. А далее уже можно определять нужные стили.А таким образом можно в 3 строки сделать сброс всех свойств для всех элементов:
* {
all: unset;
}
Но как в этом примере, сбрасывать все стили для всех элементов, всё-таки, я не рекомендую. А вот с кнопкой вполне себе вариант.
🔥13👍7❤2
Результаты State of HTML
После длительного затишья опубликованы результаты опроса State Of HTML 2023. Напомню, что это опрос для разработчиков на тему использования различных фич HTML, DOM и других браузерных API. Цель этого опроса — выявить проблемные моменты и болевые точки, с которыми сталкиваются разработчики.
По ссылке можно ознакомиться с цифрами и итоговым результатом от Лии Веру, основного автора этого опроса. Ну а я могу сделать отдельный разбор результатов.
После длительного затишья опубликованы результаты опроса State Of HTML 2023. Напомню, что это опрос для разработчиков на тему использования различных фич HTML, DOM и других браузерных API. Цель этого опроса — выявить проблемные моменты и болевые точки, с которыми сталкиваются разработчики.
По ссылке можно ознакомиться с цифрами и итоговым результатом от Лии Веру, основного автора этого опроса. Ну а я могу сделать отдельный разбор результатов.
Stateofhtml
State of HTML 2023
The 2023 edition of the annual survey about the latest trends in the HTML ecosystem.
🔥2