@alexnozer_dev


Гео и язык канала: Россия, Русский
Категория: Технологии


Рандомные мысли про HTML, CSS, доступность, пользовательские интерфейсы, производительность, браузеры и веб-стандарты.
Автор: @alexnozer

Связанные каналы  |  Похожие каналы

Гео и язык канала
Россия, Русский
Категория
Технологии
Статистика
Фильтр публикаций
















Cколько опций должно быть в переключателе темы?
Опрос
  •   Три (системная, светлая и тёмная)
  •   Две (системная и противоположная)
  •   Ноль (системная, определяется автоматически)
  •   Смотреть ответы
15 голосов
















Язык документа и его частей

В посте, посвящённому всемирному дню осведомлённости о доступности, упоминалось, что на 13.5% сайтов не задан язык документа. Радует, что это не много по сравнению с другими проблемами. Не радует, что это всё ещё 13.5%.

Исправление крайне простое: нужно задать у корневого элемента страницы атрибут lang со значением, которое соответствует основному языку контента на странице в формате BCP 47.
















На этом можно было бы и закончить пост. Просто добавьте атрибут и это исправит одну из топ 6 ошибок доступности, которую обнаруживает WAVE. Но я расскажу ещё некоторые особенности и фишки вокруг языка страницы.

От языка страницы зависит отображение некоторых элементов, в частности . Он предназначен для встроенных цитат и обрамляет текст в кавычки. Вид кавычек меняется в зависимости от языка (ёлочки или лапки).

Если сайт мультиязычный и хочется что-то менять в CSS в зависимости от языка, есть селектор :lang(). Он более мощный, чем селектор по атрибуту html[lang="..."] из-за масок и работы с вычисленным языком, а не значением в атрибуте.

ol:lang(en-US) > li::marker {
/*
Маркеры списка 1) 2) 3) для американскго английского
*/
content: counter(list-item) ') ';
}

ol:lang(ru, by, uk) > li::marker {
/*
Маркеры списка 1. 2. 3. для восточнославянских языков
*/
content: counter(list-item) '. ';
}

На странице могут быть элементы, контент которых не соответствует основному языку страницы: цитаты, термины, названия или переключатель языка. Такие элементы также нужно пометить соответствующим атрибутом lang.

Вообще lang — глобальный атрибут и его можно указывать у любых элементов. Язык наследуется вглубь по дереву от ближайшего родителя с lang. Сам атрибут переопределяет унаследованный язык.


...

...

Язык




href="/ru"
aria-current="true"
>
Русский



href="/en"
lang="en"
hreflang="en"
>
English



href="/es"
lang="es"
hreflang="es"
>
Español


...





Атрибут hreflang помогает роботам понять, что страница по ссылке на другом языке. Это важно при SEO-продвижении мультиязычного сайта. К этому ещё стоит добавить ссылки на альтернативные версии текущей страницы на других языках.


...


...


Среди контента могут быть общепринятые термины, названия брендов или фразы, которые написаны на другом языке, но не должны переводиться автоматическими переводчиками. На этот случай существует атрибут translate со значением no.

Vite позволяет быстро собирать frontend-проекты различной сложности.

#html #css #a11y


Эффект съезда с тротуара

Читая материал о доступности, встретился с феноменом «эффект съезда с тротуара» (Curb cut effect). Его суть показалась мне интересной, чтобы написать и поделиться своими мыслями в виде поста.

Представьте проезжую часть и тротуар с бордюром вдоль неё. В некоторых местах есть съезды: бордюр спущен на уровень проезжей части, а сам тротуар немного наклонён. Это сделано для устранения барьеров людям на инвалидных колясках.

Но также это помогает людям с детской коляской, сумкой на колёсиках, тележкой, велосипедом, самокатом, скейтбордом и другими средствами личной мобильности или вещами с колёсами. Ещё это помогает пожилым людям.

Эффект съезда с тротуара — это социально-экономический феномен, суть которого в том, что решения, изначально созданные для узкой группы людей, в конечном итоге оказываются полезными и эффективными для более широкой группы.

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

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

Вот несколько примеров:

