Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Исправляет код из описания рецепта "Выпадающее меню" #5469

Merged
merged 4 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 24 additions & 20 deletions recipes/dropdown-menu/demos/menu/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -236,14 +236,26 @@
<nav class="site-nav" aria-label="Сайт">
<ul class="menu">
<li class="menu__item" data-has-children>
<span data-controls="doka-submenu">Дока</span>
<button
class="menu__btn"
aria-expanded="false"
aria-controls="doka-submenu"
>
Дока
</button>

<ul class="menu menu-submenu" id="doka-submenu">
<li class="menu__item">
<a href="#" class="menu__link" aria-current="page">Рецепты</a>
</li>
<li class="menu__item" data-has-children>
<span data-controls="html-submenu">HTML</span>
<button
class="menu__btn"
aria-expanded="false"
aria-controls="html-submenu"
>
HTML
</button>

<ul class="menu menu-submenu" id="html-submenu">
<li class="menu__item">
Expand All @@ -258,7 +270,13 @@
</ul>
</li>
<li class="menu__item" data-has-children>
<span data-controls="css-submenu">CSS</span>
<button
class="menu__btn"
aria-expanded="false"
aria-controls="css-submenu"
>
CSS
</button>

<ul class="menu menu-submenu" id="css-submenu">
<li class="menu__item">
Expand Down Expand Up @@ -302,13 +320,12 @@ <h1>Рецепты</h1>
<script>
// Следуем принципам прогрессивного улучшения.
// Показываем пользователю простую навигацию в случае, если не удаётся загрузить JavaScript.
// Если JavaScript-файл загружен, заменяем span на кнопки и вешаем дополнительные ARIA-атрибуты.

const nav = document.querySelector('.site-nav')
nav.classList.add('enhanced')

const submenus = document.querySelectorAll('.menu__item[data-has-children]')
const dropdowns = document.querySelectorAll('.menu__item[data-has-children] > .menu')
const submenus = nav.querySelectorAll('.menu__item[data-has-children]')
const dropdowns = nav.querySelectorAll('.menu__item[data-has-children] > .menu')

const icon = `
<svg
Expand All @@ -327,24 +344,11 @@ <h1>Рецепты</h1>
const dropdown = item.querySelector(':scope > .menu')
dropdown.setAttribute('hidden', '')

const span = item.querySelector(':scope > span')
const text = span.innerText
const ariaControlsId = span.dataset.controls

const button = document.createElement('button')

// Добавляем класс и необходимые ARIA-атрибуты
button.classList.add('menu__btn')
button.setAttribute('aria-expanded', 'false')
button.setAttribute('aria-controls', ariaControlsId)

button.innerText = text
const button = item.querySelector(':scope > .menu__btn')

// Добавляем иконку к кнопке, чтобы визуально было понятно открыто меню или нет
button.innerHTML += icon

span.replaceWith(button)

button.addEventListener('click', function (e) {
toggleDropdown(button, dropdown)
})
Expand Down
49 changes: 25 additions & 24 deletions recipes/dropdown-menu/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ tags:
<body>
<header class="header">
<nav
class="site-nav enhanced"
class="site-nav"
aria-label="Сайт"
>
<ul class="menu">
Expand All @@ -42,7 +42,7 @@ tags:
</button>
vitya-ne marked this conversation as resolved.
Show resolved Hide resolved

<!-- Первый уровень вложенности -->
<ul class="menu" id="doka-submenu" hidden>
<ul class="menu menu-submenu" id="doka-submenu">
<li class="menu__item">
<a
href="#"
Expand All @@ -53,7 +53,7 @@ tags:
</a>
<li>

<li class="menu__item">
<li class="menu__item" data-has-children>
<button
class="menu__btn"
aria-expanded="false"
Expand All @@ -63,7 +63,7 @@ tags:
</button>

<!-- Второй уровень вложенности -->
<ul class="menu" id="html-submenu" hidden>
<ul class="menu menu-submenu" id="html-submenu">
<li class="menu__item">
<a href="#" class="menu__link">
Основы
Expand All @@ -82,7 +82,7 @@ tags:
</ul>
</li>

<li class="menu__item">
<li class="menu__item" data-has-children>
<button
class="menu__btn"
aria-expanded="false"
Expand All @@ -92,7 +92,7 @@ tags:
</button>

<!-- Второй уровень вложенности -->
<ul class="menu" id="css-submenu" hidden>
<ul class="menu menu-submenu" id="css-submenu">
<li class="menu__item">
<a href="#" class="menu__link">
Основы
Expand Down Expand Up @@ -264,42 +264,45 @@ a[aria-current="page"] {
top: 0;
left: 104%;
}

.menu[hidden] {
display: none;
}
```

```js
const nav = document.querySelector('.site-nav')
nav.classList.add('enhanced')

const submenus = document.querySelectorAll(
const submenus = nav.querySelectorAll(
'.menu__item[data-has-children]'
)
const dropdowns = document.querySelectorAll(
const dropdowns = nav.querySelectorAll(
vitya-ne marked this conversation as resolved.
Show resolved Hide resolved
'.menu__item[data-has-children] > .menu'
)

const icon = '<svg>...</svg>'
const icon = `
<svg
width="24px"
height="24px"
viewBox="0 0 24 24"
aria-hidden="true"
class="menu__btn-icon"
>
<path fill="currentColor" d="M5.64645 8.64645c.19526-.19527.51184-.19527.7071 0L12 14.2929l5.6464-5.64645c.1953-.19527.5119-.19527.7072 0 .1952.19526.1952.51184 0 .7071L12 15.7071 5.64645 9.35355c-.19527-.19526-.19527-.51184 0-.7071Z"></path>
</svg>
`

// Находим подменю, заменяем в нём span на кнопку
submenus.forEach((item) => {
const dropdown = item.querySelector(':scope > .menu')
dropdown.setAttribute('hidden', '')

const span = item.querySelector(':scope > span')
const text = span.innerText
const ariaControlsId = span.dataset.controls
const button = document.createElement('button')

// Добавляем класс и необходимые aria-атрибуты
button.classList.add('menu__btn')
button.setAttribute('aria-expanded', 'false')
button.setAttribute('aria-controls', ariaControlsId)

button.innerText = text
const button = item.querySelector(':scope > .menu__btn')

// Добавляем иконку к кнопке, чтобы визуально было
// понятно открыто меню или нет
button.innerHTML += icon
span.replaceWith(button)

button.addEventListener('click', function (e) {
toggleDropdown(button, dropdown)
Expand Down Expand Up @@ -400,7 +403,7 @@ window.addEventListener('click', collapseDropdownsWhenClickingOutsideNav)
```html
<nav class="site-nav" aria-label="Сайт">
<ul class="menu">
<li class="menu__item">
<li class="menu__item" data-has-children>
<button
class="menu__btn"
aria-expanded="false"
Expand Down Expand Up @@ -490,5 +493,3 @@ function toggleDropdown(button, dropdown) {
```

Также при создании многоуровневых меню можно часто встретить вариант, когда элементы меню появляются при наведении на них курсора мыши, — по событию `hover`. В таком случае базовая вёрстка останется аналогичной примеру, только нужно будет доработать стили появления — скрывать вложенное меню по умолчанию свойством `display: none` и показывать при наведении мыши.

В мобильной версии меню выглядит как аккордеон. Часто мобильное меню прячут за иконкой с тремя линиями или точками (бургер) или чем-то подобным. При такой реализации помните о доступности и скрывайте меню полностью, чтобы пользователи не могли сделать на нём фокус с помощью клавиши <kbd>Tab</kbd>. Для этого можно использовать свойство [`display: none`](/css/display/#kak-pishetsya) или HTML-атрибут [`hidden`](/html/hidden/). Данные методы прячут меню из [дерева доступности](/a11y/a11y-tree/), но не дают анимировать открытие и закрытие меню.
Loading