1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
|
---
title: 'HTML: Хорошая основа для доступности'
slug: Learn/Accessibility/HTML
tags:
- HTML
- a11y
- Клавиатура
- Кнопки
- Начинающий
- Семантика
- Ссылки
- Формы
- вспомогательные технологии
- доступность
translation_of: Learn/Accessibility/HTML
original_slug: Learn/Доступность/HTML
---
<div>{{LearnSidebar}}</div>
<div>{{PreviousMenuNext("Learn/Accessibility/What_is_Accessibility","Learn/Accessibility/CSS_and_JavaScript", "Learn/Accessibility")}}</div>
<p class="summary">Большая часть содержимого интернета может быть сделана доступной просто благодаря использованию правильных HTML элементов по назначению. В этой статье подробно рассмотрено как HTML может быть использован для обеспечения максимальной доступности.</p>
<table class="learn-box standard-table">
<tbody>
<tr>
<th scope="row">Необходимые знания:</th>
<td>Базовая компьютерная грамотность, базовое понимание HTML (смотрите <a href="/ru/docs/Learn/HTML/Введение_в_HTML">Введение в HTML</a>), и понимания, <a href="/ru/docs/Learn/Доступность/What_is_accessibility">что такое доступность</a>.</td>
</tr>
<tr>
<th scope="row">Цель:</th>
<td>
<p>Познакомиться с тем, какие особенности HTML способствуют доступности, и как использовать их на ваших веб-страницах должным образом.</p>
</td>
</tr>
</tbody>
</table>
<h2 id="HTML_и_доступность">HTML и доступность</h2>
<p>По мере изучения HTML: чтения статей, просмотра примеров и т.д., вы заметите одну общую тему — важность использования семантического HTML (иногда называемого POSH (Plain Old Semantic HTML), или «старый добрый семантический HTML»). Это означает использование HTML элементов по назначению насколько это возможно.</p>
<p>Вы спросите, почему это так важно? В конце концов, можно использовать комбинацию CSS и JavaScript, чтобы заставить почти любой HTML элемент вести себя так, как вы захотите. Например, кнопка для воспроизведения видео на вашем сайте может быть обозначена вот так:</p>
<pre class="brush: html"><div>Воспроизвести видео</div></pre>
<p>Но, как вы увидите далее, в данном случае намного логичнее использовать правильный элемент:</p>
<pre class="brush: html"><button>Воспроизвести видео</button></pre>
<p>HTML элементы <code><button></code> не только имеют соответствующие кнопке стили по умолчанию (которые вы скорее всего захотите переписать), они также имеют встроенную доступность с клавиатуры: между ними можно передвигаться с помощью кнопки <kbd>Tab</kbd> и активировать, используя <kbd>Enter</kbd>.</p>
<p>Вёрстка с помощью семантического HTML не займёт больше времени, чем с помощью не семантического (плохого) HTML, если делать это последовательно с самого начала проекта, и это также имеет другие преимущества помимо доступности:</p>
<ol>
<li><strong>Легче разрабатывать</strong> — как сказано выше, вы получаете функционал «из коробки», плюс проще для восприятия.</li>
<li><strong>Лучше для мобильных</strong> — семантический HTML легче по размеру, чем не семантический спагетти-код, и его легче сделать адаптивным.</li>
<li><strong>Хорошо для SEO</strong> — поисковики уделяют больше внимания ключевым словам внутри заголовков, ссылок и т.д., чем ключевым словам, помещённым в не семантический <code><div></code> и т.д., поэтому клиентам будет проще найти ваш сайт.</li>
</ol>
<p>Давайте рассмотрим доступный HTML более детально.</p>
<div class="note">
<p><strong>Примечание</strong>: Желательно, чтобы у вас был установлен скринридер, чтобы вы могли тестировать примеры, приведённые ниже. Посмотрите наше <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Screenreaders">Руководство по скринридерам</a> для более подробной информации.</p>
</div>
<h2 id="Хорошая_семантика">Хорошая семантика</h2>
<p>Мы уже говорили о важности хорошей семантики, и почему нам стоит использовать HTML элементы по назначению. Это нельзя игнорировать, поскольку это одно из основных мест, где ломается доступность из-за плохой семантики, если должным образом не уделять внимания.</p>
<p>В интернете люди делают очень странные вещи с HTML разметкой. Некоторые злоупотребляют HTML, используя устаревшие практики, которые не были полностью забыты, а некоторые просто не знают. В любом случае, вам стоит заменить по возможности плохой код, где бы вы его не увидели.</p>
<p>У вас не всегда есть возможность избавиться от плохой вёрстки: ваши страницы могут быть сгенерированы каким-нибудь фреймворком на стороне сервера, над которым у вас нет полного контроля, или на страницах есть сторонний контент (такой как рекламные баннеры), которые вы также не контролируете.</p>
<p>Цель не «всё или ничего», однако — каждое улучшение, которое вам под силу сделать, поможет обеспечить доступность.</p>
<h3 id="Текстовый_контент">Текстовый контент</h3>
<p>Одно из самых лучших вспомогательных средств доступности для пользователя скринридера — хорошая структура заголовков, параграфов, список и т.д. Пример хорошей семантики может выглядеть так:</p>
<pre class="brush: html example-good line-numbers language-html"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>h1</span><span class="punctuation token">></span></span>Мой заголовок<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>h1</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>p</span><span class="punctuation token">>Это первый раздел моей страницы.</span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>p</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>p</span><span class="punctuation token">>Я добавлю ещё один параграф тут.</span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>p</span><span class="punctuation token">>
<ol>
<li>Это</li>
<li>список для</li>
<li>чтения</li>
</ol></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>h2</span><span class="punctuation token">></span></span>Мой подзаголовок<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>h2</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>p</span><span class="punctuation token">></span></span>Это первый подраздел моей страницы. Я бы хотела, чтобы люди могли найти этот контент!<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>p</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>h2</span><span class="punctuation token">>Мой второй подзаголовок</</span></span><span class="tag token"><span class="tag token">h2</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>p</span><span class="punctuation token">></span></span>Это второй подраздел. Думаю, он намного интереснее, чем предыдущий.<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>p</span><span class="punctuation token">></span></span></code></pre>
<p>Мы подготовили версию с длинными текстом, чтобы вы попробовали со скринридером (смотрите <a href="http://mdn.github.io/learning-area/accessibility/html/good-semantics.html">good-semantics.html</a>). Если вы попробуете поперемещаться, то увидите, как легко ориентироваться на странице:</p>
<ol>
<li>Скринридер озвучивает каждый заголовок по мере перемещения, оповещая вас, что является заголовком, а что параграфом. </li>
<li>Он останавливается после каждого элемента, позволяя вам переместиться в любое другое место, которое вам надо.</li>
<li>Во многих скринридерах Вы можете перемещаться к следующему/предыдущему заголовкам.</li>
<li>Во многих скринридерах Вы также можете вызвать список всех заголовков, который можно использовать как содержание, чтобы найти определённую информацию. </li>
</ol>
<p>Иногда люди используют презентационные элементы HTML и перенос строки, чтобы написать заголовки или параграфы:</p>
<pre class="brush: html example-bad line-numbers language-html"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>font</span> <span class="attr-name token">size</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>7<span class="punctuation token">"</span></span><span class="punctuation token">>Мой заголовок</span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>font</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="punctuation token">Это первый раздел моей страницы.</span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="punctuation token">Я добавлю ещё один параграф тут.</span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">>
1. Это
</span><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">>
2. список для
</span><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">>
3. чтения
</span><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>font</span> <span class="attr-name token">size</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>5<span class="punctuation token">"</span></span><span class="punctuation token">>Мой подзаголовок</span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>font</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span></span>
Это первый подраздел моей страницы. Я бы хотела, чтобы люди могли найти этот контент!
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>font</span> <span class="attr-name token">size</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>5<span class="punctuation token">"</span></span><span class="punctuation token">>Мой второй подзаголовок</span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>font</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span></span>
Это второй подраздел. Думаю, он намного интереснее, чем предыдущий.</code></pre>
<p>Если вы попробуете полную версию с помощью скринридера (смотрите <a href="http://mdn.github.io/learning-area/accessibility/html/bad-semantics.html">bad-semantics.html</a>), вам не слишком это понравится: скринридеру нечего использовать как ориентир, поэтому вы не сможете получить содержание, а вся страница для скринридера — это один большой блок, поэтому он озвучит всё за один раз, без остановок. </p>
<p>Есть и другие проблемы, помимо доступности — сложнее стилизовать контент, используя CSS, или манипулировать им с помощью JavaScript, например, потому что там нет элементов, которые можно использовать как селекторы.</p>
<h4 id="Использование_понятного_языка">Использование понятного языка</h4>
<p>Язык, который вы используете, также может влиять на доступность. В целом, лучше использовать понятный язык, который не слишком сложный, и который не использует ненужные жаргоны и сленг. Это помогает не только людям с когнитивными или другими нарушениями, но и читателям, для которых текст написан не на родном языке, молодым людям... на самом деле всем! Кроме этого, стоит избегать использование языка и символов, которые не могут быть чётко озвучено скринридером. Например:</p>
<ul>
<li>Не используйте тире, если можете избежать этого. Вместо «5-7», напишите «от 5 до 7».</li>
<li>Не пишите сокращения: вместо «Янв» пишите «Январь».</li>
<li>Расшифровывайте аббревиатуры, как минимум один или два раза. Вместо «HTML» при первом употреблении, пишите «Hypertext Markup Language».</li>
</ul>
<h3 id="Вёрстка">Вёрстка</h3>
<p>В старые недобрые времена, люди верстали с помощью HTML-таблиц: использовали различные табличные ячейки для размещения шапки, подвала, боковую панель, колонку с основным контентом и т.д. Это плохая идея, потому что скринридер, скорее всего, выдаст непонятную озвучку, особенно, если раскладка сложная и имеет много вложенных таблиц.</p>
<p>Посмотрите пример табличной вёрстки, открыв <a href="http://mdn.github.io/learning-area/accessibility/html/table-layout.html">table-layout.html</a>, которая выглядит примерно так:</p>
<pre class="brush: html"><table width="1200">
<!-- main heading row -->
<tr id="heading">
<td colspan="6">
<h1 align="center">Шапка</h1>
</td>
</tr>
<!-- nav menu row -->
<tr id="nav" bgcolor="#ffffff">
<td width="200">
<a href="#" align="center">Главная</a>
</td>
<td width="200">
<a href="#" align="center">Наша команда</a>
</td>
<td width="200">
<a href="#" align="center">Проекты</a>
</td>
<td width="200">
<a href="#" align="center">Контакты</a>
</td>
<td width="300">
<form width="300">
<input type="search" name="q" placeholder="Поиск" width="300">
</form>
</td>
<td width="100">
<button width="100">Вперёд!</button>
</td>
</tr>
<!-- spacer row -->
<tr id="spacer" height="10">
<td>
</td>
</tr>
<!-- main content and aside row -->
<tr id="main">
<td id="content" colspan="4" bgcolor="#ffffff">
<!-- основной контент -->
</td>
<td id="aside" colspan="2" bgcolor="#ff80ff" valign="top">
<h2>Связанный контент</h2>
<!-- второстепенный контент -->
</td>
</tr>
<!-- spacer row -->
<tr id="spacer" height="10">
<td>
</td>
</tr>
<!-- footer row -->
<tr id="footer" bgcolor="#ffffff">
<td colspan="6">
<p>© 2050 никто. Все права защищены.</p>
</td>
</tr>
</table></pre>
<p>Если вы попробуете поперемещаться с помощью скринридера, вероятно, он скажет вам, что перед вами таблица (хотя некоторые скринридеры могу различать табличную вёрстку от таблиц данных). После этого, скорее всего (в зависимости от того, какой скринридер вы используете), вам придётся переместиться в таблицу как в объект, посмотрев каждый элемент по отдельности, затем выйти из таблицы, чтобы продолжить перемещение по контенту.</p>
<p>Табличная вёрстка — пережиток прошлого, который имел смысл, когда поддержка CSS не была сильно распространена среди браузеров, но она создаёт путаницу среди пользователей скринридеров, и плоха по многим другим причинам (злоупотребление таблицами, пожалуй, требует больше разметки, делает дизайн менее гибким). Не делайте так!</p>
<p>Вы можете проверить эти утверждения, сравнив предыдущий опыт с <a href="http://mdn.github.io/learning-area/html/introduction-to-html/document_and_website_structure/">более современной структурой веб-сайта</a>, которая выглядит так:</p>
<pre class="brush: html"><header>
<h1>Шапка</h1>
</header>
<nav>
<!-- основная навигация -->
</nav>
<!-- Основной контент нашей страницы -->
<main>
<!-- На ней есть статьи -->
<article>
<h2>Заголовок статьи</h2>
<!-- сама статья -->
</article>
<aside>
<h2>Связанный контент</h2>
<!-- второстепенный контент -->
</aside>
</main>
<!-- А здесь наш основной подвал, который используется на всех страницах нашего сайта -->
<footer>
<!-- здесь содержимое подвала -->
</footer></pre>
<p>Если вы попробуете нашу более современную структуру с помощью скринридера, вы увидите, что разметка больше не сбивает с толку скринридер. Она также более компактная с точки зрения размера кода, что означает, его легче поддерживать, а пользователям меньше скачивать (особенно для тех, у кого медленный интернет).</p>
<p>На что ещё стоит обратить внимание при вёрстке — это использование семантических HTML5 элементов, которые можно увидеть в примере выше (смотрите <a href="/ru/docs/Web/HTML/Element#Секционирование_содержания">секционирование содержания)</a>: вы можно верстать, используя только вложенные {{htmlelement("div")}} элементы, но лучше использовать соответствующие секционные элементы, чтобы обернуть вашу основную навигацию ({{htmlelement("nav")}}), футер ({{htmlelement("footer")}}), повторяющийся контент ({{htmlelement("article")}}) и т.д. Эти элементы предоставляют дополнительную семантику для скринридеров (и других инструментов), чтобы давать пользователю дополнительную информацию о контенте, по которому они перемещаются (смотрите статью <a href="http://www.weba11y.com/blog/2016/04/22/screen-reader-support-for-new-html5-section-elements/">Screen Reader Support for new HTML5 Section Elements</a> для представления поддержки этих элементов с помощью скринридеров).</p>
<div class="note">
<p><strong>Примечание</strong>: Помимо того, что ваш контент имеет семантическую и красивую разметку, он должен иметь логический порядок в его исходном коде — позже вы всегда можете разместить элементы там, где хотите, с помощью CSS, но располагать элементы в правильном порядке нужно в самом начале, чтобы то, что зачитывает пользователям скринридер, имело смысл.</p>
</div>
<h3 id="Элементы_интерфейса">Элементы интерфейса</h3>
<p>Под элементами интерфейса мы подразумеваем основные элементы веб-страниц, с которыми взаимодействует пользователь, в основном это кнопки, ссылки и элементы форм. В этом разделе мы рассмотрим основные проблемы доступности, которые стоит учитывать при создании таких элементов. В следующих статьях про WAI-ARIA и мультимедиа мы рассмотрим другие аспекты доступности пользовательского интерфейса.</p>
<p>Одним из ключевых аспектов доступности элементов интерфейса является то, что браузеры по умолчанию позволяют управлять ими с помощью клавиатуры. Вы можете проверить это, открыв в новой вкладке <a href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html">native-keyboard-accessibility.html </a>(смотрите <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html">исходный код</a>). Попробуйте понажимать клавишу <kbd>Tab</kbd>, после нескольких нажатий вы заметите, что фокус перемещается по всем фокусируемым элементам. Сфокусированные элементы подсвечиваются браузерными стилями по умолчанию (в зависимости от браузера они немного разные), чтобы можно было понять, какой элемент в фокусе.</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/14215/button-focused-unfocused.png" style="border-style: solid; border-width: 1px; display: block; height: 39px; margin: 0px auto; width: 288px;"></p>
<p>Вы можете нажать <kbd>Enter</kbd>, чтобы перейти по сфокусированной ссылке или нажать кнопку (мы добавили немного JavaScript, чтобы кнопки выводили окно с сообщением), или начать печатать в текстовом поле (другие элементы формы имеют разное управление, например, у элемента {{htmlelement("select")}} можно отобразить опции и переключаться между ними, используя клавиши-стрелки вверх и вниз).</p>
<div class="note">
<p><strong>Примечание</strong>: Различные браузеры могут иметь разное управление с клавиатуры. Для более подробной информации смотрите <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Using_native_keyboard_accessibility">Using native keyboard accessibility.</a></p>
</div>
<p>Такое поведение вы получаете сразу по умолчанию, просто используя правильные элементы, например:</p>
<pre class="brush: html example-good"><h1>Ссылки</h1>
<p>Это ссылка ведёт на сайт <a href="https://www.mozilla.org">Mozilla</a>.</p>
<p>Другая ссылка на <a href="https://developer.mozilla.org">Mozilla Developer Network</a>.</p>
<h2>Кнопки</h2>
<p>
<button data-message="Это из первой кнопки">Нажми меня!</button>
<button data-message="Это из второй кнопки">Меня тоже нажми!</button>
<button data-message="Это из третьей кнопки">И меня!</button>
</p>
<h2>Форма</h2>
<form>
<div>
<label for="name">Укажите ваше имя:</label>
<input type="text" id="name" name="name">
</div>
<div>
<label for="age">Укажите ваш возраст:</label>
<input type="text" id="age" name="age">
</div>
<div>
<label for="mood">Выберите ваше настроение:</label>
<select id="mood" name="mood">
<option>Счастливый</option>
<option>Грустный</option>
<option>Злой</option>
<option>Обеспокоенный</option>
</select>
</div>
</form></pre>
<p>Это предполагает использование соответствующим образом ссылок, кнопок, элементов форм и меток (включая элемент {{htmlelement("label")}} для элементов форм).</p>
<p>Однако, опять же, люди иногда делают странные вещи с HTML. Например, иногда вы видите кнопки, размеченные с помощью элемента {{htmlelement("div")}}:</p>
<pre class="brush: html example-bad"><div data-message="Это из первой кнопки">Нажми меня!</div>
<div data-message="Это из второй кнопки">Меня тоже нажми!</div>
<div data-message="Это из третьей кнопки">И меня!</div></pre>
<p>Такой код не советуется использовать: вы сразу же теряете нативную доступность с клавиатуры, которая у вас была бы, если просто использовать элемент {{htmlelement("button")}}, к тому же {{htmlelement("div")}} по умолчанию не имеет кнопочных стилей.</p>
<h4 id="Добавление_доступности_с_клавиатуры">Добавление доступности с клавиатуры</h4>
<p>Для добавления доступности с клавиатуры несоответствующим элементам придётся немного поработать (вы можете посмотреть пример, открыв <a class="external external-icon" href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/fake-div-buttons.html">fake-div-buttons.html</a>, а также <a class="external external-icon" href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/accessibility/fake-div-buttons.html">исходный код</a>). Мы дали нашим поддельным <code><div></code>-кнопкам возможность фокусироваться (в том числе через <kbd>Tab</kbd>), указав атрибут <code>tabindex="0"</code>:</p>
<pre class="brush: html"><div data-message="Это из первой кнопки" tabindex="0">Кликни меня!</div>
<div data-message="Это из второй кнопки" tabindex="0">Меня тоже кликни!</div>
<div data-message="Это из третьей кнопки" tabindex="0">И меня!</div></pre>
<p>Атрибут {{htmlattrxref("tabindex")}} в первую очередь предназначен для того, чтобы менять порядок фокусируемых элементов в последовательной навигации (указанный в виде положительного целого числа). Это почти всегда — плохая идея, которая может вызвать большую путаницу. Используйте его, если он правда необходим, например, если визуальный порядок сильно отличается от исходного, и вы хотите более логичную последовательную навигацию. Есть два варианта значений <code>tabindex</code>:</p>
<ul>
<li><code>tabindex="0"</code> — как указано выше, это значение позволяет элементу быть выделенным и достигнутым с помощью последовательной навигации. Это самое полезное значение <code>tabindex</code>.</li>
<li><code>tabindex="-1"</code> — позволяет элементам, которые обычно не принимают фокусное выделение, получать его программно, например, с помощью JavaScript, или как цель якорной ссылки.</li>
</ul>
<p>Хотя дополнение, которые мы сделали, позволяет нам перемещаться по кнопкам с помощью <kbd>Tab</kbd>, оно не позволяет нам активировать их кнопкой <kbd>Enter</kbd>. Для этого нам необходимо добавить хитрый кусочек JavaScript:</p>
<pre class="brush: js line-numbers language-js"><code class="language-js">document<span class="punctuation token">.</span>onkeydown <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>e<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">if</span><span class="punctuation token">(</span>e<span class="punctuation token">.</span>keyCode <span class="operator token">===</span> <span class="number token">13</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> <span class="comment token">// Кнопка Enter</span>
document<span class="punctuation token">.</span>activeElement<span class="punctuation token">.</span><span class="function token">click</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre>
<p>Мы навешиваем обработчик событий на <code>document</code> для обнаружения нажатий с клавиатуры. Далее, через свойство объекта события <code><a href="/ru/docs/Web/API/KeyboardEvent/keyCode">keyCode</a></code>, проверяем, какая кнопка была нажата. Если код клавиши совпадает с кодом клавиши <kbd>Enter</kbd>, мы выполняем функцию, которая хранится в обработчике кнопки <code>onclick</code>, используя <code>document.activeElement.click().</code> <code><a href="/ru/docs/Web/API/Document/activeElement">activeElement</a></code> возвращает текущий сфокусированный элемент.</p>
<p>Слишком много дополнительной мороки с добавлением такой функциональности. И обязательно будут ещё проблемы. <strong>Лучше просто сразу использовать правильные элементы по назначению.</strong></p>
<h4 id="Содержательные_текстовые_метки">Содержательные текстовые метки</h4>
<p>Текстовые метки (описания) для элементов интерфейса полезны всем пользователям, но их правильное описание — особенно важно для пользователей с ограниченными способностями.</p>
<p>Вы должны следить за тем, чтобы кнопки и ссылки имели понятные и уникальные текстовые описания. Не используйте фразу «Кликните здесь», потому что пользователи скринридеров иногда вызывают список кнопок и элементов форм. В примере ниже можно увидеть такой список, вызванный из VoiceOver на Mac.</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/14335/voiceover-formcontrols.png" style="display: block; height: 604px; margin: 0px auto; width: 802px;"></p>
<p>Удостоверьтесь, что описания вне контекста имеют смысл, так же как и в контексте параграфа, в котором они содержаться. Например, вот хороший текст для ссылки:</p>
<pre class="brush: html example-good"><p>Киты очень классные существа. <a href="whales.html">Узнай больше о китах</a>.</p></pre>
<p>а это плохой текст для ссылки:</p>
<pre class="brush: html example-bad"><p>Киты очень классные существа. Чтобы узнать больше о китах, <a href="whales.html">нажмите здесь</a>.</p></pre>
<div class="note">
<p><strong>Примечание: </strong>Более подробно о создании ссылок и лучших практиках можно почитать в статье «<a href="/ru/docs/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks">Создание ссылок</a>». Также посмотреть на примеры хороших и плохих ссылок можно на <a class="external external-icon" href="http://mdn.github.io/learning-area/accessibility/html/good-links.html">good-links.html</a> и <a class="external external-icon" href="http://mdn.github.io/learning-area/accessibility/html/bad-links.html">bad-links.html</a>. </p>
</div>
<p>Описания форм также важны для понимания, что нужно вводить в каждое текстовое поле. Следующий пример кажется достаточно разумным:</p>
<pre class="brush: html example-bad">Укажите ваше имя: <input type="text" id="name" name="name"></pre>
<p>Однако, это не совсем удобно для пользователей с ограниченными возможностями. В примере нет ничего, что могло бы однозначно связать описание текстового поля с самим текстовым полем, и чётко указать, как его заполнить, если вы не можете видеть. Если бы вы воспользовались скринридером, скорее всего он озвучил описание примерно как «редактировать текст».</p>
<p>Следующий пример намного лучше:</p>
<pre class="brush: html example-good"><div>
<label for="name">Укажите ваше имя:</label>
<input type="text" id="name" name="name">
</div></pre>
<p>С такой разметкой описание будет явно связано с текстовым полем, и будет звучать как «Укажите ваше имя: редактировать текст».</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/14337/voiceover-good-form-label.png" style="display: block; margin: 0 auto;"></p>
<p>Как бонус, в большинстве браузеров привязка описания к полю ввода означает, что вы можете щелкнуть по описанию, чтобы выбрать/активировать элемент формы. Это облегчает нажатие на элемент формы из-за увеличенной зоны нажатия.</p>
<div class="note">
<p><strong>Примечание</strong>: Посмотреть на хорошие и плохие пример форм можно на <a href="http://mdn.github.io/learning-area/accessibility/html/good-form.html">good-form.html</a> и <a href="http://mdn.github.io/learning-area/accessibility/html/bad-form.html">bad-form.html</a>.</p>
</div>
<h2 id="Доступные_таблицы">Доступные таблицы</h2>
<p>Обычные таблицы с данными можно сверстать очень простой разметкой, например:</p>
<pre class="brush: html"><table>
<tr>
<td>Имя</td>
<td>Возраст</td>
<td>Пол</td>
</tr>
<tr>
<td>Гавриил</td>
<td>13</td>
<td>Мужской</td>
</tr>
<tr>
<td>Эвелина</td>
<td>8</td>
<td>Женский</td>
</tr>
<tr>
<td>Фрида</td>
<td>5</td>
<td>Женский</td>
</tr>
</table></pre>
<p>Но есть проблемы — пользователи скринридера никак не смогут связать вместе строки или столбцы в группу данных. Чтобы это сделать, нужно знать какие из строк являются заголовками, и озаглавливают ли они строки, столбцы и т.д. Для таблицы выше это можно определить только визуально (попробуйте сами на примере, открыв <a href="http://mdn.github.io/learning-area/accessibility/html/bad-table.html">bad-table.html</a>).</p>
<p>Теперь посмотрим на <a href="https://github.com/mdn/learning-area/blob/master/css/styling-boxes/styling-tables/punk-bands-complete.html">пример таблицы с панк-группами</a>, где можно увидеть несколько вспомогательных средств:</p>
<ul>
<li>Заголовки таблиц определены, используя элементы {{htmlelement("th")}}; можно также указать являются ли они заголовками для строк или столбцов с помощью атрибута <code>scope</code>. Это даёт нам полные группы данных, которые скринридер обработает как отдельные блоки.</li>
<li>Элемент {{htmlelement("caption")}} и атрибут <code>summary</code> у элемента {{htmlelement("table")}} выполняют похожую работу — они выступают в качестве альтернативного текста для таблицы, предоставляя пользователям скринридера краткое содержание. Элемент <code><caption></code> обычно предпочтительнее, так как контент становится доступнее и для зрячих пользователей, которые могут посчитать это полезным. На самом деле необязательно ни то, ни другое.</li>
</ul>
<div class="note">
<p><strong>Примечание</strong>: Более подробную информацию о доступных таблицах можно узнать в статье <a href="/ru/docs//ru/docs/Learn/HTML/Tables/Advanced">HTML-таблицы: продвинутые возможности и доступность</a>.</p>
</div>
<h2 id="Альтернативный_текст">Альтернативный текст</h2>
<p>В то время как текстовый контент доступен по умолчанию, этого нельзя сказать о мультимедийном контенте — изображения/видео-контент не может быть просмотрен людьми с нарушениями зрения, а аудио контент не может быть услышан людьми с нарушениями слуха. Мы подробно рассмотрим видео и аудио контент в статье о доступности мультимедиа позже, но в этой статье мы рассмотрим доступность для простого элемента {{htmlelement("img")}}.</p>
<p>У нас есть простой пример, <a href="http://mdn.github.io/learning-area/accessibility/html/accessible-image.html">accessible-image.html</a>, который содержит четыре копии одного и того же изображения:</p>
<pre><img src="dinosaur.png">
<img src="dinosaur.png"
alt="Красный тираннозавр Рекс: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов.">
<img src="dinosaur.png"
alt="Красный тираннозавр Рекс: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов."
title="Красный динозавр Mozilla">
<img src="dinosaur.png" aria-labelledby="dino-label">
<p id="dino-label">Красный тираннозавр Рекс Mozilla: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов.</p>
</pre>
<p>Первое изображение, когда оно просматривается программой чтения с экрана, не очень помогает пользователю — например, VoiceOver озвучивает его как «/dinosaur.png, image». Он озвучивает имя файла, чтобы попытаться помочь. В этом примере пользователь, по крайней мере, будет знать, что это какой-то динозавр, но часто файлы могут загружаться с программно-генерируемыми именами (например, с цифровой камеры), и эти имена файлов, скорее всего, не обеспечат контекста для содержимого изображения.</p>
<div class="note">
<p><strong>Примечание</strong>: Вот почему вы никогда не должны включать текстовое содержимое в изображение — скринридеры просто не могут получить к нему доступ.Есть и другие недостатки — вы не можете выбрать его и скопировать/вставить. Просто не делайте этого!</p>
</div>
<p>Когда скринридер встретит второе изображение, он озвучит атрибут <code>alt</code> полностью: «Красный тираннозавр Рекс: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов».</p>
<p>Это подчёркивает важность не только использования содержательных файловых имён в случаях отсутствия, так называемого, <strong>альтернативного текста</strong>, но также важность предоставления альтернативного текста в атрибуте <code>alt</code>, где это возможно. Заметьте, что содержание атрибута <code>alt</code> должно всегда предоставлять прямое представление изображения и то, что оно визуально передаёт. Любые личные знания или дополнительное описание не должны быть включены, так как это не принесёт пользы людям, которые не видели изображение ранее.</p>
<p>Также стоит учитывать, имеют ли изображения значение внутри вашего контента, или они исключительно для украшения без смысла. Если они декоративные, лучше оставить значение атрибута <code>alt</code> пустым (смотрите «<a href="#Пустые_атрибуты_alt">Пустые атрибуты alt</a>») или просто вставить их как фон с помощью CSS.</p>
<div class="note">
<p><strong>Примечание</strong>: Для более подробной информации об изображениях и лучших практиках читайте «<a href="/ru/docs/Learn/HTML/Multimedia_and_embedding/Изображения_в_HTML">Изображения в HTML»</a> и «<a href="/ru/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images">Адаптивные изображения</a>».</p>
</div>
<p>Если вы всё же хотите предоставить дополнительную контекстуальную информацию, поместите её в тексте рядом с изображением или внутри атрибута <code>title</code>, как показано ниже. В этом случае большинство скринридеров озвучат альтернативный текст, атрибут <code>title</code> и имя файла. Дополнительно, при наведении мышкой браузеры отобразят текст из атрибута <code>title</code> как всплывающую подсказку.</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/14333/title-attribute.png" style="display: block; margin: 0 auto;"></p>
<p>Давайте взглянем на четвёртый способ:</p>
<pre class="brush: html"><img src="dinosaur.png" aria-labelledby="dino-label">
<p id="dino-label">Красный тираннозавр Mozilla ... </p></pre>
<p>В этом случае мы вообще не используем атрибут <code>alt</code>. Вместо этого мы представили наше описание изображения как обычный параграф, указали <code>id</code>, и потом использовали атрибут <code>aria-labelledby</code>, сославшись на тот <code>id</code>. Это вынуждает скринридеры использовать параграф как альтернативный текст/описание изображения. Это особенно удобно, если вы хотите использовать один текст как описание для нескольких изображений, что невозможно с помощью атрибута <code>alt</code>.</p>
<div class="note">
<p><strong>Примечание</strong>: <code>aria-labelledby</code> — часть спецификации <a href="https://www.w3.org/TR/wai-aria-1.1/">WAI-ARIA</a>, которая позволяет разработчиками добавлять, где требуется, дополнительную семантику разметке для улучшения доступности при использовании скринридеров. Чтобы узнать больше о том, как это работает, читайте статью <a href="/ru/docs/Learn/Accessibility/WAI-ARIA_basics">«Основы WAI-ARIA».</a></p>
</div>
<h3 id="Другие_механизмы_альтернативного_текста">Другие механизмы альтернативного текста</h3>
<p>У изображений есть ещё один механизм для предоставления описательного текста. Например, есть атрибут <code>longdesc</code>, который предназначен для указания отдельной веб-страницы, содержащей расширенное описание изображения:</p>
<pre class="brush: html"><img src="dinosaur.png" longdesc="dino-info.html"></pre>
<p>Звучит, как хорошая идея, особенно для такой инфографики как диаграммы с большим количеством информации, которую, в качестве альтернативы, можно представить в виде доступной таблицы с данными (смотрите предыдущий раздел). Однако, <code>longdesc</code> нестабильно поддерживается скринридерами, и контент полностью недоступен пользователям, которые не используют скринридеры. Пожалуй, намного лучше будет вставить длинное описание на страницу вместе с изображением, или указать обычную ссылку.</p>
<p>HTML5 содержит два новых элемента — {{htmlelement("figure")}} и {{htmlelement("figcaption")}}, которые, как предполагается, должны связывать какую-любо фигуру (всё что угодно, необязательно изображение) с заголовком фигуры:</p>
<pre class="brush: html"><figure>
<img src="dinosaur.png" alt="Тираннозавр организации Mozilla">
<figcaption>Красный тираннозавр Рекс: стоящий как человек двуногий динозавр, с маленькими передними лапами и большой головой с большим количеством острых зубов.</figcaption>
</figure></pre>
<p>К сожалению, большинство скринридеров, кажется, пока ещё не умеют связывать заголовки фигур с самими фигурами, но такая структура элементов удобна для CSS стилизации, к тому же, она предоставляет способ расположить описание рядом с изображением в исходнике.</p>
<h3 id="Пустые_атрибуты_alt">Пустые атрибуты alt</h3>
<pre class="brush: html"><h3>
<img src="article-icon.png" alt="">
Тираннозавр Рекс: король динозвров
</h3></pre>
<p>Бывает, что в дизайне страницы присутствуют изображения, но они исполняют декоративную роль. В примере выше вы можете заметить, что у изображения пустой атрибут <code>alt</code> — это сделано, чтобы скринридер опознал изображение, но не стал озвучивать её описание (вместо этого, он бы озвучил её как «изображение», или аналогично).</p>
<p>Причина, по которой стоит использовать пустой атрибут <code>alt</code>, вместо того, чтобы просто его не указывать в том, что большинство скринридеров объявят весь URL-адрес изображения, если не указан <code>alt</code>. В пример выше изображение используется как украшение для связанного с ним заголовка. В таких случаях и случаях, когда изображение является украшением и не имеет ценное содержание, вы должны использовать пустой атрибут <code>alt</code>. Другой вариант — использовать aria роль role="presentation". Это также предотвратит озвучивание скринридером альтернативного текста.</p>
<div class="note">
<p><strong>Примечание</strong>: По возможности для отображения декоративных изображений вы должны использовать CSS.</p>
</div>
<h2 id="Заключение">Заключение</h2>
<p>Теперь вы должны хорошо разбираться в написании доступного HTML для большинства случаев. Наша статья про основы WAI-ARIA также заполнит пробелы в знаниях, но эта статья посвящена основам. Далее мы рассмотрим CSS и JavaScript, и как хорошо или плохое их использование влияет на доступность. </p>
<p>{{PreviousMenuNext("Learn/Accessibility/What_is_Accessibility","Learn/Accessibility/CSS_and_JavaScript", "Learn/Accessibility")}}</p>
<h2 id="В_этом_модуле">В этом модуле</h2>
<ul>
<li><a href="/ru/docs/Learn/Доступность/What_is_accessibility">Что такое доступность?</a></li>
<li><a href="/ru/docs/Learn/Accessibility/HTML">HTML: Хорошая основа для доступности</a></li>
<li><a href="/ru/docs/Learn/Accessibility/CSS_and_JavaScript">CSS и JavaScript доступность - лучшие практики</a></li>
<li><a href="/ru/docs/Learn/Accessibility/WAI-ARIA_basics">Основы WAI-ARIA</a></li>
<li><a href="/ru/docs/Learn/Accessibility/Multimedia">Доступность мультимедиа</a></li>
<li><a href="/ru/docs/Learn/Accessibility/Mobile">Мобильная доступность</a></li>
<li><a href="/ru/docs/Learn/Accessibility/Accessibility_troubleshooting">Устранение проблем доступности</a></li>
</ul>
|