- Хороший шрифт с достаточным размером и контрастными цветами улучшает читабельность сайта, пользователям удобнее читать;
- Субтитры позволят пользователям смотреть видео без звука и читать субтитры в шумном помещении, если нет наушников;
- Достаточно большие интерактивные элементы легче нажимать пальцами или стилусом на смартфоне или планшете с сенсорным экраном;
- Подписи, подсказки и автодополнение у полей ввода помогут пользователям быстрее заполнять формы с меньшим количеством ошибок;
- Хорошо размеченная с помощью семантического HTML страница более понятна поисковым работам, агентам, лучше разбирается в режиме чтения;
- Текстовая расшифровка видео позволяет использовать поиск по тексту, переводить его на другой язык и копировать для различных целей;
- Правильно заданный язык страницы и элементов помогает программе-переводчику определить язык и предложить перевод.

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

#a11y


CSS Linked Parameters

При использовании встроенных SVG-иконок в HTML удобно то, что к ним есть доступ в CSS. Можно, например, изменять цвета, скрывать отдельные части иконки, менять толщину линий, радиус окружности, применять анимации и так далее.





Назад


a {
color: var(--color-link);
transition: color .3s linear;

svg path {
fill: currentColor;
transition: fill .3s linear;
}
}

a:hover {
color: var(--color-link-hover);
}


Однако при использовании внешних SVG-иконок доступ в CSS теряется. Отчасти это можно обойти через SVG-спрайты, но у них есть свои нюансы. CSSWG выпустила черновик CSS Linked Parameters, который предлагает решение проблемы.

Суть предложения в том, чтобы передавать через URL специальные параметры и затем получать к ним доступ через переменные окружения в атрибутах и CSS. Так можно будет передать цвет во внешний SVG-файл, подключаемый через или url().

Дисклеймер: это обзор раннего предложения новых функций. Синтаксис может измениться в будущем или от функций могут отказаться







img {
/*
Параметры можно задать в CSS
с помощью link-parameters.
Это добавит к src и
ссылкам на все ресурсы
#param(--color,green)
*/
link-parameters:
param(--color, green)
;
}

.icon {
/*
Параметры можно задать
в функции url() в CSS
*/
background-image:
url(
"icon.svg",
param(--color, green)
)
;
}












path {
fill: env(--color, black);
}




Можно передавать несколько параметров, перечислив их в URL через &, указав несколько param() через пробел в url() или через запятую в link-parameters. В качестве значения могут быть пользовательские свойства CSS.






img {
/*
несколько param() в link-parameters,
доступны пользовательские свойства
*/
link-parameters:
param(--color, var(--color-primary)),
param(--stroke, 1)
;
}

.icon {
/*
несколько param() в url(),
доступны пользовательские свойства
*/
background-image:
url(
"icon.svg",
param(--color, var(--color-primary))
param(--stroke, 1)
)
;
}


Таким образом появляется возможность передавать данные во внешние файлы. Основное назначение — , но также упоминается возможность передачи для . Синтаксис фрагментов используется для обратной совместимости.

#html #svg #css


Отсутствующие подписи для полей

Более половины сайтов (51%) по данным отчёта WebAIM Million 2026 содержат поля ввода без подписей. У полей нет имени и нельзя идентифицировать какие данные необходимо ввести. Это одна из 6 самых частых ошибок в WAVE.

Исправить эту ошибку не сложно. Нужно указать подпись (имя) одним из способов. Порядок отражает приоритет применения:

- aria-labelledby
- aria-label
-
- title
- placeholder
- aria-placeholder

Лучше всего указывать видимые подписи в и связывать их с полями через for и id. Или оборачивать в с подписью внутри. Эти варианты не требуют ARIA, что соответствует первому правилу. Поэтому они предпочтительны.


Имя (обязательно)




Имя (обязательно)



Атрибут title использовать не стоит. Он задаёт имя полю, но также создаёт системную всплывающую подсказку. Эта подсказка не соответствует требованиям доступности по критериям 1.4.4, 1.4.10, 1. 4.12, 1.4.13.

Иногда дизайнеры рисуют подпись внутри поля и это выглядит как заполнитель. В таком случае разработчик может указать атрибут placeholder. Хотя он задаёт имя полю, он предназначен не для этого. Используйте атрибут по назначению.

Когда подпись находится внутри поля, можно прибегнуть к технике плавающих подписей. Это когда при фокусе на поле, подпись подъезжает вверх и остаётся видимой. Техника не лишена проблем, но это лучше, чем подпись в placeholder.

