Skip to content

Доступність

Вебдоступність (також відома як a11y) відноситься до практики створення вебсайтів, які можуть використовуватися будь-ким — будь то особа з обмеженими можливостями, або хто має інтернет з повільним з’єднанням, застарілим чи несправним обладнанням, або просто знаходиться у несприятливому середовищі. Наприклад, додавання субтитрів до відео допоможе як користувачам із вадами слуху, так і користувачам, які перебувають у гучному середовищі й не чують свій телефон. Аналогічно, якщо переконатися, що ваш текст не надто низькоконтрастний, то це допоможе як користувачам з ослабленим зором, так і користувачам, які намагаються використовувати свій телефон при яскравому сонячному світлі.

Готові почати, але не знаєте з чого?

Ознайомтеся з гідом планування та керування веб-доступністю від World Wide Web Consortium (W3C)

Ви повинні додати посилання у верхню частину кожної сторінки, щоб користувачі могли швидко перейти до області основного вмісту на ній і пропустити елементи, що повторюються, на веб-сторінках.

Зазвичай таке посилання розміщується у верхній частині розмітки головного компонента App.vue, оскільки воно повинно бути першим сфокусованим елементом на всіх сторінках:

template
<ul class="skip-links">
  <li>
    <a href="#main" ref="skipLink" class="skip-link">Skip to main content</a>
  </li>
</ul>

Приховувати посилання, доки воно не отримає фокус, можна за допомогою стилів:

css
.skip-link {
  white-space: nowrap;
  margin: 1em auto;
  top: 0;
  position: fixed;
  left: 50%;
  margin-left: -72px;
  opacity: 0;
}
.skip-link:focus {
  opacity: 1;
  background-color: white;
  padding: 0.5em;
  border: 1px solid black;
}

При переході на іншу сторінку повертаємо фокус назад на посилання. Для цього викличемо відповідний метод на елементі через ref (за умови використання vue-router):

vue
<script>
export default {
  watch: {
    $route() {
      this.$refs.skipLink.focus()
    }
  }
}
</script>
vue
<script setup>
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()
const skipLink = ref()

watch(
  () => route.path,
  () => {
    skipLink.value.focus()
  }
)
</script>

Ознайомитись з документацією про реалізацію посилань для переходу до основного вмісту

Структурування вмісту

Один із найважливіших елементів доступності – розробка дизайну з прицілом на доступність. Дизайн повинен розглядати не лише колірний контраст, шрифт, розмір тексту та мову, але й те, як вміст має бути структурований у додатку.

Заголовки

Користувачі можуть переміщатися в додатку за допомогою заголовків. Наявність описових заголовків для кожного розділу вашого додатка полегшує користувачам передбачити вміст кожного розділу. Що стосується заголовків, є кілька рекомендованих практик доступності:

  • Використовуйте вкладені заголовки в порядку їхньої черговості: <h1> - <h6>
  • Не пропускайте заголовки всередині розділу
  • Використовуйте теги заголовків замість візуальної стилізації тексту під нього

Дізнатись докладніше про заголовки

template
<main role="main" aria-labelledby="main-title">
  <h1 id="main-title">Main title</h1>
  <section aria-labelledby="section-title-1">
    <h2 id="section-title-1"> Section Title </h2>
    <h3>Section Subtitle</h3>
    <!-- Content -->
  </section>
  <section aria-labelledby="section-title-2">
    <h2 id="section-title-2"> Section Title </h2>
    <h3>Section Subtitle</h3>
    <!-- Content -->
    <h3>Section Subtitle</h3>
    <!-- Content -->
  </section>
</main>

Орієнтири

Орієнтири забезпечують програмний доступ до розділів додатку. Користувачі, які використовують допоміжні технології, можуть безпосередньо переходити до кожного розділу додатку, обминаючи решту вмісту. Для цього використовуйте ARIA ролі які допоможуть вам досягти цього.

