Введение в ARIA

ARIA (Accessible Rich Internet Applications) — это спецификация, разработанная W3C, которая помогает сделать веб-контент более доступным для людей с ограниченными возможностями. Она предлагает множество атрибутов, которые можно добавлять к HTML-элементам, чтобы улучшить их доступность и интерактивность.

Кратко

aria-disabled — это ARIA-атрибут, который указывает, что элемент интерфейса в данный момент недоступен для взаимодействия. Он позволяет разработчикам явно указать, что элемент неактивен, без изменения его DOM-структуры или удаления привязанных событий.

Так же работает HTML-атрибут disabled.

Пример

Пример с кнопкой, которую хотим временно сделать неактивной, не удаляя при этом обработчики событий:

<button aria-disabled="true">Отправить</button>

Кнопка будет отображаться, но пользователь не сможет по ней кликнуть или сфокусироваться.

Как пишется

Добавьте к тегу атрибут aria-disabled с одним из значений:

  • true — элемент неактивен;

  • false (по умолчанию) — элемент активен, с ним можно взаимодействовать.

aria-disabled можно задавать только некоторым тегам и ролям:

  • <button>, <summary>, <input> с типами button, image, reset, submit или для роли button;

  • <a> или link;

  • <details>, <fieldset>, <optgroup> или group;

  • <hr> или separator;

  • <div>, <span> или generic;

  • tab;

  • scrollbar;

  • application;

  • gridcell;

  • menuitem.

Для HTML-тегов лучше использовать атрибут disabled вместо aria-disabled там, где он поддерживается.

Подводные камни и особенности

  • неактивные родительские элементы: если родительский элемент получает aria-disabled="true", его дочерние элементы также считаются неактивными;

  • CSS и JavaScript: чтобы полностью реализовать поведение неактивности, нужно использовать CSS для стилизации и JavaScript для управления состоянием, так как aria-disabled сам по себе не останавливает взаимодействие с элементом.

Особенности для ссылок

Для элементов <a>, которые не содержат атрибут href, aria-disabled="true" может быть использован для указания, что ссылка в текущем состоянии нефункциональна. Такой трюк используют для хлебных крошек. Так пользователи клавиатуры знают, где находятся сейчас, при этом не могут перейти по ссылке на текущую страницу. Например:

<a href="#dogs">Товары для собак</a>

<a
  role="link"
  aria-disabled="true"
  aria-current="page"
>
  Товары для котов
</a>

В случае неактивной ссылки лучше не использовать href, и чтобы ссылка не потеряла свою роль, явно её задать с помощью атрибута role="link".

Задействуем CSS и JavaScript

Использование aria-disabled отличается от атрибута disabled. ARIA-атрибут не останавливает все виды пользовательского взаимодействия с элементом на уровне браузера. Поэтому важно использовать CSS и JavaScript для управления состояниями элементов. Вот простой пример, как можно стилизовать и управлять элементом с aria-disabled:

[aria-disabled="true"] {
  opacity: 0.7;
  cursor: not-allowed;
}

[aria-disabled="true"]:focus {
  outline: none;
}
document.querySelectorAll('[aria-disabled="true"]').forEach((element) => {
  element.addEventListener('click', (e) => {
    // Предотвращаем клики
    e.preventDefault()
  })
})

Простой пример чтобы попробовать самостоятельно:

<!DOCTYPE html>
<html lang="ru">
  <head>
    <title>aria-disabled</title>
    <meta charset="utf-8" />
    <style>
      button {
        font-size: 16px;
        background: plum;
        display: block;
        border: 2px solid transparent;
        border-radius: 6px;
        padding: 9px 15px;
      }

      [aria-disabled='true'] {
        color: #ffffff;
        opacity: 0.5;
        background-color: #6c757d;
      }
    </style>
  </head>
  <body>
    <button
      id="toggleButton"
      aria-disabled="false"
      onclick="toggleDisabled()"
    >
      Нажми меня
    </button>

    <script>
      function toggleDisabled() {
        const el = document.getElementById('toggleButton')
        if (el.getAttribute('aria-disabled') === 'true') {
          return;
        }
        el.setAttribute('aria-disabled', 'true')
        el.textContent = 'Я теперь не активна'
        el.style.pointerEvents = 'none'
      }
    </script>
  </body>
</html>

Как понять

На элементе с aria-disabled пользователи не могут сделать фокус, узнать о его роли и состоянии, а также скопировать из него данные. Такое поведение может быть у временно неактивных элементов. К примеру, когда в форме заполнены не все поля или какое-то действие в процессе выполнения.

С помощью aria-disabled можете создать гибкие и доступные интерфейсы. Помните, что для полной функциональности нужны CSS и JavaScript. Это не только делает сайт более доступным, но и улучшает пользовательский опыт в целом. Не забудьте также протестировать сайт со скринридерами. ARIA-разметка должна облегчать взаимодействие с интерфейсом всех пользователей, а не усложнять.

Интеграция с современными фреймворками

В современных фреймворках, таких как React или Angular, вы можете интегрировать aria-disabled напрямую в ваш компонентный подход. Например, в React компоненте это может выглядеть так:

function SaveButton({ isSaving }) {
  return (
    <button aria-disabled={isSaving ? 'true' : 'false'}>
      {isSaving ? 'Saving...' : 'Save Changes'}
    </button>
  );
}

Комментарии (5)


  1. monochromer
    16.05.2024 15:17

    Кнопка будет отображаться, но пользователь не сможет по ней кликнуть или сфокусироваться.

    В общем случае, сможет. И даже несмотря на то, что Voice Over сообщил мне "Недоступно, кнопка", я всё равно смог нажать на неё.


    1. teplostanski Автор
      16.05.2024 15:17

      Ваша правда, всё зависит от того, как написан код.


  1. BlackStar1991
    16.05.2024 15:17

    Я так и не понял, зачем использовать aria-disabled если есть disabled ? *Без всяких подводных камней и на любой html элемент. Ещё и меньше символов гоняем по сети, тем самым отодвигая глобальное потепление.


    1. teplostanski Автор
      16.05.2024 15:17
      +1

      Стоит ознакомиться с концепцией a11y


    1. ifap
      16.05.2024 15:17

      Aria-disabled может быть полезно навесить на элемент с невидимостью. Скажем, мы выводим сразу всю форму на странице, но показываем ее отдельные поля по сыбытиям, по мере заполнения предыдущих полей и/или в зависимости от их заполнения. Для скринридера в этом случае может быть неочевидно (в зависимости от верстки), что из элементов должно озвучиваться, а что нет.