aria-label можно применить для быстрого исправления отсутствующей подписи, но она не будет видна визуально. Это нарушает один из критериев WCAG и ухудшает доступность. Поэтому лучше избегать aria-label для подписей.

aria-labelledby работает как , но наоборот: поле ссылается по id на элемент, который действует как подпись. Такой способ подойдёт для нестандартных полей ввода или если нет возможности добавить в разметку.

Что касается критериев, применимых к подписям, то их пять:

- 1.3.1 Info and Relationship — подпись должна быть программно связана с полем, а её визуальная информация программно обозначена;
- 2.4.6 Headings and Labels — подпись, если она есть, должна быть понятной и описательной;
- 2.5.3 Label in Name — видимая подпись должна полностью или частично соответствовать программно заданному имени поля;
- 3.3.2 Labels or Instructions — у полей должна быть видимая подпись или инструкция для обозначения требуемой информации;
- 4.1.2 Name, Role, Value — у поля должно быть программно заданное имя.

Вариант с соответствует всем критериям, поэтому он предпочтительный. Всем критериям будет соответствовать вариант с aria-labelledby, ссылаясь на элемент с видимым описательным текстом. Это резервный вариант.


Имя (обязательно)




Имя (обязательно)


#html #a11y


Prop for that

Адам Аргайл выпустил небольшую JS-библиотеку prop-for-that, которая следит за различными параметрами страницы и записывает значения в пользовательские свойства CSS. Это позволяет писать стили на основе значений этих свойств.

Что библиотека может отслеживать:

- Положение курсора (x, y) в px и % от области просмотра;
- Размер области просмотра;
- Текущее время (часы, минуты, секунды, текущий timestamp);
- Количество кадров в секунду;
- Онлайн-статус;
- Состояние видимости и фокусировки страницы;
- Параметры сети (тип, downlink, rtt, режим экономии данных);
- Состояние батареи (процент заряда, заряжается ли);
- Нагрузку на CPU;
- Прокрутку (направление и скорость);
- Визуальную область просмотра (pinch-zoom, отображение виртуальной клавиатуры);
- Виртуальную клавиатуру (открыта ли, размеры, координаты);
- Ориентацию устройства;
- Параметры акселерометра;
- Геолокацию;
- Плотность пикселей экрана;
- Количество ядер процессора;
- Доступный объём оперативной памяти;
- Ширину полосы прокрутки;
- Тип навигации;
- Мета-данные (theme-color, og-image, color-scheme);
- Размеры элемента;
- Видимость элемента;
- Значение ;
- Свойства текстовых полей (длина, пустое ли, валидное ли, лимит символов);
- Состояние валидности полей ввода;
- Состояния полей («чистое», «грязное», тронутое, нетронутое, изменённое, отправленное);
- Количество полей (валидных, не валидных, заполненных);
- Состояния (индекс, количество опций, количество выбранных опций, текущее значение);
- Цвет из ;
- Состояния и (прогресс, текущее время, длительность, пауза, громкость);
- Состояния (физические размеры, загружено ли, ошибка загрузки);
- Цвета (доминантный, акцентный, тёмный, светлый, средний, температура);
- Цвета (доминантный, акцентный);
- Состояние урезанного текста (line-clamp).

Достаточно большой список. Плюс к этому есть JS API и система плагинов, поэтому библиотеку можно расширять. Некоторые свойства глобальные, как состояние сети, процессора или батареи. Такие свойства записываются в :root.

Другие свойства работают на уровне элементов. Чтобы библиотека отслеживала свойства, нужно указать атрибут data-props-for у элемента и перечислить через запятую названия отслеживаемых свойств. По умолчанию ничего не отслеживается.




.box::after {
counter-reset: w calc(var(--live-w)) h calc(var(--live-h));
content: counter(w) ' × ' counter(h);
}


В примере указано, что нужно отслеживать размеры (data-props-for="size"). В CSS будут доступны свойства --live-w и --live-h с актуальными значениями. Для примера они выводятся в элементе с помощью счётчиков.

В документации много примеров, где и как это можно применить. Особенно хорошо это работает в сочетании с Container Style Queries и функцией if(), позволяя делать динамическую стилизацию на основе значений свойств.

Счётчики и псевдо-элементы со свойством content можно использовать для вывода значений в интерфейсе. Также можно скрывать или показывать отдельные узлы по условию. В общем, фантазии хватает как это можно применить.

#css #js

Показано 20 последних публикаций.