HTMLARIA рольПризначення орієнтиру
headerrole="banner"Основний заголовок: заголовок сторінки
navrole="navigation"Колекція посилань для переміщення по сторінці або іншим сторінкам documents
mainrole="main"Основний або найважливіший вміст документа.
footerrole="contentinfo"Відомості про головний документ: виноски/авторські права/посилання на конфіденційність
asiderole="complementary"Підтримує основний вміст, але є відокремленим і значущим за власним вмістом
Not availablerole="search"Розділ, що містить функціональність пошуку по додатку
formrole="form"Колекція елементів форми
sectionrole="region"Супутній вміст, який користувач, можливо, захоче вивчити. Для такого елемента потрібно вказати мітку

Порада:

Рекомендується використовувати орієнтири HTML-елементів із надлишковими атрибутами ролей, щоб максимально підвищити сумісність із застарілими версіями браузерів, які не підтримують семантичні елементи HTML5.

Дізнатись докладніше про орієнтири

Семантичні форми

При створенні форми можна використовувати наступні елементи: <form>, <label>, <input>, <textarea>, and <button>

Мітки зазвичай розміщуються зверху або зліва від полів форми:

template
<form action="/dataCollectionLocation" method="post" autocomplete="on">
  <div v-for="item in formItems" :key="item.id" class="form-item">
    <label :for="item.id">{{ item.label }}: </label>
    <input
      :type="item.type"
      :id="item.id"
      :name="item.id"
      v-model="item.value"
    />
  </div>
  <button type="submit">Надіслати</button>
</form>

Зверніть увагу, яким чином ви можете включити autocomplete='on' в елемент форми, і це буде застосовано до всіх полів input у вашій формі. Ви також можете встановити різні значення для атрибута autocomplete для кожного поля input.

Мітки

Надайте мітки, для опису полів форми та для створення зв'язку між елементами з атрибутами for і id:

template
<label for="name">Name</label>
<input type="text" name="name" id="name" v-model="name" />

Якщо оглянути цей елемент через інструменти розробника в Chrome і перейти на вкладку Accessibility у розділі Elements, можна побачити, що поле отримує ім'я з його мітки:

Інструменти розробника Chrome показують ім’я поля, отримане з його мітки

Увага:

Хоча ви, можливо, бачили мітки, де поля input знаходиться всередині, як це:

template
<label>
  Name:
  <input type="text" name="name" id="name" v-model="name" />
</label>

Явна вказівка мітки з відповідним id краще підтримується допоміжними технологіями.

aria-label

Ви також можете дати полю input доступну назву за допомогою aria-label.

template
<label for="name">Name</label>
<input
  type="text"
  name="name"
  id="name"
  v-model="name"
  :aria-label="nameLabel"
/>

Не соромтеся перевірити цей елемент в Chrome DevTools, щоб побачити, як змінилася доступна назва:

Інструменти розробника Chrome показують доступну назву input з aria-label

aria-labelledby

Використання атрибуту aria-labelledby подібний до aria-label, за винятком того, що він використовується, якщо текст мітки видно на екрані. Він створює зв'язок між елементами з атрибутом id, при цьому допускається вказати кілька id:

template
<form
  class="demo"
  action="/dataCollectionLocation"
  method="post"
  autocomplete="on"
>
  <h1 id="billing">Billing</h1>
  <div class="form-item">
    <label for="name">Name:</label>
    <input
      type="text"
      name="name"
      id="name"
      v-model="name"
      aria-labelledby="billing name"
    />
  </div>
  <button type="submit">Надіслати</button>
</form>

Інструменти розробника Chrome показують доступну назву input з aria-labelledby

aria-describedby

aria-describedby використовується так само як aria-labelledby, за винятком надання опису з додатковою інформацією, яка може знадобитися користувачеві. Це можна використовувати для опису критеріїв для будь-якого input:

template
<form
  class="demo"
  action="/dataCollectionLocation"
  method="post"
  autocomplete="on"
