Skip to content

Commit

Permalink
Дополняет доку про роли none и presentation (#4962)
Browse files Browse the repository at this point in the history
* Дополняет текст доки

* Увеличивает шрифт в демке

* Увеличивает высоту демки

* Удаляет недоссылку

* Исправляет ошибки щ(゜ロ゜щ)

* Добавляет уточнение про картинки

* Укорачивает пример

* Слегка улучшает текст

* Добавляет потерявшееся слово

* Возвращает предыдущий размер
  • Loading branch information
TatianaFokina authored Nov 22, 2023
1 parent 512af03 commit bffcc48
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 20 deletions.
7 changes: 6 additions & 1 deletion a11y/role-presentation-none/demos/decorative-hr/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<title>Декоративный разделитель в тексте — presentation, none — Дока</title>
<title>Текст с декоративным разделителем — presentation, none — Дока</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preconnect" href="https://fonts.googleapis.com">
Expand All @@ -14,6 +14,11 @@
box-sizing: border-box;
}

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

body {
min-height: 100vh;
padding: 50px;
Expand Down
Binary file added a11y/role-presentation-none/images/just-table.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
146 changes: 127 additions & 19 deletions a11y/role-presentation-none/index.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
---
title: "`presentation`, `none`"
description: "Роли для удаления семантики элементов."
description: "Роли, которые сметают на своём пути семантику элементов."
authors:
- tatianafokina
contributors:
- skorobaeus
keywords:
- доступность
- a11y
- ARIA
- сброс семантики
related:
- a11y/aria-intro
- a11y/aria-hidden
- a11y/aria-roles
- a11y/aria-attrs
tags:
Expand All @@ -18,9 +19,15 @@ tags:

## Кратко

`presentation`[роль структуры документа](/a11y/aria-roles/#roli-struktury-dokumenta), которая удаляет семантику элемента. Другая роль `none` — это синоним `presentation`.
`presentation`[роль структуры документа](/a11y/aria-roles/#roli-struktury-dokumenta) из WAI-ARIA, которая удаляет семантику элемента. `none` — это другое название для `presentation`.

Обе роли делают одно и то же, но рекомендуется использовать `presentation` вместо `none`. У `presentation` более стабильная поддержка.
`presentation` и `none` превращают любой семантический тег в [`<div>`](/html/div/) или [`<span>`](/html/span/) для [скринридеров](/a11y/screenreaders/) и других вспомогательных технологий.

<aside>

🤸‍♀️ Пока что лучше использовать `presentation`. У роли более стабильная поддержка.

</aside>

## Пример

Expand All @@ -35,34 +42,135 @@ tags:
</p>
```

<iframe title="Текст с декоративным разделителем" src="demos/decorative-hr/" height="390"></iframe>
<iframe title="Текст с декоративным разделителем" src="demos/decorative-hr/" height="530"></iframe>

В этом примере тег [`<hr>`](/html/hr/) потерял свою семантику и стал просто декоративным разделителем.
В этом примере тег [`<hr>`](/html/hr/) потерял свою семантику и стал просто декоративным разделителем. Из-за этого скринридер не расскажет, что на странице есть элемент с [ролью `separator`](/a11y/role-separator/).

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

Добавьте `role="presentation"` или `role="none"` к семантическому тегу. Исключение — интерактивные элементы, с которыми могут взаимодействовать пользователи. К примеру, кнопки, ссылки или поля.
Добавьте `role="presentation"` или `role="none"` к семантическому тегу — HTML-элементу со встроенной ролью. Например, [`<h1>`](/html/h1-h6/), [`<table>`](/html/table/) или [`<li>`](/html/li/). Исключение — интерактивные элементы, с которыми взаимодействуют пользователи. Это могут быть кнопки [`<button>`](/html/button/), ссылки [`<a>`](/html/a/) или поля [`<input>`](/html/input/) и [`<textarea>`](/html/textarea/).

Хотя современные браузеры больше не удаляют семантику интерактивных тегов из-за `presentation` или `none`, всё равно лучше не нарушать [правила использования ARIA](/a11y/aria-intro/#pravila-ispolzovaniya).

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

На самом деле современные браузеры делают исключение для кликабельных элементов вроде ссылок и полей и не отменяют их семантику, когда им заданы роли `presentation` или `none`. Но всё равно лучше не нарушать [правила использования ARIA](/a11y/aria-intro/#pravila-ispolzovaniya).
К элементам с ролями `presentation` или `none` можно добавлять все [ARIA-атрибуты](/a11y/aria-attrs/), кроме глобальных:

Элементам с ролями `presentation` или `none` можно задавать почти все [ARIA-атрибуты](/a11y/aria-attrs/), кроме [`aria-label`](/a11y/aria-label/) и [`aria-labelledby`](/a11y/aria-labelledby/).
- [`aria-label`](/a11y/aria-label/);
- [`aria-braillelabel`](/a11y/aria-braillelabel/);
- [`aria-labelledby`](/a11y/aria-labelledby/);
- [`aria-describedby`](/a11y/aria-describedby/);
- [`aria-details`](/a11y/aria-details/);
- [`aria-description`](/a11y/aria-description/);
- [`aria-roledescription`](/a11y/aria-roledescription/);
- [`aria-brailleroledescription`](/a11y/aria-brailleroledescription/);
- [`aria-hidden`](/a11y/aria-hidden/);
- [`aria-flowto`](/a11y/aria-flowto/);
- [`aria-keyshortcuts`](/a11y/aria-keyshortcuts/);
- [`aria-current`](/a11y/aria-current/);
- [`aria-controls`](/a11y/aria-controls/);
- [`aria-owns`](/a11y/aria-owns/);
- [`aria-live`](/a11y/);
- [`aria-busy`](/a11y/aria-live/);
- [`aria-atomic`](/a11y/aria-atomic/);
- [`aria-relevant`](/a11y/aria-relevant/).

Если зададите [глобальные ARIA-атрибуты](/a11y/aria-attrs/#globalnye-atributy) для элемента с этими ролями, браузер использует его встроенную роль и проигнорирует явную `presentation` или `none`.
Если используете атрибуты из списка в теге со сброшенной семантикой, некоторые браузеры и вспомогательные технологии используют встроенную роль элемента и проигнорируют явную `presentation`.

[`<img>`](/html/img/) с `presentation` или `none` ведёт себя так, как если бы картинку скрыли от скринридера с помощью ARIA-атрибута [`aria-hidden`](/a11y/aria-hidden/). Поэтому такое изображение не надо описывать в [`alt`](/html/img/#alt).
Последнее важное правило для `presentation` и `none` — таким элементам не нужны имена. Это их краткие названия, которые скринридеры читают перед ролью. Не важно, откуда берётся имя у элемента — из текстового содержимого тега или из `aria-label`.

Разберём простой пример со списком. Зададим родительскому [`<ul>`](/html/ul/) явную роль `presentation`:

```html
<ul role="presentation">
<li>Динозавры.</li>
<li>Минералы.</li>
<li>
Вкусный <a href="#">пирожок</a>.
</li>
</ul>
```

Когда в элемент с ролями `presentation` или `none` вложены другие элементы, они вместе с родителем потеряют свою семантику. В таком случае в [дерево доступности](/a11y/screenreaders/#derevo-dostupnosti) попадёт только их содержимое, к примеру, текст.
Для вспомогательных технологий всё превратится в [`<span>`](/html/span/), кроме ссылки `<a>`:

## Как понять
```html
<span>
<span>Динозавры.</span>
<span>Минералы.</span>
<span>
Вкусный <a href="#">пирожок</a>.
</span>
</span>
```

Роли `presentation` или `none` пригодятся, когда нужно оставить встроенные стили элемента, но скрыть его семантику от вспомогательных технологий. Это полезно в некоторых случаях:
`presentation` и `none` пригодятся, когда нужно оставить встроенные стили или логику тега, но не рассказывать вспомогательным технологиям про его семантику. Распространённые ситуации:

- декоративный элемент — картинки для красоты, разделители и похожие элементы;
- таблица для раскладки, как на старых сайтах или в электронных письмах;
- кастомный элемент, внутри которого есть элементы с ненужной семантикой в этом контексте. Например, панель вкладок, меню и другие контролы.
- кастомный элемент, внутри которого есть другие с ненужной в этом контексте семантикой. Например, панель вкладок или меню как в редакторе текста.

## Подсказки
Декоративная картинка [`<img>`](/html/img/) с ролью `presentation` ведёт себя так, как если бы её скрыли от скринридера с помощью `aria-hidden` или CSS-свойства [`display: none`](/css/display/). Такое изображение точно не нужно описывать в [`alt`](/html/img/#alt).

```html
<img role="presentation" src="img/decorative-pic-1.svg" alt="">
```

Можете встретить вариант декоративной картинки с пропущенным `alt`:

```html
<img role="presentation" src="img/decorative-pic-1.svg">
```

Хотя этот пример из спецификации, такой код не пройдёт валидацию. Дело в том, что у элементов с атрибутом `role` обязательно должны быть имена. В случае тега `<img>` имя элемента берётся из `alt`. Также вспомогательные технологии пока плохо поддерживают подобные картинки.

<aside>

🐶 Рекомендуем всегда использовать возможности HTML. Просто оставьте `alt` пустым, если нужна декоративная картинка: `<img src="…" alt="">`.

</aside>

На практике `presentation` чаще всего встречается в письмах. Тег [`<table>`](/html/table/) в письмах используют не для хранения данных как обычно, а для визуального выравнивания содержимого. При помощи роли `presentation` сбросится не только семантика самой таблицы, но и её дочерних элементов — [`<tr>`](/html/tables/#tr), [`<th>`](/html/tables/#th), [`<td>`](/html/tables/#td) и других.

```html
<table
role="presentation"
width="100%"
cellpadding="0"
cellspacing="0"
border="0"
style="color: green;"
>
<tbody>
<tr>
<th>
Привет, это рассылка от нас!
</th>
</tr>
</tbody>
</table>
```

💡 `presentation` и `none` превращают любой семантический тег в [`<div>`](/html/div/) или [`<span>`](/html/span/) для [скринридера](/a11y/screenreaders/). Применять эти роли к `<span>` или `<div>` нет смысла, так как у них нет встроенной семантики.
Если загляните в [дерево доступности](/a11y/screenreaders/#derevo-dostupnosti) в инструменте разработчика в Chrome, заметите, что у `<th>` внутри `<table role="presentation">` вычисляется [роль `generic`](/a11y/role-generic/). Это значит, что для браузеров и других программ это элемент без семантики.

![Слева HTML-код таблицы из примера, справа дерево доступности с вычисленными свойствами. Таблице задана роль presentation.](images/table-role-presentation.png)

Для сравнения, у `<th>` будет роль `layoutTableCell` в таблице с родной семантикой, но без подписи [`<caption>`](/html/caption/).

![Слева HTML-код таблицы, справа дерево доступности с вычисленными свойствами. У таблицы на этот раз нет роли presentation.](images/just-table.png)

`presentation` также часто используют во вкладках и в других кастомных элементах, для которых пока не хватает возможностей HTML. К примеру, вспомогательные технологии в случае вкладок на `<ul>` не расскажут, что пользователь находится на элементе списка.

```html
<ul role="tablist">
<li role="presentation">
<a role="tab" href="#">Тапиры</a>
</li>
<li role="presentation">
<a role="tab" href="#">Утконосы</a>
</li>
</ul>
```

## Подсказки

💡 Элементам с `presentation` и `none` не нужны имена. Это их краткие названия, которые скринридер читает перед ролями.
💡 `presentation` и `none` часто путают с `aria-hidden="true"`. Их разница в том, что атрибут полностью удаляет элемент из дерева доступности. Из-за этого вспомогательные технологии не знают о его семантике, содержимом, состоянии и свойствах.

0 comments on commit bffcc48

Please sign in to comment.