Skip to content

Commit

Permalink
Добавляет доку про aria-expanded (doka-guide#4994)
Browse files Browse the repository at this point in the history
* Дополняет текст

* Добавляет черновик демки

* Указывает правильный путь

* Допиливает демку

* Дополняет текст

* Дописывает текст

* Добавляет недостающий размер шрифта

* Исправляет ссылки

* Улучшает текст

* Вносит мелкие правки в текст

* Удаляет лишний пробел

* Актуализирует пример

* Упрощает пример

* Использует привычный термин

* Выравнивание многоточие

* Добавляет контрибьютера

---------

Co-authored-by: Svetlana Korobtseva <wizzzjer@gmail.com>
  • Loading branch information
2 people authored and baileys-li committed Dec 19, 2024
1 parent e8289bb commit 30847ca
Show file tree
Hide file tree
Showing 2 changed files with 234 additions and 33 deletions.
174 changes: 174 additions & 0 deletions a11y/aria-expanded/demos/burger-menu/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<title>Бургер-меню — aria-expanded — Дока</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400&display=swap">
<style>
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}

html {
color-scheme: dark;
font-size: 18px;
}

body {
min-height: 100vh;
padding: 50px;
display: flex;
justify-content: center;
background-color: #18191C;
color: #000000;
font-family: "Roboto", sans-serif;
}

.subnav-container {
position: relative;
}

.subnav {
display: none;
position: absolute;
top: 53px;
right: 0;
max-width: 240px;
min-width: 180px;
padding: 10px;
list-style: none;
background-color: #FFFFFF;
}

.subnav-opened {
display: block;
}

.subnav-link {
display: inline-flex;
align-items: center;
width: 100%;
padding: 10px;
gap: 10px;
border-radius: 3px;
color: inherit;
-webkit-text-decoration-color: #10F3AF;
text-decoration-color: #10F3AF;
text-decoration-thickness: 2px;
transition: background-color 0.2s linear;
}

.subnav-link:hover, .subnav-link:focus {
background-color: #10F3AF;
transition: background-color 0.2s linear;
outline-width: 0;
}

.button {
display: block;
border: 2px solid transparent;
border-radius: 6px;
padding: 11px 15px;
color: #000000;
font-size: 1rem;
line-height: 0;
font-weight: 300;
font-family: inherit;
transition: background-color 0.2s linear;
}

.button:hover {
background-color: #FFFFFF;
cursor: pointer;
transition: background-color 0.2s linear;
}

.button:focus-visible {
border: 2px solid #FFFFFF;
outline: none;
}

.button:focus {
border: 2px solid #FFFFFF;
outline: none;
}

.button-aqua {
background-color: #10F3AF;
}

.button-dots {
width: 23px;
height: 23px;
stroke: #000000;
stroke-width: 2.6;
stroke-linecap: round;
stroke-linejoin: round;
}

@media (max-width: 768px) {
body {
padding: 30px;
}

.subnav {
max-width: 100%;
right: -60px;
}
}
</style>
</head>
<body>
<div class="subnav-container">
<button class="button button-aqua" aria-label="Список товаров" aria-expanded="false" aria-controls="subnav">
<svg class="button-dots" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23" aria-hidden="true">
<circle cx="12" cy="12" r="1"/>
<circle cx="19" cy="12" r="1"/>
<circle cx="5" cy="12" r="1"/>
</svg>
</button>

<ul class="subnav" id="subnav">
<li class="subnav-item">
<a href="#" class="subnav-link">Бассейны для собак</a>
</li>
<li class="subnav-item">
<a href="#" class="subnav-link">Коробки для кошек</a>
</li>
<li class="subnav-item">
<a href="#" class="subnav-link">Поилки для крыс</a>
</li>
</ul>
</div>

<script>
const button = document.querySelector('.button')
const subnav = document.querySelector('.subnav')
const openedSubnavClass = 'subnav-opened'

button.addEventListener('click', (event) => {
event.stopPropagation()
button.setAttribute('aria-expanded', button.getAttribute('aria-expanded') === 'true' ? 'false' : 'true')
subnav.classList.toggle(openedSubnavClass)
})

function closeSubnav() {
button.setAttribute('aria-expanded', 'false')
subnav.classList.remove(openedSubnavClass)
}

document.addEventListener('click', (event) => {
closeSubnav()
})

document.addEventListener('focusin', (event) => {
closeSubnav()
})
</script>
</body>
</html>
93 changes: 60 additions & 33 deletions a11y/aria-expanded/index.md
Original file line number Diff line number Diff line change
@@ -1,65 +1,92 @@
---
title: "`aria-expanded`"
description: "ARIA-атрибут для элементов, которые разворачивают и сворачивают другие элементы или содержимое."
description: "Как рассказать скринридерам, что элемент что-то разворачивает и сворачивает."
authors:
- doka-dog
- tatianafokina
contributors:
- skorobaeus
keywords:
- a11y
- доступность
- ARIA
- ARIA-атрибут
- expandable widget
related:
- a11y/aria-owns
- a11y/aria-attrs
- a11y/aria-haspopup
- a11y/aria-controls
tags:
- doka
- placeholder
---

## Кратко

[Состояние виджета](/a11y/aria-attrs/#atributy-vidzhetov) из [WAI-ARIA](/a11y/aria-intro/#specifikaciya). Даёт вспомогательным технологиям понять, что элемент что-то разворачивает или сворачивает.
[Состояние виджета](/a11y/aria-attrs/#atributy-vidzhetov) из [WAI-ARIA](/a11y/aria-intro/#specifikaciya). Сообщает вспомогательным технологиям, что элемент разворачивает и сворачивает другое содержимое.

`aria-expanded` нужен для компонентов, которые изменяют видимость содержимого. Например для кнопки, которая показывает или скрывает список ссылок на сайте.

## Пример

```html
<button aria-expanded="false" aria-controls="menu">Раскрыть меню</button>
<div class="menu" id="menu">
<ul>
<li>
<a href="/dogs-pools/">Бассейны для собак</a>
</li>
<li>
<a href="/cats-boxes/">Коробки для кошек</a>
</li>
</ul>
</div>
<nav>
<button
aria-label="Список товаров"
aria-expanded="false"
aria-controls="subnav"
>
<!-- Иконка -->
</button>

<div id="subnav">
<ul>
<li>
<a href="/dogs-pools/">
Бассейны для собак
</a>
</li>
<li>
<a href="/cats-boxes/">
Коробки для кошек
</a>
</li>
<li>
<a href="/rats-water-bowls/">
Поилки для крыс
</a>
</li>
</ul>
</div>
</nav>
```

<iframe title="Бургер-меню" src="demos/burger-menu/" height="360"></iframe>

[Скринридер](/a11y/screenreaders/) при фокусе на кнопке расскажет о ней примерно так: «Список товаров, кнопка, свёрнуто». Когда пользователь раскроет список, скринридер просто сообщит «развёрнуто» без повторения информации о кнопке.

## Как пишется

Добавьте к тегу атрибут `aria-expanded` с одним из трёх значений:
Добавьте к элементу атрибут `aria-expanded` с одним из трёх значений:

- `undefined` (по умолчанию) — у элемента нет содержимого, которое разворачивается и сворачивается.
- `true` — содержимое или другие элементы развёрнуты.
- `false` — содержимое или другие элементы свёрнуты.
- `undefined` (по умолчанию) — у элемента нет содержимого, которое разворачивается и сворачивается.

Атрибут можно использовать только для некоторых тегов и [ARIA-ролей](/a11y/aria-roles/):
`aria-expanded` используют для интерактивных элементов, с которыми могут взаимодействовать пользователи. Так что атрибут подходит только для некоторых HTML-тегов и [ARIA-ролей](/a11y/aria-roles/):

- [`<a>`](/html/a/) или [`link`](/a11y/role-link/).
- [`<button>`](/html/button/) или [`button`](/a11y/role-button/).
- [`<input type="checkbox">`](/html/input/#type) или [`checkbox`](/a11y/role-checkbox/).
- [`<select>`](/html/select/) или [`combobox`](/a11y/role-combobox/), [`listbox`](/a11y/role-listbox/).
- [`<tr>`](/html/tables/#tr) или [`row`](/a11y/role-row/).
- [`<th>`](/html/tables/#th) или [`rowheader`](/a11y/role-rowheader/).
- [`application`](/a11y/role-application/).
- [`tab`](/a11y/role-tab/).
- [`menuitem`](/a11y/role-menuitem/).
- [`treeitem`](/a11y/role-treeitem/).
- [`gridcell`](/a11y/role-gridcell/).
- ссылок [`<a>`](/html/a/) или [роли `link`](/a11y/role-link/);
- кнопок [`<button>`](/html/button/) или [роли `button`](/a11y/role-button/);
- чекбоксов [`<input type="checkbox">`](/html/input/#type) или [роли `checkbox`](/a11y/role-checkbox/);
- выпадающих списков [`<select>`](/html/select/) или ролей [`combobox`](/a11y/role-combobox/), [`listbox`](/a11y/role-listbox/);
- интерактивных строк таблиц [`<tr>`](/html/tables/#tr) или [`row`](/a11y/role-row/);
- интерактивных заголовков ячеек или строк таблиц [`<th>`](/html/tables/#th) или [`rowheader`](/a11y/role-rowheader/);
- приложений [`application`](/a11y/role-application/);
- вкладок [`tab`](/a11y/role-tab/);
- пунктов меню как в программе [`menuitem`](/a11y/role-menuitem/);
- пунктов древовидных списков [`treeitem`](/a11y/role-treeitem/);
- ячеек сеток [`gridcell`](/a11y/role-gridcell/).

Используйте `aria-expanded` вместе с [`aria-controls`](/a11y/aria-controls/) или [`aria-owns`](/a11y/aria-owns/), когда контейнер с разворачивающимся содержимым не вложен в главный элемент.
Атрибут повысит доступность бургер-меню, кастомных аккордеонов, выпадающих или древовидных списков, а ещё сеток — интерактивных таблиц как в Exel.

## Как понять
`aria-expanded` хорошо сочетается с атрибутами связи [`aria-controls`](/a11y/aria-controls/) и [`aria-owns`](/a11y/aria-owns/). `aria-controls` указывает на связь между управляющим и управляемым элементами, а `aria-owns` — на связь между родительским и дочерним.

Атрибут `aria-expanded` нужен для элементов, при взаимодействии с которыми содержимое изменяет видимость. Например для кнопки, которая показывает или скрывает меню.
Чтобы скринридеры правильно рассказали о том, свёрнут или развёрнут элемент, задействуйте магию JavaScript 🪄 Например, слушайте [событие `click`](/js/events/) на элементе и, если содержимое развёрнуто, задавайте кнопке `aria-expanded="true"`, если свёрнуто — `aria-expanded="false"`. Значения можно переключать методом `.setAttribute()`.

0 comments on commit 30847ca

Please sign in to comment.