>
  <h1 id="billing">Billing</h1>
  <div class="form-item">
    <label for="name">Full Name:</label>
    <input
      type="text"
      name="name"
      id="name"
      v-model="name"
      aria-labelledby="billing name"
      aria-describedby="nameDescription"
    />
    <p id="nameDescription">Please provide first and last name.</p>
  </div>
  <button type="submit">Надіслати</button>
</form>

Ви можете переглянути опис, переглянувши Chrome DevTools:

Інструменти розробника Chrome показують доступну назву input з aria-labelledby і опис з aria-describedby

Підказка всередині поля

Намагайтеся обмежити використання підказок усередині поля, оскільки вони можуть заплутати багатьох користувачів.

Одна із проблем підказок усередині поля в тому, що за умовчанням вони не відповідають критеріям колірного контрасту Спроба виправити колірний контраст робить підказку схожу на попередньо заповнені дані в input полях. Подивіться на наступний приклад: підказка поля Last Name відповідає критеріям колірного контрасту, хоча вона не відрізняється від поля з підставленим значенням:

Доступна підказка

template
<form
  class="demo"
  action="/dataCollectionLocation"
  method="post"
  autocomplete="on"
>
  <div v-for="item in formItems" :key="item.id" class="form-item">
    <label :for="item.id">{{ item.label }}: </label>
    <input
      type="text"
      :id="item.id"
      :name="item.id"
      v-model="item.value"
      :placeholder="item.placeholder"
    />
  </div>
  <button type="submit">Надіслати</button>
</form>
css
/* https://www.w3schools.com/howto/howto_css_placeholder.asp */

#lastName::placeholder {
  /* Chrome, Firefox, Opera, Safari 10.1+ */
  color: black;
  opacity: 1; /* Firefox */
}

#lastName:-ms-input-placeholder {
  /* Internet Explorer 10-11 */
  color: black;
}

#lastName::-ms-input-placeholder {
  /* Microsoft Edge */
  color: black;
}

Всю необхідну інформацію для заповнення найкраще показати поза полів форми.

Інструкції

Додаючи інструкції для полів input, переконайтеся, що їх правильно пов'язано з input. Ви можете надати додаткові інструкції та зв'язати кілька ідентифікаторів усередині aria-labelledby. Це робить дизайн більш гнучким.

template
<fieldset>
  <legend>Використання aria-labelledby</legend>
  <label id="date-label" for="date">Поточна дата:</label>
  <input
    type="date"
    name="date"
    id="date"
    aria-labelledby="date-label date-instructions"
  />
  <p id="date-instructions">MM/DD/YYYY</p>
</fieldset>

Крім того, ви можете прикріпити інструкції до input за допомогою aria-describedby:

template
<fieldset>
  <legend>Using aria-describedby</legend>
  <label id="dob" for="dob">Дата народження:</label>
  <input type="date" name="dob" id="dob" aria-describedby="dob-instructions" />
  <p id="dob-instructions">MM/DD/YYYY</p>
</fieldset>

Приховування вмісту

Зазвичай не рекомендується візуально приховувати мітки, навіть якщо input має доступну назву. Однак, якщо функціональність input можна зрозуміти з навколишнього вмісту, тоді ми можемо приховати візуальну мітку.

Розгляньмо це поле пошуку:

template
<form role="search">
  <label for="search" class="hidden-visually">Пошук: </label>
  <input type="text" name="search" id="search" v-model="search" />
  <button type="submit">Пошук</button>
</form>

Ми можемо це зробити, оскільки кнопка пошуку допоможе користувачам візуально визначити призначення поля input.

Ми можемо використовувати CSS, щоб візуально приховати елементи, але залишити їх доступними для допоміжних технологій:

css
.hidden-visually {
  position: absolute;
  overflow: hidden;
  white-space: nowrap;
  margin: 0;
  padding: 0;
  height: 1px;
  width: 1px;
  clip: rect(0 0 0 0);
  clip-path: inset(100%);
}

aria-hidden="true"

Додавання aria-hidden="true" приховає елемент від допоміжних технологій, але залишить його візуально доступним для інших користувачів. Не використовуйте його на елементах, які можна сфокусувати, а застосовувуйте тільки для декоративних, дублюючих або не відображених на екрані елементах.

