TGViewer
<divelopers> <divelopers> @alexnozer_dev · 1.18K subscribers
Post #289 1.11K
Меню без скриптов

Я уже писал о 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
  • ❤ 3
  • 👾 2
More from @alexnozer_dev
  1. Sep 23, 2026Images Preview На некоторых сайтах, где надо показывать изображения в высоком качестве, дл…
  2. Sep 21, 2026Реализация пользовательских атрибутов Под конец прошлого года я рассказывал об API пользов…
  3. Sep 14, 2026Подклассы Event вместо CustomEvent Многие библиотеки предоставляют систему событий в качес…
  4. Sep 11, 2026Эволюция стилей в темах Shopify Адам Ватан на днях поделился новостью, что Shopify выкупил…
  5. Sep 9, 2026Persistent Widgets Многие сайты не должны быть SPA. Но иногда эта архитектура продиктована…
  6. Sep 7, 2026Processing Instructions и маркеры В DOM всё представлено в виде узлов (Node) разных типов.…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →