Пользовательские атрибуты
В HTML есть набор глобальных атрибутов. Например
Некоторые атрибуты специфичны для конкретных элементов. Например
Стандарт ARIA предлагает набор атрибутов с префиксом
Когда стандартных атрибутов не хватает, разработчики могут безопасно применять пользовательские атрибуты с префиксом
Некоторые разработчики и авторы библиотек пренебрегают префиксом
При разработке Popover API планировали добавить атрибут
Если вы автор библиотеки или просто хотите использовать пользовательский атрибут — добавьте префикс
Или используйте пользовательские элементы. Их особенность в том, что нет ограничений на имена атрибутов, поэтому можно валидно и не нарушая стандарт задавать любые. Главное помнить о глобальных атрибутах и ARIA.
#html
В HTML есть набор глобальных атрибутов. Например
class, id, lang, dir, hidden, translate и так далее. Полный список можно посмотреть в спецификации. Эти атрибуты можно указывать у любых элементов.Некоторые атрибуты специфичны для конкретных элементов. Например
type и value у <input> или scope и colspan у <th>. У таких атрибутов бывают правила использования в сочетании с другими атрибутами.Стандарт ARIA предлагает набор атрибутов с префиксом
aria-* и атрибут role для создания более доступных сайтов. У них есть правила использования и ограничения. В целом их можно отнести к глобальным и задавать на любых элементах.Когда стандартных атрибутов не хватает, разработчики могут безопасно применять пользовательские атрибуты с префиксом
data-*. Кроме того, для работы с data-* атрибутами DOM API предлагает интерфейс dataset.Некоторые разработчики и авторы библиотек пренебрегают префиксом
data-*, аргументируя это лучшим DX. Отчасти это справедливо. С другой стороны, это нарушает стандарт и может привести к долгосрочным последствиям.При разработке Popover API планировали добавить атрибут
popup. Исследование показало, что достаточно много сайтов уже используют атрибут с таким названием, поэтому внедрение popup сломает сайты. В итоге атрибут назвали popover.Если вы автор библиотеки или просто хотите использовать пользовательский атрибут — добавьте префикс
data-*. 5 лишних символов не сильно испортят DX, но предотвратят возможные конфликты и облегчат жизнь авторам стандартов.Или используйте пользовательские элементы. Их особенность в том, что нет ограничений на имена атрибутов, поэтому можно валидно и не нарушая стандарт задавать любые. Главное помнить о глобальных атрибутах и ARIA.
#html
👍12🌚2
Анализ производительности сайта Йоркширской воздушной скорой помощи
Гарри Робертс поделился видео с анализом производительности сайта Йоркширской воздушной скорой помощи. За 40 с лишним минут, с помощью DevTools и других инструментов Гарри идентифицировал основные проблемы и дал рекомендации по исправлению.
Хотя видео, по большей части, — реклама услуг, всё же показывает процесс анализа производительности с помощью разных инструментов и мышление при идентификации проблем и способов их решения.
#performance
Гарри Робертс поделился видео с анализом производительности сайта Йоркширской воздушной скорой помощи. За 40 с лишним минут, с помощью DevTools и других инструментов Гарри идентифицировал основные проблемы и дал рекомендации по исправлению.
Хотя видео, по большей части, — реклама услуг, всё же показывает процесс анализа производительности с помощью разных инструментов и мышление при идентификации проблем и способов их решения.
#performance
YouTube
Yorkshire Air Ambulance Site-Speed Optimisation
Book your own audit here: https://csswizardry.com/performance-audits/#fix-it-fast
00:00 Intro
01:55 CruX data
04:51 Time to First Byte
05:48 Caching
09:58 Back–Forward Cache (bfcache)
11:00 Speculation Rules
15:14 Individual URL analysis
16:13 Homepage
17:07…
00:00 Intro
01:55 CruX data
04:51 Time to First Byte
05:48 Caching
09:58 Back–Forward Cache (bfcache)
11:00 Speculation Rules
15:14 Individual URL analysis
16:13 Homepage
17:07…
👍12
Семантический HTML и TypeScript
Казалось бы, что может быть общего у семантического HTML и TypeScript? Просматривая один из докладов, услышал интересную аналогию.
Есть TypeScript, который расширяет JS синтаксисом описания типов. Разработчики дают определённым структурам данных «названия», отмечая, что это не случайные данные, а «пользователь», «заказ» или «позиция в корзине».
Грамотная типизация данных даёт ряд преимуществ:
- Понятное назначение данных при чтении кода;
- Всплывающие подсказки в IDE;
- Генерация схем и типов для других сервисов и языков;
- Генерация документации с сигнатурами;
- Предотвращение некоторых ошибок на этапе разработки.
То есть разные потребители (IDE, библиотеки, сборщики, компиляторы, линтеры, скрипты) извлекают из типов полезную для себя информацию и что-то на её основе делают.
В TypeScript есть конструкция, наличие которой в коде считается плохой практикой — тип
Аналогия с семантическим HTML такая:
Разные потребители (поисковые роботы, режимы чтения, браузерные расширения, средства доступности, парсеры) не извлекут для себя полезную информацию, которую извлекли бы при наличии семантических элементов.
Разница в том, что типы TypeScript более конкретные, в то время как семантика HTML-элементов достаточно абстрактная. Но даже из этого можно извлечь пользу. Есть способы дополнить HTML «типами», но об этом в другой раз.
Это не значит, что нужно заменять любые
#html
Казалось бы, что может быть общего у семантического HTML и TypeScript? Просматривая один из докладов, услышал интересную аналогию.
Есть TypeScript, который расширяет JS синтаксисом описания типов. Разработчики дают определённым структурам данных «названия», отмечая, что это не случайные данные, а «пользователь», «заказ» или «позиция в корзине».
Грамотная типизация данных даёт ряд преимуществ:
- Понятное назначение данных при чтении кода;
- Всплывающие подсказки в IDE;
- Генерация схем и типов для других сервисов и языков;
- Генерация документации с сигнатурами;
- Предотвращение некоторых ошибок на этапе разработки.
То есть разные потребители (IDE, библиотеки, сборщики, компиляторы, линтеры, скрипты) извлекают из типов полезную для себя информацию и что-то на её основе делают.
В TypeScript есть конструкция, наличие которой в коде считается плохой практикой — тип
any. Он нужен в некоторых ситуациях, но в основном его использование сводит преимущества TypeScript на нет.Аналогия с семантическим HTML такая:
<div> и <span> в HTML аналогичны any в TypeScript. Если использовать только эти элементы для разметки всего на странице, то получится ничего не значащий, не «типизированный» контент.Разные потребители (поисковые роботы, режимы чтения, браузерные расширения, средства доступности, парсеры) не извлекут для себя полезную информацию, которую извлекли бы при наличии семантических элементов.
Разница в том, что типы TypeScript более конкретные, в то время как семантика HTML-элементов достаточно абстрактная. Но даже из этого можно извлечь пользу. Есть способы дополнить HTML «типами», но об этом в другой раз.
Это не значит, что нужно заменять любые
<div> и <span> чем-то другим. У этих элементов есть назначение, в рамках которого они уместны. Но не стоит использовать только их при наличии подходящих альтернатив.#html
💯14✍4❤4👍2
Автоматизация тестирования доступности
При работе с доступностью хочется всё автоматизировать: обнаружение проблем, классификацию, построение отчётов, постановку задач, отслеживание прогресса и изменений. Понятное и естественное желание.
По разным оценкам текущие инструменты автоматического тестирования доступности способны обнаружить 30-50% проблем. Речь о таких инструментах, как Lighthouse, Axe, WAVE и других. По моим личным ощущениям эта цифра в районе 20-30%.
Текущие инструменты, в основном, проверяют разметку на соответствие определённым правилам. Например, у
Инструменты не проверяют, осмысленный ли
Стив Фолкнер составил список критериев WCAG с пометками, что можно проверить с помощью автоматизации, а что нет. Почти все критерии автоматизируются лишь частично, многое нужно проверять вручную. Подобное также делал Карл Грувс.
Потому что в доступности многое завязано на смыслы, намерения, удобство и пользовательский опыт. Это то, что можно проверить только вручную. В теории инструменты на базе нейросетей могли бы увеличить покрытие, нужно дождаться появления таких.
Можно создать недоступный сайт и получить 100 баллов доступности в Lighthouse и 0 ошибок в Axe. Нет специальных элементов и атрибутов — нет ошибок. Сегодня ни один инструмент не в состоянии автоматически проверить соответсвие WCAG и выдать отчёт.
#a11y
При работе с доступностью хочется всё автоматизировать: обнаружение проблем, классификацию, построение отчётов, постановку задач, отслеживание прогресса и изменений. Понятное и естественное желание.
По разным оценкам текущие инструменты автоматического тестирования доступности способны обнаружить 30-50% проблем. Речь о таких инструментах, как Lighthouse, Axe, WAVE и других. По моим личным ощущениям эта цифра в районе 20-30%.
Текущие инструменты, в основном, проверяют разметку на соответствие определённым правилам. Например, у
<img> должен быть атрибут alt, aria-label должен использоваться только у элементов с определёнными ролями, и так далее.Инструменты не проверяют, осмысленный ли
alt у изображения, соответствует ли значение aria-label цели элемента, совпадает ли видимый порядок контента тому, что определён в разметке, правильно ли структурирована страница и другие подобные моменты.Стив Фолкнер составил список критериев WCAG с пометками, что можно проверить с помощью автоматизации, а что нет. Почти все критерии автоматизируются лишь частично, многое нужно проверять вручную. Подобное также делал Карл Грувс.
Потому что в доступности многое завязано на смыслы, намерения, удобство и пользовательский опыт. Это то, что можно проверить только вручную. В теории инструменты на базе нейросетей могли бы увеличить покрытие, нужно дождаться появления таких.
Можно создать недоступный сайт и получить 100 баллов доступности в Lighthouse и 0 ошибок в Axe. Нет специальных элементов и атрибутов — нет ошибок. Сегодня ни один инструмент не в состоянии автоматически проверить соответсвие WCAG и выдать отчёт.
#a11y
Adrian Roselli
Automated WCAG Testing Is Grrreat!
I’m a big fan of using automation in WCAG testing. I use bookmarklets, dev tools, browser features & reporting, and a pile of third-party products from assorted vendors. These save me time and effort, letting me focus on more tricky cases. But… Unfortunately…
1👍7❤2😢1
Возможности гиперссылок
У элемента
-
-
-
-
-
-
-
-
-
Также не стоит забывать о схемах, которые можно использовать в
#html
У элемента
<a> есть несколько особенностей, связанных с атрибутом href. Они помогают в некоторых ситуациях обойтись без JS и решить задачу нативным способом. Джим Нильсен поделился этими особенностями.-
<a href="#"> — прокручивает страницу к верхней части, что можно использовать для создания плавающей кнопки «наверх»;-
<a href="#top"> — так же прокручивает страницу к верхней части, если нет элементов с id="top";-
<a href="doc.pdf#page42"> — при просмотре PDF через браузер открывает 42-ю страницу, если она есть;-
<a href=""> — перезагружает текущую страницу, сохраняя параметры, но удаляя идентификатор фрагмента (example.com?foo=bar#baz →example.com?foo=bar);-
<a href="."> — перезагружает страницу, удаляя параметры и идентификатор фрагмента, но нужно помнить про слэш в конце пути (example.com?foo=bar#baz →example.com);-
<a href="?"> — перезагружает страницу, удаляя параметры и идентификатор фрагмента, но оставляет символ ? (example.com?foo=bar#baz →example.com?);-
<a href="data:text/plain,Hello"> — перенаправляет на страницу с текстом Hello или другими данными в зависимости от указанного типа. Можно использовать для встраивания небольшого объёма данных;-
<a href="video.mp4#t=10,20"> — при обращении к аудио или видео через браузер, перематывает плеер на 10-ю секунду и останавливает воспроизведение на 20-й секунде;-
<a href="#:~:text=foo"> — перенаправляет на страницу, прокручивает к первому вхождению текста foo и подсвечивает его.Также не стоит забывать о схемах, которые можно использовать в
href: tel:, mailto:, sms:, javanoscript: и пользовательских обработчиках схем, создаваемых через registerProtocolHandler().#html
Jim Nielsen’s Blog
A Few Things About the Anchor Element’s href You Might Not Have Known
I’ve written previously about reloading a document using only HTML but that got me thinking: What are all the values you can put in an anchor tag’s href attribute?
🔥25🤝8❤3🤔1
Старые технологии и производительность
В октябре прошлого года Уэс Босс записал видео о сайте частной американской компании McMasters-Carr, которая занимается поставками оборудования, инструментов, запчастей и сырья для технического обслуживания.
Первое впечатление при посещении сайта — старый легаси-проект. Но он работает и выполняет свою задачу. И, что самое интересное, сайт очень быстрый. Страницы загружаются и отображаются практически мгновенно.
Команда разработчиков хорошо оптимизировала сайт. Разметка генерируется на сервере. При наведении на ссылки страницы предварительно загружаются. Используется Service Wokrer для кэширования и CDN для эффективной доставки.
Применяется техника критического CSS, который встраивается прямо на страницу. JS разделяется по страницам и загружается только там, где нужно. Подход App Shell позволяет перерисовывать только основную часть страницы.
Ещё интереснее стек: ASP.NET, YUI (Yahoo UI Library) и jQuery, то есть устаревшие по современным меркам технологии. И это не мешает сайту работать быстро и эффективно. Всё дело в том, как используются эти технологии.
Этот сайт — хорошее дополнение к докладу Алексея Симоненко о том, что важен продукт, а не технологии. Правильный подход и понимание техник оптимизации позволяют создавать производительный сайт даже на старых технологиях.
#performance
В октябре прошлого года Уэс Босс записал видео о сайте частной американской компании McMasters-Carr, которая занимается поставками оборудования, инструментов, запчастей и сырья для технического обслуживания.
Первое впечатление при посещении сайта — старый легаси-проект. Но он работает и выполняет свою задачу. И, что самое интересное, сайт очень быстрый. Страницы загружаются и отображаются практически мгновенно.
Команда разработчиков хорошо оптимизировала сайт. Разметка генерируется на сервере. При наведении на ссылки страницы предварительно загружаются. Используется Service Wokrer для кэширования и CDN для эффективной доставки.
Применяется техника критического CSS, который встраивается прямо на страницу. JS разделяется по страницам и загружается только там, где нужно. Подход App Shell позволяет перерисовывать только основную часть страницы.
Ещё интереснее стек: ASP.NET, YUI (Yahoo UI Library) и jQuery, то есть устаревшие по современным меркам технологии. И это не мешает сайту работать быстро и эффективно. Всё дело в том, как используются эти технологии.
Этот сайт — хорошее дополнение к докладу Алексея Симоненко о том, что важен продукт, а не технологии. Правильный подход и понимание техник оптимизации позволяют создавать производительный сайт даже на старых технологиях.
#performance
YouTube
How is this Website so fast!?
Breaking down the McMaster Carr website and the techniques they use to make it so dang fast.
00:00 - Intro
00:38 - Server Rendered HTML
00:54 - Prefetching HTML
02:02 - CDN Caching
02:36 - Client Caching with Service Worker
03:29 - Preloading Assets
05:33…
00:00 - Intro
00:38 - Server Rendered HTML
00:54 - Prefetching HTML
02:02 - CDN Caching
02:36 - Client Caching with Service Worker
03:29 - Preloading Assets
05:33…
👍10❤5👎1
Идеальных контрольных точек не существует
С момента первых свёрстанных макетов меня беспокоит тема контрольных точек (брейкпоинтов) для медиа-запросов. Какие значения использовать? По какому принципу их выбирать? Сколько их должно быть?
Наиболее популярна система контрольных точек Bootstrap: 576-768-922-1200-1400. Я придерживаюсь вариации системы 600-900-1200-1800 из статьи «The 100% correct way to do CSS breakpoints» Дэвида Гилбертсона, она показалась мне более логичной.
Предустановленная тема Dawn в магазинах на платформе Shopify использует систему 749/750-989/990 и двумя дополнительными контрольными точками: 650 и 1200. В интернете есть статьи и видео, где люди делятся собственными подходами.
Так какую же систему выбрать? В Set Studio пришли к выводу: идеальных контрольных точек не существует. В рамках эксперимента было собрано более 120000 источников, из которых получилось более 2300 уникальных размеров экранов.
Ни одна система контрольных точек не покроет такое количество экранов. Всё потому что в современном мире сайт может быть открыт везде, где есть браузер. А браузер сейчас есть даже там, где его не ожидаешь увидеть.
К этому добавляется огромное разнообразие моделей мониторов, ноутбуков, планшетов, смартфонов и часов. Плюс разные режимы отображения: разделённый экран, предпросмотр ссылок, увеличенный масштаб, упрощённый режим, Picture-in-Picture.
Этот факт подводит к мысли об отказе от контрольных точек для медиа-запросов. Пусть
А вместо контрольных точек применить «алгоритмическую вёрстку» — описание в CSS некоторых правил (алгоритмов), по которым браузер сам решает, как размещать и отображать элементы. Подробнее об этом расскажу в отдельном посте.
#css
С момента первых свёрстанных макетов меня беспокоит тема контрольных точек (брейкпоинтов) для медиа-запросов. Какие значения использовать? По какому принципу их выбирать? Сколько их должно быть?
Наиболее популярна система контрольных точек Bootstrap: 576-768-922-1200-1400. Я придерживаюсь вариации системы 600-900-1200-1800 из статьи «The 100% correct way to do CSS breakpoints» Дэвида Гилбертсона, она показалась мне более логичной.
Предустановленная тема Dawn в магазинах на платформе Shopify использует систему 749/750-989/990 и двумя дополнительными контрольными точками: 650 и 1200. В интернете есть статьи и видео, где люди делятся собственными подходами.
Так какую же систему выбрать? В Set Studio пришли к выводу: идеальных контрольных точек не существует. В рамках эксперимента было собрано более 120000 источников, из которых получилось более 2300 уникальных размеров экранов.
Ни одна система контрольных точек не покроет такое количество экранов. Всё потому что в современном мире сайт может быть открыт везде, где есть браузер. А браузер сейчас есть даже там, где его не ожидаешь увидеть.
К этому добавляется огромное разнообразие моделей мониторов, ноутбуков, планшетов, смартфонов и часов. Плюс разные режимы отображения: разделённый экран, предпросмотр ссылок, увеличенный масштаб, упрощённый режим, Picture-in-Picture.
Этот факт подводит к мысли об отказе от контрольных точек для медиа-запросов. Пусть
@media используется по прямому назначению — определению медиа-функций prefers-*, print, pointer, forced-colors, orientation, color-gamut и других. А вместо контрольных точек применить «алгоритмическую вёрстку» — описание в CSS некоторых правил (алгоритмов), по которым браузер сам решает, как размещать и отображать элементы. Подробнее об этом расскажу в отдельном посте.
#css
viewports.fyi
The ideal viewport doesn’t exist
Before you settle on basing design decisions on a handful of strict breakpoints, make sure you consider the vast fragmentation of screen sizes and browser viewports.
1❤16👍6🔥3
Алгоритмическая вёрстка
Рассуждая на тему того, что идеальных контрольных точек не существует, я подвёл к мысли об отказе от контрольных точек в пользу алгоритмической вёрстки. В этом посте подробнее расскажу что это такое.
Суть алгоритмической вёрстки в том, чтобы вместо медиа-запросов с контрольными точками указывать правила (алгоритмы), по которым браузер сам принимает решение о размещении элементов в зависимости от условий.
Хейдон Пикеринг в своём видео Making Future Interfaces: Algorithmic Layouts демонстрирует суть на примере макета с боковой колонкой. Позже идея получила развитие в книге Every Layout за авторством Хейдона и Энди Бэлла.
Предположим, что нужно создать сетку с карточками товаров. На широких экранах карточки должны отображаться в несколько колонок. Чем у́же экран, тем меньше колонок. Классический подход — использовать grid и медиа-запросы:
Получается многословно, а значения контрольных точек жёстко заданы. Этот код можно сделать компактнее, используя вложенность, функцию
Вместо изменения количества колонок в контрольных точках можно задать алгоритм построения сетки с автоматическими колонками из элементов, ширина которых ограничена минимальным значением:
Браузер получает алгоритм: «автоматически создавай колонку, если в неё помещается элемент шириной от
Отступы, поля, размеры шрифта, закругления тоже можно описать в виде алгоритма c использованием функций
Алгоритм для браузера: «рассчитай размер шрифта на основе текущей ширины области просмотра и размера шрифта корневого элемента, но не менее
Больше примеров алгоритмической вёрстки:
- 1-Line Layouts
- SmolCSS
- Container Query Solutions with CSS Grid and Flexbox
- Modern Fluid Typography Using CSS Clamp
- Utopia Fluid Responsive Design
- Every Layout
#css
Рассуждая на тему того, что идеальных контрольных точек не существует, я подвёл к мысли об отказе от контрольных точек в пользу алгоритмической вёрстки. В этом посте подробнее расскажу что это такое.
Суть алгоритмической вёрстки в том, чтобы вместо медиа-запросов с контрольными точками указывать правила (алгоритмы), по которым браузер сам принимает решение о размещении элементов в зависимости от условий.
Хейдон Пикеринг в своём видео Making Future Interfaces: Algorithmic Layouts демонстрирует суть на примере макета с боковой колонкой. Позже идея получила развитие в книге Every Layout за авторством Хейдона и Энди Бэлла.
Предположим, что нужно создать сетку с карточками товаров. На широких экранах карточки должны отображаться в несколько колонок. Чем у́же экран, тем меньше колонок. Классический подход — использовать grid и медиа-запросы:
.product-grid {
display: grid;
grid-template-columns: 1fr;
gap: 30px;
}
@media (width > 600px) {
.product-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (width > 900px) {
.product-grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (width > 1400px) {
.product-grid {
grid-template-columns: repeat(4, 1fr);
}
}
Получается многословно, а значения контрольных точек жёстко заданы. Этот код можно сделать компактнее, используя вложенность, функцию
if() и пользовательские свойства. Но проверка контрольных точек всё равно останется:.product-grid {
--columns: if(
media(width > 1400px): 4;
media(width > 900px): 3;
media(width > 600px): 2;
);
display: grid;
grid-template-columns: repeat(var(--columns, 1), 1fr);
gap: 30px;
}Вместо изменения количества колонок в контрольных точках можно задать алгоритм построения сетки с автоматическими колонками из элементов, ширина которых ограничена минимальным значением:
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 30px;
}Браузер получает алгоритм: «автоматически создавай колонку, если в неё помещается элемент шириной от
200px до одной доли доступного пространства, остальные элементы переноси на новую строку».Отступы, поля, размеры шрифта, закругления тоже можно описать в виде алгоритма c использованием функций
calc(), min(), max(), clamp(). На этом, в частности, основана «гибкая типографика» (fluid typography):.noscript {
font-size: clamp(2rem, 4vw + 1rem, 3rem);
}Алгоритм для браузера: «рассчитай размер шрифта на основе текущей ширины области просмотра и размера шрифта корневого элемента, но не менее
2rem и не более 3rem». Размер шрифта будет меняться в зависимости от ширины экрана.Больше примеров алгоритмической вёрстки:
- 1-Line Layouts
- SmolCSS
- Container Query Solutions with CSS Grid and Flexbox
- Modern Fluid Typography Using CSS Clamp
- Utopia Fluid Responsive Design
- Every Layout
#css
YouTube
Making Future Interfaces: Algorithmic Layouts
Learn how to create CSS layouts that are self-governing, using Flexbox and Grid.
*IMPORTANT:* The code at 4.02 is incomplete. You need to add `flex-basis: 0` to the `.not-sidebar` element. Combined with `flex-grow: 666` this essentially means "grow from…
*IMPORTANT:* The code at 4.02 is incomplete. You need to add `flex-basis: 0` to the `.not-sidebar` element. Combined with `flex-grow: 666` this essentially means "grow from…
🔥23✍6🗿5👍3❤1🤔1🤡1
Obs.js
Гарри Робертс поделился коротким видео, в котором рассказал о разработке библиотеки с открытым исходным кодом Obs.js. Слоган библиотеки — контекстно-зависимая производительность для всех.
Obs.js подключается к странице и использует различные API для определения текущих возможностей устройства: качество соединения, сетевую задержку, состояние батареи, заряжается ли устройство, доступную память и CPU.
В результате объект
Если у пользователя слабое соединение, мало батареи или включен режим экономии трафика, можно загружать картинки худшего качества, не загружать видео, уменьшить количество анимации и скрыть некоторые блоки.
Подход Obs.js похож на некогда популярную библиотеку Modernizr, но направлен на определение функций производительности. Есть демо-страница, на которой можно проверить своё устройство.
#js #performance
Гарри Робертс поделился коротким видео, в котором рассказал о разработке библиотеки с открытым исходным кодом Obs.js. Слоган библиотеки — контекстно-зависимая производительность для всех.
Context-aware web performance for everyone
Obs.js подключается к странице и использует различные API для определения текущих возможностей устройства: качество соединения, сетевую задержку, состояние батареи, заряжается ли устройство, доступную память и CPU.
В результате объект
window.obs заполняется соответствующей информацией, а на <html> добавляются классы вида .has-bandwidth-high, .has-battery-charging, .has-cpu-high, .has-latency-medium и другие.Если у пользователя слабое соединение, мало батареи или включен режим экономии трафика, можно загружать картинки худшего качества, не загружать видео, уменьшить количество анимации и скрыть некоторые блоки.
Подход Obs.js похож на некогда популярную библиотеку Modernizr, но направлен на определение функций производительности. Есть демо-страница, на которой можно проверить своё устройство.
#js #performance
YouTube
Obs.js Preview – Adapt to user context
By tapping into the Navigator and Battery APIs, we can write CSS and JS that adapts to our users’ contexts. Low bandwidth? Send smaller images! Battery running low? Disable animations!
👉 Demo: https://csswizardry.com/Obs.js/demo/
In this video, I take a…
👉 Demo: https://csswizardry.com/Obs.js/demo/
In this video, I take a…
👍13🔥5❤2💩1
День знаний
Так как в этом году 1е сентября (день знаний) выпало на понедельник, предлагаю подборку бесплатных материалов для изучения веб-разработки. Материалы ориентированы на новичков, но и старожилам может быть полезно освежить знания и узнать что-то новое.
- Learn web development от MDN. Структурированный набор обучающих материалов по основам веб-разработки от команды MDN. Не так давно MDN получил обновлённый дизайн с улучшенной типографикой, блоками кода, иконками, поиском и навигацией;
- Learn web development от web.dev. Набор небольших курсов по HTML, CSS, JS, производительности, приватности, доступности, изображениям, дизайну, формам, PWA и тестированию от web.dev и команды деврелов Chrome;
- Дока. Дружелюбный справочник по веб-разработке, создаваемый силами сообщества;
Игровой формат:
- CSS Diner. Игра, где с помощью CSS-селекторов необходимо выбрать нужные элементы на виртуальном столе;
- Flexbox Froggy. Игра, в которой с помощью Flexbox нужно помочь лягушкам добраться до своих лилий;
- Grid Garden. Игра, где нужно выращивать морковку, используя свойства CSS Grid.
- Anchoreum. Игра, обучающая работе с новым Anchor Positioning API, где нужно правильно разместить якоря.
Также напомню про подборку ссылок от Алекса Рассела на различные блоги, статьи и видео о веб-платформе, а также небольшую подборку материалов по доступности, которую я делал на 14й Всемирный День Информирования о Доступности.
#html #css #js
Так как в этом году 1е сентября (день знаний) выпало на понедельник, предлагаю подборку бесплатных материалов для изучения веб-разработки. Материалы ориентированы на новичков, но и старожилам может быть полезно освежить знания и узнать что-то новое.
- Learn web development от MDN. Структурированный набор обучающих материалов по основам веб-разработки от команды MDN. Не так давно MDN получил обновлённый дизайн с улучшенной типографикой, блоками кода, иконками, поиском и навигацией;
- Learn web development от web.dev. Набор небольших курсов по HTML, CSS, JS, производительности, приватности, доступности, изображениям, дизайну, формам, PWA и тестированию от web.dev и команды деврелов Chrome;
- Дока. Дружелюбный справочник по веб-разработке, создаваемый силами сообщества;
Игровой формат:
- CSS Diner. Игра, где с помощью CSS-селекторов необходимо выбрать нужные элементы на виртуальном столе;
- Flexbox Froggy. Игра, в которой с помощью Flexbox нужно помочь лягушкам добраться до своих лилий;
- Grid Garden. Игра, где нужно выращивать морковку, используя свойства CSS Grid.
- Anchoreum. Игра, обучающая работе с новым Anchor Positioning API, где нужно правильно разместить якоря.
Также напомню про подборку ссылок от Алекса Рассела на различные блоги, статьи и видео о веб-платформе, а также небольшую подборку материалов по доступности, которую я делал на 14й Всемирный День Информирования о Доступности.
#html #css #js
👍11❤6
You don’t know HTML: <label>
Элемент
Второй способ лучше подходит для флажков и радио-кнопок, так как расширяет интерактивную область и позволяет избежать не интерактивных зазоров между элементом и подписью. Второй способ также позволяет обойтись без
В обоих подходах элемент получит accessible name «Email». Программы чтения с экрана объявят имя при переходе к элементу. С помощью программ голосового управления можно обратиться к элементу по его имени.
Нажатие по
К одному элементу можно привязать несколько
Создавать комплексные подписи можно путём размещения всего текста внутри одного элемента
В JS у
У самих элементов управления есть свойство
#ydkhtml #html #a11y
Элемент
<label> представляет подпись для элементов управления, которые относятся к категории labelable element. Подпись идентифицирует элемент, кратко описывает назначение и используется как accessible name в дереве доступности.<label> ассоциируется с элементом двумя способами: через атрибут for с ссылкой по id и путём вкладывания элемента внутрь <label>. Во втором случае подпись ассоциируется с первым найденным элементом управления внутри <label>.<label for="email">
</label>
<input
type="email"
id="email"
autocomplete="email"
>
Второй способ лучше подходит для флажков и радио-кнопок, так как расширяет интерактивную область и позволяет избежать не интерактивных зазоров между элементом и подписью. Второй способ также позволяет обойтись без
id.<label>
<input
type="email"
id="email"
autocomplete="email"
>
</label>
В обоих подходах элемент получит accessible name «Email». Программы чтения с экрана объявят имя при переходе к элементу. С помощью программ голосового управления можно обратиться к элементу по его имени.
<label> переопределяет accessible name, полученный из атрибута noscript или текстового контента элемента, как в случае с кнопками. Атрибуты aria-label и aria-labelledby приоритетнее, поэтому они переопределяют значение из <label>.Нажатие по
<label> активирует связанный элемент. Для флажков и радио-кнопок — это изменение состояния отмечен/не отмечен, для текстовых полей — установка фокуса, для кнопки — нажатие, для выбора файла — активация окна выбора.К одному элементу можно привязать несколько
<label>, которые будут объединяться в единую подпись. Это можно использовать для комплексных подписей с дополнительными инструкциями, которые размещены в разных местах:<label for="birthday">
Дата рождения
</label>
<input
type="text"
id="birthday"
autocomplete="bday"
pattern="\d{2}\/\d{2}\/\d{4}"
>
<label for="birthday">
(формат: ДД/ММ/ГГГГ)
</label>
<!--
Accessible name:
Дата рождения (формат: ДД/ММ/ГГГГ)
-->
Создавать комплексные подписи можно путём размещения всего текста внутри одного элемента
<label>. Accessible name элемента управления будет генерироваться на основе всего текстового содержимого внутри <label>.<label>
<span>Дата рождения</span>
<input
type="text"
id="birthday"
autocomplete="bday"
pattern="\d{2}\/\d{2}\/\d{4}"
>
<small>(формат: ДД/ММ/ГГГГ)</small>
</label>
<!--
Accessible name:
Дата рождения (формат: ДД/ММ/ГГГГ)
-->
<label> можно привязывать к пользовательским элементам, если они помечены как ассоциированные с формой с помощью свойства formAssociated. Но <label> нельзя привязать к элементу внутри Shadow DOM (на данный момент).<label for="custom-checkbox">
Согласен получать спам
</label>
<custom-checkbox
id="custom-checkbox"
checked
>
</custom-checkbox>
<label for="custom-input">
Email для спама
</label>
<custom-input>
<template shadowrootmode="open">
<!-- подпись не привяжется -->
<input
type="email"
id="custom-input"
autocomplete="email"
>
</template>
</custom-input>
В JS у
<label> есть два свойства. control возвращает элемент, которому привязан <label>. Свойство form возвращает элемент <form>, к которому относится связанный с <label> элемент управления.У самих элементов управления есть свойство
labels, которое возвращает коллекцию NodeList со связанными элементами <label>. У пользовательских элементов такого свойства нет, но оно доступно через объект ElementInternals.#ydkhtml #html #a11y
👍19❤3
Вы неправильно загружаете шрифты
Джоно Олдерсон написал исчерпывающую статью «You’re loading fonts wrong (and it’s crippling your performance)» о шрифтах. От исторического экскурса до современных подходов. Советую прочитать статью полностью. Основные принципы кратко:
- Системный стек. Начните с хорошего набора системных шрифтов и используйте пользовательские шрифты как прогрессивное улучшение. Если брендинг не важен, рассмотрите использование только системных шрифтов;
- Нарезка на подмножества. Нарежьте монолитный файл шрифта на несколько подмножеств («бандлов») под разные языки и загружайте только те подмножества, которые нужны на странице;
- Предварительная загрузка и встраивание. Предоставьте браузеру информацию о критических шрифтах как можно раньше с помощью Early Hints,
- WOFF2. Используйте шрифты в современном формате
- SVG для иконок. Не используйте иконочные шрифты, такие как Font Awesome для добавления иконок. SVG поддерживается во всех браузерах, хорошо подходит для иконок и позволяет объединить их в один файл (спрайт);
- Вариативные шрифты. Используйте вариативные шрифты, если на сайте требуется тонкая настройка параметров (толщина, наклон, ширина) или используется много вариаций одного шрифта;
- Настройка резервных вариантов. Подберите настройки метрик для резервных шрифтов, чтобы внешне они максимально совпадали с пользовательским шрифтами во избежание прыжков макета при перерисовке;
- Глобальные сценарии. Учитывайте особенности и применяйте индивидуальные оптимизации для арабских языков, языков группы CJK, разных направлений написания и эмодзи;
- Тестирование. Проверяйте поведение и отображение шрифтов на различных устройствах, сетях и языках.
Шрифты — это не украшение, а часть инфраструктуры. Они находятся на критическом пути рендеринга, влияют на метрики LCP и CLS, представляют брендинг и влияют на то, смогут ли пользователи прочитать контент.
#css #performance
Джоно Олдерсон написал исчерпывающую статью «You’re loading fonts wrong (and it’s crippling your performance)» о шрифтах. От исторического экскурса до современных подходов. Советую прочитать статью полностью. Основные принципы кратко:
- Системный стек. Начните с хорошего набора системных шрифтов и используйте пользовательские шрифты как прогрессивное улучшение. Если брендинг не важен, рассмотрите использование только системных шрифтов;
- Нарезка на подмножества. Нарежьте монолитный файл шрифта на несколько подмножеств («бандлов») под разные языки и загружайте только те подмножества, которые нужны на странице;
- Предварительная загрузка и встраивание. Предоставьте браузеру информацию о критических шрифтах как можно раньше с помощью Early Hints,
<link rel="preload"> и встраивания @font-face в <style>;- WOFF2. Используйте шрифты в современном формате
woff2, не подключайте в @font-face форматы ttf, otf, eot, noscript. Если необходима поддержка старых браузеров, добавьте к woff2 шрифт в формате woff;- SVG для иконок. Не используйте иконочные шрифты, такие как Font Awesome для добавления иконок. SVG поддерживается во всех браузерах, хорошо подходит для иконок и позволяет объединить их в один файл (спрайт);
- Вариативные шрифты. Используйте вариативные шрифты, если на сайте требуется тонкая настройка параметров (толщина, наклон, ширина) или используется много вариаций одного шрифта;
- Настройка резервных вариантов. Подберите настройки метрик для резервных шрифтов, чтобы внешне они максимально совпадали с пользовательским шрифтами во избежание прыжков макета при перерисовке;
- Глобальные сценарии. Учитывайте особенности и применяйте индивидуальные оптимизации для арабских языков, языков группы CJK, разных направлений написания и эмодзи;
- Тестирование. Проверяйте поведение и отображение шрифтов на различных устройствах, сетях и языках.
Шрифты — это не украшение, а часть инфраструктуры. Они находятся на критическом пути рендеринга, влияют на метрики LCP и CLS, представляют брендинг и влияют на то, смогут ли пользователи прочитать контент.
#css #performance
Jono Alderson
You’re loading fonts wrong (and it’s crippling your performance)
Fonts are one of the most visible, most powerful parts of the web. And yet: almost everyone gets them wrong.
👍16❤3
Псевдо-кнопки
Марианна Минич пишет:
И сопровождается пост подобным примером:
Подобное периодически встречается в кодовых базах, когда разработчики задумываются о доступности или приходят соответствующие специалисты и просят исправить кнопки. Раз просят, нужно исправлять:
-
-
-
-
-
Эти манипуляции нужны, чтобы «исправить» кнопки и воспроизвести поведение
Поэтому просто используйте
Вместо написания лишнего JS для воспроизведения поведения у
Два CSS-свойства вместо десятков строк кода на JS и полотна из атрибутов в HTML (или директив в шаблоне компонента фреймворка), чтобы получить стилизуемую, семантическую, доступную кнопку со всеми её встроенными возможностями и API.
#html #css #a11y
Марианна Минич пишет:
На какие угодно ухищрения готовы пойти разработчики, лишь бы не использовать семантичную <button> 😅
И сопровождается пост подобным примером:
<div
tabindex="0"
role="button"
class="button"
(mouseenter)="onMouseEnter"
(mouseleave)="onMouseLeave"
(click)="onClick"
(keydown)="onKeyDown"
[attr.aria-pressed]="isPressed"
[attr.aria-label]="label"
...
>
...
</div>
Подобное периодически встречается в кодовых базах, когда разработчики задумываются о доступности или приходят соответствующие специалисты и просят исправить кнопки. Раз просят, нужно исправлять:
-
tabindex="0", чтобы не фокусируемый <div> попал в последовательность табуляции и стал доступен для клавиатуры;-
role="button", чтобы семантически нейтральный <div> попал в дерево доступности как кнопка и корректно обрабатывался вспомогательными технологиями;-
keydown, чтобы нажатия клавиш Enter и Space приводили к нажатию на <div> и вызову события click;-
aria-pressed, чтобы передавать в дерево доступности информацию о том, находится ли кнопка в нажатом состоянии;-
aria-label, чтобы задать кнопке имя для дерева доступности, которое переопределяет текстовый контент внутри (если его нет, как в случае с кнопками-иконками).Эти манипуляции нужны, чтобы «исправить» кнопки и воспроизвести поведение
<button> у <div>. Но это не всё: отправка, сброс и переопределение параметров формы, отключение, управление поповером и вызов команд — это то, что сегодня умеет <button>.Поэтому просто используйте
<button>! Причина создания псевдо-кнопок из <div> в стилизации. У <button> специфические стили, которые отличаются от браузера к браузеру. У <div> таких стилей нет и всё одинаково во всех браузерах.Вместо написания лишнего JS для воспроизведения поведения у
<div>, куда проще сделать сброс стилей у <button>, применив all: unset. Важно вернуть стандартную рамку фокуса (или реализовать свою), так как all: unset сбрасывает её:button {
all: unset;
}
button:focus-visible {
outline: auto;
}Два CSS-свойства вместо десятков строк кода на JS и полотна из атрибутов в HTML (или директив в шаблоне компонента фреймворка), чтобы получить стилизуемую, семантическую, доступную кнопку со всеми её встроенными возможностями и API.
#html #css #a11y
👍28❤10❤🔥2👏2🤡1
Современный CSS
Предлагаю запись доклада Адама Аргайла с прошедшего в апреле митапа Smashing Meets CSS. Адам рассказал о 33-х новых возможностях CSS. Практически каждая функция сопровождается демонстрациями на codepen, где можно изучить код и скопировать его в собственные проекты.
Ссылки на демонстрации доступны в презентации, которая работает в браузере и сама по себе использует многие функции CSS. Поэтому лучше всего смотреть презентацию и примеры в последней версии Chrome.
#css
Предлагаю запись доклада Адама Аргайла с прошедшего в апреле митапа Smashing Meets CSS. Адам рассказал о 33-х новых возможностях CSS. Практически каждая функция сопровождается демонстрациями на codepen, где можно изучить код и скопировать его в собственные проекты.
Ссылки на демонстрации доступны в презентации, которая работает в браузере и сама по себе использует многие функции CSS. Поэтому лучше всего смотреть презентацию и примеры в последней версии Chrome.
#css
YouTube
Can We Do That? with ADAM ARGYLE at Smashing Meets CSS - April 1, 2025
Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.
❤14👍7🌚1👾1
Меню без скриптов
Я уже писал о CSS-хаках и раскрывал эту тему на примере вкладок на основе ссылок и псевдо-класса :target. Продолжу разбором решения из статьи «меню для отзывчивого интерфейса без скриптов» с очередным хаком.
По вводному предложению можно подумать, что статья расскажет о новых Popover и Anchor Positioning, с помощью которых действительно можно создать меню только с помощью HTML и CSS. Но статья про старый добрый хак с флажком.
Таким меню невозможно воспользоваться с клавиатуры, так как флажок скрыт, а
В статье есть раздел про улучшение доступности. На
Добавлены роли
Добавления ARIA-атрибутов не сделало меню доступным. Флажок скрыт и недоступен для клавиатуры, программ чтения с экрана и голосового управления. Не передаётся состояние
Это плохое меню с точки зрения пользовательского опыта и доступности. Стоит ли погоня за реализацией «без JS» сломанного опыта для пользователей? Для меня ответ очевиден: не стоит. Хаки есть хаки, применять их в интерфейсах не стоит.
#html #css #a11y #ui
Я уже писал о CSS-хаках и раскрывал эту тему на примере вкладок на основе ссылок и псевдо-класса :target. Продолжу разбором решения из статьи «меню для отзывчивого интерфейса без скриптов» с очередным хаком.
В этом руководстве мы покажем, как сделать отзывчивое mobile-first меню только с помощью HTML и CSS.
По вводному предложению можно подумать, что статья расскажет о новых Popover и Anchor Positioning, с помощью которых действительно можно создать меню только с помощью HTML и CSS. Но статья про старый добрый хак с флажком.
<!-- Hamburger icon -->
<input class="side-menu" type="checkbox" id="side-menu"/>
<label class="hamb" for="side-menu"><span class="hamb-line"></span></label>
<!-- Menu -->
<nav class="nav">
<label> привязывается к скрытому флажку и меняет его состояние при нажатии. Псевдо-класс :checked позволяет отследить отмеченное состояние флажка и через комбинатор соседства ~ применить стили к нижележащему элементу <nav>..side-menu {
display: none;
} /* Hide checkbox */
/* Toggle menu icon */
.side-menu:checked ~ nav{
max-height: 100%;
}Таким меню невозможно воспользоваться с клавиатуры, так как флажок скрыт, а
<label> не фокусируемый. Можно скрыть флажок классом visually-hidden и добавить видимый индикатор фокуса, тогда меню можно будет открыть с клавиатуры.<label> не содержит текста, поэтому у флажка нет доступного имени. Пользователи программ чтения с экрана услышат что-то вроде «checkbox, not checked» и это их только запутает. Также не получиться активировать флажок голосовым управлением.Доступность — важный аспект веб-разработки. Он гарантирует, что ваш сайт будет удобным для пользователей с ограниченными возможностями. Атрибуты ARIA (Accessible Rich Internet Applications) играют ключевую роль в этом.
В статье есть раздел про улучшение доступности. На
<label> установлен атрибут aria-label="Menu", что исправляет проблему с безымянным флажком. Но в этом нет смысла, так как флажок скрыт, а <label> не интерактивный.Добавлены роли
banner и navigation для <header> и <nav>, у которых они встроены по умолчанию. На <nav> установлен атрибут aria-label="Main", a на подменю — aria-haspopup. При этом подменю отображается при ховере и фокусе без передачи соответствующего состояния.Добавления ARIA-атрибутов не сделало меню доступным. Флажок скрыт и недоступен для клавиатуры, программ чтения с экрана и голосового управления. Не передаётся состояние
aria-expanded. Подменю работают при ховере и фокусе. Анимации не сокращены.Это плохое меню с точки зрения пользовательского опыта и доступности. Стоит ли погоня за реализацией «без JS» сломанного опыта для пользователей? Для меня ответ очевиден: не стоит. Хаки есть хаки, применять их в интерфейсах не стоит.
#html #css #a11y #ui
👍7❤1👾1
System design и выбор фреймворков
Недавно прошёл 13й митап сообщества MinskJS, где по традиции было три доклада. Хочу отметить первые два, которые дополняют друг друга. Василий Ванчук рассказал про System Design для фронтендеров, а Анна Ширяева про выбор фреймворков.
Оба доклада так или иначе затрагивают темы кругозора и осознанного выбора инструментов и подходов для решения задачи. Периодически я пишу о выборе неподходящих инструментов и вытекающих из этого последствиях.
#js
Недавно прошёл 13й митап сообщества MinskJS, где по традиции было три доклада. Хочу отметить первые два, которые дополняют друг друга. Василий Ванчук рассказал про System Design для фронтендеров, а Анна Ширяева про выбор фреймворков.
Оба доклада так или иначе затрагивают темы кругозора и осознанного выбора инструментов и подходов для решения задачи. Периодически я пишу о выборе неподходящих инструментов и вытекающих из этого последствиях.
#js
minskjs.site
MinskJS Meetup #13 | MinskJS
Серия митапов MinskJS посвящена самому популярному языку программирования в вебе — JavaScript. Основная тематика — программирование, взаимодействие с бэкендом, различные оптимизации и вопросы безопасности.
❤5🔥3👍2
You don’t know HTML: виды скриптов
Для добавления скриптов на страницу используется элемент
Классический скрипт. Выполняется сразу же при обнаружении парсером и блокирует его.
Если значение атрибута
Как классический скрипт, но загружается внешний файл. Во время загрузки и обработки парсер блокируется. Тело элемента
Атрибут
Атрибут
Если у скрипта одновременно указаны атрибуты
Скрипт с атрибутом
Модульный скрипт с атрибутом
Атрибут
Атрибут
Атрибут
Атрибуты
#ydkhtml #js
Для добавления скриптов на страницу используется элемент
<noscript>. При этом скрипты бывают разных видов, что влияет на их поведение и загрузку.<noscript>Классический скрипт. Выполняется сразу же при обнаружении парсером и блокирует его.
<noscript type="not-javanoscript">Если значение атрибута
type не равно одному из MIME-типов JS или одному из ключевых слов, то это блок данных. Код в теле <noscript> не обрабатывается и не выполняется, что можно использовать для хранения данных.<noscript src="/noscript.js">Как классический скрипт, но загружается внешний файл. Во время загрузки и обработки парсер блокируется. Тело элемента
<noscript> с атрибутом src игнорируется, даже если там JS. Поэтому внутри можно оставить комментарии и пояснения. <noscript src="/noscript.js" async>Атрибут
async делает скрипт асинхронным и работает только с внешними файлами. Асинхронные скрипты загружаются при обнаружении парсером, но не блокируют его во время загрузки. Скрипты выполняются и блокируют парсер как только загрузятся.<noscript src="/noscript.js" defer>Атрибут
defer не блокирует парсер во время загрузки скрипта, но откладывает выполнение до момента готовности DOM. Отложенные скрипты выполняются в том же порядке, в котором они расположены в HTML, что отличает defer от async.<noscript src="/noscript.js" async defer>Если у скрипта одновременно указаны атрибуты
async и defer, то defer игнорируется. Поведение будет таким же, как у <noscript src="/noscript.js" async>.<noscript src="/noscript.js" type="module">Скрипт с атрибутом
type="module" обрабатывается как ES-модуль, где работают операторы import и export. Такие скрипты не блокируют парсер во время загрузки и выполняются по готовности DOM, при этом все зависимые модули должны загрузиться.<noscript src="/noscript.js" type="module" async></noscript>Модульный скрипт с атрибутом
async и все его зависимые модули загружаются параллельно и не блокируют парсер. Модуль выполнится сразу, как только будет загружена самая последняя зависимость.<noscript src="/noscript.js" nomodule></noscript>Атрибут
nomodule сообщает браузерам с поддержкой ES-модулей, что скрипт классический и его не нужно загружать и обрабатывать. nomodule используется в сочетании с модульными скриптами для создания резервного варианта для старых браузеров.<noscript type="importmap">Атрибут
type="importmap" сообщает браузеру, что тело скрипта — карта импортов. Это JSON-объект с псевдонимами путей к модулям, которые используются в операторах import и export. В современных браузерах можно определить несколько карт импортов.<noscript type="speculationrules">Атрибут
type="speculationrules" сообщает браузеру, что тело скрипта — правила спекулятивной загрузки. Браузеры заранее загружают страницы при выполнении указанных условий, что приводит к мгновенной загрузке страниц и ресурсов.Атрибуты
src, async, nomodule и defer не должны применяться для type="not-javanoscript", type="importmap" и type="speculationrules", поэтому их использование не окажет никакого влияния.#ydkhtml #js
1❤16👍9🤓2👾1
Web Interface Guidelines
Vercel поделилась списком лучших практик дизайна и разработки веб-интерфейсов. Список разделён на категории: взаимодействие, анимации, раскладка, контент, формы, производительность, дизайн и копирайтинг.
Некоторые пункты специфичны для React, а раздел про копирайтинг отражает особенности брендинга Vercel. В остальном это универсальный список, который точно стоит взять на вооружение дизайнерам и разработчикам интерфейсов.
Vercel также предлагает готовый файл AGENTS.md с адаптированными для LLM рекомендациями. Его можно использовать для расширения контекста агентов, чтобы они следовали этим практикам при генерации кода.
#ui
Vercel поделилась списком лучших практик дизайна и разработки веб-интерфейсов. Список разделён на категории: взаимодействие, анимации, раскладка, контент, формы, производительность, дизайн и копирайтинг.
Некоторые пункты специфичны для React, а раздел про копирайтинг отражает особенности брендинга Vercel. В остальном это универсальный список, который точно стоит взять на вооружение дизайнерам и разработчикам интерфейсов.
Vercel также предлагает готовый файл AGENTS.md с адаптированными для LLM рекомендациями. Его можно использовать для расширения контекста агентов, чтобы они следовали этим практикам при генерации кода.
#ui
Vercel Design
Web Interface Guidelines
Guidelines for building great interfaces on the web. Covers interactions, animations, layout, content, forms, performance & design.
👍7👾3😁1🌚1
Плавающие подписи
В интерфейсах часто встречаются так называемые плавающие подписи (floating labels). Это когда подпись отображается поверх поля ввода как заполнитель (placeholder), а при попадании фокуса плавно съезжает вверх и уменьшается в размерах.
Этот подход стал популярным благодаря дизайн-системе Material Design от Google. Он сохраняется в актуальной на сегодняшний день 3й версии. Его также можно встретить в других дизайн-системах и библиотеках компонентов.
Задумка плавающих подписей — компактность, учитывая что Material Design разработан в том числе для Android. Можно было бы использовать стандартный заполнитель, но это не лучшая идея. Плавающие подписи лучше, чем заполнители.
Но самый надёжный и практичный на мой взгляд способ подписывать поля — видимый текст рядом с полем ввода. Да, он не такой компактный, но лишён недостатков плавающих подписей, более надёжный и доступный.
Недостатки плавающих полей:
1. Структура HTML.
2. Переполнение. Длина подписи может оказаться больше длины поля. Хотя длинные подписи — плохая практика с точки зрения UX, такое иногда встречается. Перенос подписи ломает смещение и перекрывает введённое значение, с
3. Перекрытие заполнителя. Плавающая подпись перекрывает заполнитель, из-за чего его не используют или умышленно делают прозрачным, чтобы не было наложений. Заполнитель полезен, чтобы показать пример требуемых данных или формат ввода.
4. Выглядит как значение. Плавающая подпись у пустого поля выглядит так, как будто в поле уже что-то введено. Это может сбить с толку некоторых пользователей, особенно с когнитивными особенностями или нарушением зрения.
5. Размер шрифта. Наряду со смещением подписи вверх, также принято уменьшать её размер. Это может привести к слишком мелкому тексту, который трудно читать людям с нарушениями зрения. Увеличение размера текста в настройках либо ни к чему не приведёт, либо сломает плавающие подписи.
Для меня этого списка достаточно, чтобы избегать плавающих подписей. По возможности я стараюсь убедить дизайнеров использовать обычную подпись над полем, жертвуя компактностью.
Это оправдано, потому что в хороших формах не должно быть много полей, либо они должны разбиваться на шаги по принципу one thing per page. К тому же вертикальная прокрутка никуда не делась, форму с видимыми подписями можно прокрутить.
#ux #a11y
В интерфейсах часто встречаются так называемые плавающие подписи (floating labels). Это когда подпись отображается поверх поля ввода как заполнитель (placeholder), а при попадании фокуса плавно съезжает вверх и уменьшается в размерах.
Этот подход стал популярным благодаря дизайн-системе Material Design от Google. Он сохраняется в актуальной на сегодняшний день 3й версии. Его также можно встретить в других дизайн-системах и библиотеках компонентов.
Задумка плавающих подписей — компактность, учитывая что Material Design разработан в том числе для Android. Можно было бы использовать стандартный заполнитель, но это не лучшая идея. Плавающие подписи лучше, чем заполнители.
Но самый надёжный и практичный на мой взгляд способ подписывать поля — видимый текст рядом с полем ввода. Да, он не такой компактный, но лишён недостатков плавающих подписей, более надёжный и доступный.
<label for="name">
Имя
</label>
<input
type="text"
id="name"
autocomplete="given-name"
autocapitalize="words"
spellcheck="false"
>
<!--
Имя
[___________]
-->
Недостатки плавающих полей:
1. Структура HTML.
<label> нужно размещать после <input> и использовать селектор с комбинатором ~ или +. Или воспользоваться относительно новым селектором :has():input:is(:not(:placeholder-shown), :focus) + label {
/* ... */
}
label:has(+ input:is(:not(:placeholder-shown), :focus)) {
/* ... */
}
2. Переполнение. Длина подписи может оказаться больше длины поля. Хотя длинные подписи — плохая практика с точки зрения UX, такое иногда встречается. Перенос подписи ломает смещение и перекрывает введённое значение, с
overflow: hidden теряется информация, а торчащая за пределы поля подпись выглядит не красиво.3. Перекрытие заполнителя. Плавающая подпись перекрывает заполнитель, из-за чего его не используют или умышленно делают прозрачным, чтобы не было наложений. Заполнитель полезен, чтобы показать пример требуемых данных или формат ввода.
4. Выглядит как значение. Плавающая подпись у пустого поля выглядит так, как будто в поле уже что-то введено. Это может сбить с толку некоторых пользователей, особенно с когнитивными особенностями или нарушением зрения.
5. Размер шрифта. Наряду со смещением подписи вверх, также принято уменьшать её размер. Это может привести к слишком мелкому тексту, который трудно читать людям с нарушениями зрения. Увеличение размера текста в настройках либо ни к чему не приведёт, либо сломает плавающие подписи.
Для меня этого списка достаточно, чтобы избегать плавающих подписей. По возможности я стараюсь убедить дизайнеров использовать обычную подпись над полем, жертвуя компактностью.
Это оправдано, потому что в хороших формах не должно быть много полей, либо они должны разбиваться на шаги по принципу one thing per page. К тому же вертикальная прокрутка никуда не делась, форму с видимыми подписями можно прокрутить.
#ux #a11y
❤14🥰1😢1👾1
Enhanced Range Input
Во всех браузерах уже достаточно давно существует элемент
- Сложно стилизовать из-за ограничений и различий в вендорных псевдо-элементах;
- Не все части в принципе возможно стилизовать;
- Не поддерживается несколько ползунков, что часто встречается в фильтрах.
Из-за этого стандартный слайдер заменяют JS-библиотеками, вроде noUiSlider. Предложение Enhanced Range Input от OpenUI призвано решить проблемы и предоставить нативное решение.
Первое предложение связано со спецификацией CSS Form Control Styling, о которой я уже рассказывал. Это возможность включить «базовый» режим для стандартных элементов управления с помощью свойства
В «базовом» режиме элемент управления получает набор минималистичных стилей, которые стандартизированы и одинаковы для всех браузеров. Также «базовый» режим открывает доступ к новым псевдо-элементам для стилизации внутренних частей.
Далее предлагается новый элемент
У элемента
Атрибуты
Предусмотрена возможность привязки элемента
Промежутки между несколькими ползунками также можно стилизовать, используя новый псевдо-элемент
Для работы с диапазонами и несколькими значениями у
Предложение развивается и есть ряд открытых вопросов. Примеры кода и API можно посмотреть в самом предложении. Также автор подготовил прототип в виде веб-компонента и интерактивную площадку с примерами. Ждём реализацию в браузерах.
#html #css #js #ui
Во всех браузерах уже достаточно давно существует элемент
<input type="range">, отображающий слайдер с ползунком для изменения значения в заданном диапазоне. Элемент вполне можно использовать, но есть ряд проблем:- Сложно стилизовать из-за ограничений и различий в вендорных псевдо-элементах;
- Не все части в принципе возможно стилизовать;
- Не поддерживается несколько ползунков, что часто встречается в фильтрах.
Из-за этого стандартный слайдер заменяют JS-библиотеками, вроде noUiSlider. Предложение Enhanced Range Input от OpenUI призвано решить проблемы и предоставить нативное решение.
Дисклеймер: это обзор раннего предложения новых функций. Синтаксис может измениться в будущем или от функций могут отказаться.
Первое предложение связано со спецификацией CSS Form Control Styling, о которой я уже рассказывал. Это возможность включить «базовый» режим для стандартных элементов управления с помощью свойства
appearance.В «базовом» режиме элемент управления получает набор минималистичных стилей, которые стандартизированы и одинаковы для всех браузеров. Также «базовый» режим открывает доступ к новым псевдо-элементам для стилизации внутренних частей.
input[type="range"] {
appearance: base;
::slider-track {
/* Шкала, по которой перемещается ползунок */
}
::slider-fill {
/* Заполненная часть шкалы */
}
::slider-thumb {
/* Ползунок */
}
::slider-segment {
/* Часть шкалы между двумя ползунками */
}
::slider-tick {
/* Засечки при использовании <datalist> */
}
::slider-tick-label {
/* Подпись засечки при использовании <datalist> */
}
}Далее предлагается новый элемент
<rangegroup> для создания слайдера с несколькими ползунками. Это контейнер, который оркестрирует элементами <input type="range"> и отображает единый элемент управления.<rangegroup>
<legend>Цена</legend>
<label for="price-min">
Минимальная цена
</label>
<input
type="range"
id="price-min"
name="price-min"
value="25"
>
<label for="price-max">
Максимальная цена
</label>
<input
type="range"
id="price-max"
name="price-max"
value="75"
>
</rangegroup>
У элемента
<rangegroup> можно указать атрибуты min, max, name, list и stepbetween. Первые четыре работают как у <input type="range">, но определяют общий диапазон. stepbetween задаёт минимальную дистанцию между двумя ползунками.Атрибуты
min, max, value, name и step у <input> будут корректно взаимодействовать с атрибутами у <rangegroup>. Так min и max у <rangegroup> ограничивают min и max у <input>, чтобы они не выходили за пределы диапазона.Предусмотрена возможность привязки элемента
<datalist> с набором <option> к <rangegroup> для создания засечек с подсказками, к которым «магнитятся» ползунки. С псевдо-элементами ::slider-tick и ::slider-tick-label их можно стилизовать.Промежутки между несколькими ползунками также можно стилизовать, используя новый псевдо-элемент
::slider-segment в сочетании с псевдо-классами :nth-child. Аналогично можно по-разному стилизовать каждый ползунок.Для работы с диапазонами и несколькими значениями у
<rangegroup> будут соответствующие свойства и методы. Никуда не исчезнет API самих элементов <input type="range">, с которыми можно работать, получив их через <rangegroup>.const rangeGroup = document.querySelector(
'rangegroup[name="price-range"]'
);
// Получение значений
console.log(rangeGroup.values);
// [100, 750]
// Получение слайдеров
const inputs = rangeGroup.inputs;
console.log(inputs.length);
// 2
// Установка значений
rangeGroup.setRangeValue(0, 150);
console.log(rangeGroup.values);
// [150, 750]
Предложение развивается и есть ряд открытых вопросов. Примеры кода и API можно посмотреть в самом предложении. Также автор подготовил прототип в виде веб-компонента и интерактивную площадку с примерами. Ждём реализацию в браузерах.
#html #css #js #ui
👍10🔥4👾2❤1🌚1
Atomic Accessibility
Чарли Триплет создал набор атомарных критериев доступности для дизайнеров, разработчиков, тестировщиков и продуктовых менеджеров. Это своего рода чеклист для проверки доступности, но со своими особенностями.
Atomic Accessibility предлагает атомарный подход к требованиям соответствия. Сначала нужно выбирать роль: дизайнер, веб-, iOS- или Android-разработчик. Для каждой роли есть список элементов с разбивкой по категориям.
Внутри каждой категории находятся конкретные атомарные элементы интерфейса: шапка, форма поиска, хлебные крошки, пагинация, поле ввода пароля, диалоговое окно, флажки, вкладки, подвал и так далее.
У каждого элемента есть критерии соответствия. Для дизайнеров — требования WCAG и нарушения, которые затрагивает элемент. Для разработчиков — ожидаемое поведение клавиатуры, скринридеров и настроек системы.
Информация выводятся в текстовое поле, откуда её можно скопировать и вставить в техническое задание, описание задачи, чеклист приёмки, комментарии в ревью на GitHub, инструкции к нейросетям и агентам или куда-то ещё.
Можно перейти на детальную страницу каждого элемента, с описанием, примерами хорошего и плохого кода, пояснениями и ссылками. Критерии доступны в формате JSON для интеграции с разными системами.
#a11y
Чарли Триплет создал набор атомарных критериев доступности для дизайнеров, разработчиков, тестировщиков и продуктовых менеджеров. Это своего рода чеклист для проверки доступности, но со своими особенностями.
Atomic Accessibility предлагает атомарный подход к требованиям соответствия. Сначала нужно выбирать роль: дизайнер, веб-, iOS- или Android-разработчик. Для каждой роли есть список элементов с разбивкой по категориям.
Внутри каждой категории находятся конкретные атомарные элементы интерфейса: шапка, форма поиска, хлебные крошки, пагинация, поле ввода пароля, диалоговое окно, флажки, вкладки, подвал и так далее.
У каждого элемента есть критерии соответствия. Для дизайнеров — требования WCAG и нарушения, которые затрагивает элемент. Для разработчиков — ожидаемое поведение клавиатуры, скринридеров и настроек системы.
Информация выводятся в текстовое поле, откуда её можно скопировать и вставить в техническое задание, описание задачи, чеклист приёмки, комментарии в ревью на GitHub, инструкции к нейросетям и агентам или куда-то ещё.
Можно перейти на детальную страницу каждого элемента, с описанием, примерами хорошего и плохого кода, пояснениями и ссылками. Критерии доступны в формате JSON для интеграции с разными системами.
#a11y
Atomic Accessibility
Accessibility criteria & checklists
- [Updated 2025] Atomic Accessibility
- [Updated 2025] Atomic Accessibility
❤9👍6🤔2🌚1👾1