template
<p>Це не приховано від програм зчитування з екрана.</p>
<p aria-hidden="true">Це приховано від програм зчитування з екрана.</p>

Кнопки

Якщо ви використовуєте кнопки всередині форми, вам слід вказувати їх тип, щоб запобігти відправленню форми. Ви можете також використовувати input для створення кнопок:

template
<form action="/dataCollectionLocation" method="post" autocomplete="on">
  <!-- Buttons -->
  <button type="button">Скасувати</button>
  <button type="submit">Надіслати</button>

  <!-- Input buttons -->
  <input type="button" value="Cancel" />
  <input type="submit" value="Submit" />
</form>

Функціональні зображення

За допомогою цієї техніки можна створювати функціональні зображення.

  • Input поля

    • Ці зображення виконуватимуть функцію кнопки відправлення у формах
    template
    <form role="search">
      <label for="search" class="hidden-visually">Пошук: </label>
      <input type="text" name="search" id="search" v-model="search" />
      <input
        type="image"
        class="btnImg"
        src="https://img.icons8.com/search"
        alt="Search"
      />
    </form>
  • Іконки

template
<form role="search">
  <label for="searchIcon" class="hidden-visually">Пошук: </label>
  <input type="text" name="searchIcon" id="searchIcon" v-model="searchIcon" />
  <button type="submit">
    <i class="fas fa-search" aria-hidden="true"></i>
    <span class="hidden-visually">Пошук</span>
  </button>
</form>

Стандарти

Консорціум Всесвітньої павутини (W3C) Ініціатива веб-доступності (WAI) розробляє стандарти вебдоступності для різних компонентів:

Гід з доступності веб-вмісту (WCAG)

WCAG 2.1 поширюється на WCAG 2.0 і дозволяє впроваджувати нові технології, враховуючи зміни в Інтернеті. W3C заохочує використання найновішої версії WCAG під час розробки або оновлення політик вебдоступності.

WCAG 2.1 Чотири основні керівні принципи (скорочено POUR):

  • Сприйнятливість
    • Подана інформація має бути доступною для всіх користувачів
  • Керованість
    • Компоненти інтерфейсу, елементи керування та навігації підтримують керування з клавіатури
  • Зрозумілість
    • Інформація та функціонування інтерфейсу мають бути зрозумілі всім користувачам
  • Надійність
    • Робочий доступ до інформації незалежно від технології використовуваної користувачами

Ініціатива веб-доступності – Доступні багаті Інтернет-додатки (WAI-ARIA)

W3C's WAI-ARIA надає вказівки щодо створення динамічного вмісту та розширених елементів керування інтерфейсу користувача.

Ресурси

Документація

Допоміжні технології

Тестування

Користувачі

Згідно з Всесвітньою організацією охорони здоров'я, 15% населення світу має будь-яку форму інвалідності, 2-4% з них — важку форму. За оцінками ВООЗ, у світі налічується приблизно 1 мільярд інвалідів, що робить їх найбільшою групою меншин у світі.

Існує дуже багато інвалідностей, які можна розділити на чотири категорії:

  • Візуальні - Таким користувачам можуть допомогти програми для читання з екрана, збільшення екрану, керування контрастністю екрана або дисплей Брайля..
  • Слухові - Таким користувачам можуть допомогти субтитри, розшифровки або відео з мовою жестів.
  • Рухові - Таким користувачам можуть допомогти різні допоміжні технології при рухових порушеннях: програми для розпізнавання голосу, відстеження очей, пристрої для простого керування, головні щуп-указки, пристрої для керування вказівником миші без рук, безрозмірні трекбол-миші, сенсорні клавіатури та інші допоміжні технології.
  • Когнітивні - Таким користувачам можуть допомогти додаткові медіа, структурована організація вмісту, зрозумілий та простий стиль написання..

Перегляньте наступні посилання з WebAim для розуміння проблеми з боку користувачів:

Доступність has loaded