aboutsummaryrefslogtreecommitdiff
path: root/files/ru/learn/accessibility/css_and_javascript/index.html
blob: 16c9b2e1821447de42b96d12fb39725a35ce738f (plain)
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
---
title: CSS и JavaScript доступность - лучшие практики
slug: Learn/Accessibility/CSS_and_JavaScript
tags:
  - Доступность
  - Статья
  - CSS
  - CodingScripting
  - Руководство
  - JavaScript
  - Обучение
  - Цвет
  - Контраст
  - Скрытие
  - Ненавязчивость
translation_of: Learn/Accessibility/CSS_and_JavaScript
original_slug: Learn/Доступность/CSS_and_JavaScript
---
<div>{{LearnSidebar}}</div>

<div>{{PreviousMenuNext("Learn/Accessibility/HTML","Learn/Accessibility/WAI-ARIA_basics", "Learn/Accessibility")}}</div>

<p class="summary">В CSS и JavaScript есть множество возможностей для создания доступных интерфейсов. Но это обоюдоострый клинок — при неосторожном обращении они могут доступности и значительно навредить. В этой статье мы рассмотрим лучшие практики в CSS и JavaScript, которые позволят даже сложному контенту оставаться доступным настолько, насколько это возможно.</p>

<table class="learn-box standard-table">
 <tbody>
  <tr>
   <th scope="row">Необходимые знания:</th>
   <td>Базовая компьютерная грамотность, базовое понимание HTML, CSS и JavaScript, а также понимание, <a href="/ru/docs/Learn/Accessibility/What_is_accessibility">что такое доступность</a>.</td>
  </tr>
  <tr>
   <th scope="row">Цель:</th>
   <td>Ознакомиться со способами использования CSS и JavaScript таким образом, чтобы не вредить доступности интерфейсов, а даже улучшать её.</td>
  </tr>
 </tbody>
</table>

<h2 id="CSS_and_JavaScript_are_accessible">Влияют ли CSS и JavaScript на доступность?</h2>

<p>По сравнению с HTML, влияние CSS и JavaScript на доступность веб-страниц не столь велико, однако они всё равно способны внести свой вклад — как положительный, так и отрицательный. Иными словами, важно ознакомиться с рекомендациями по использованию CSS и JavaScript без риска случайно сломать доступность ваших веб-страниц.</p>

<h2 id="CSS">CSS</h2>

<p>Начнём наш обзор с CSS.</p>

<h3 id="Correct_semantics_and_user_expectation">Правильная семантика и ожидаемое пользователем поведение</h3>

<p>При помощи CSS мы можем заставить любой HTML-элемент выглядеть <em>как угодно</em>, однако это не означает, что следует так делать. Как мы часто упоминали в статье <a href="/ru/docs/Learn/Accessibility/HTML">HTML: Хорошая основа для доступности</a>, для каждой задачи всегда стоит использовать соответствующий семантический элемент. Если не следовать данному правилу, то могут возникнуть проблемы и неудобства для всех, а в особенности для людей с ограниченными возможностями здоровья. Правильная семантика также тесно связана с ожидаемым пользователями поведением — элементы выглядят и ведут себя определенным образом, в соответствии с задачами, которые они решают. Внешний вид и поведение элементов интерфейса часто универсальны между разными сайтами и даже браузерами — пользователи привыкают к этому и им проще ориентироваться в интерфейсах.</p>

<p>Например, пользователь скринридера не сможет передвигаться по странице с помощью заголовков, если разработчик не разметит контент корректно с их помощью. Аналогично, если заголовок стилизован так, что вовсе не распознается как заголовок, то он теряет своё визуальное значение.</p>

<p>Эмпирическое правило гласит: стилизовать элементы страницы, подгоняя их под требуемый дизайн, можно до той степени, пока они выглядят и ведут себя ожидаемо. В следующих разделах мы рассмотрим рекомендации по стилизации некоторых важных HTML-элементов.</p>

<h4 id="Standard_text_content_structure">«Стандартная» структура текстового контента</h4>

<p>Заголовки, параграфы и списки — это основа текстового контента веб-страницы:</p>

<pre class="brush: html">&lt;h1&gt;Заголовок&lt;/h1&gt;

&lt;p&gt;Параграф&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;В моём списке&lt;/li&gt;
  &lt;li&gt;два элемента.&lt;/li&gt;
&lt;/ul&gt;</pre>

<p>Типичные стили для такого контента могут выглядеть следующим образом:</p>

<pre class="brush: css">h1 {
  font-size: 5rem;
}

p, li {
  line-height: 1.5;
  font-size: 1.6rem;
}</pre>

<p>Следует обратить внимание, что:</p>

<ul>
 <li>У шрифтов выбраны разумные размер, интерлиньяж, межбуквенное расстояние и прочее, чтобы сделать текстовый контент разборчивым и комфортным для чтения.</li>
 <li>Заголовки заметно отличаются от основного текста, например имеют такой же крупный размер шрифта и полужирное начертание, как стандартная стилизация. Списки выглядят как списки.</li>
 <li>Цвет текста должен быть достаточно контрастен относительно цвета фона.</li>
</ul>

<p> Для более подробной информации смотрите <a href="/ru/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals">Основы редактирования текста в HTML</a> и <a href="/ru/docs/Learn/CSS/Styling_text">Стилизация текста</a>.</p>

<h4 id="Emphasised_text">Акцентированный текст</h4>

<p>Строчный элемент, который акцентирует особое внимание на содержащемся в нём тексте:</p>

<pre class="brush: html">&lt;p&gt;Вода &lt;em&gt;очень горячая&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Собирающиеся на поверхности капельки воды называются &lt;strong&gt;конденсатом&lt;/strong&gt;.&lt;/p&gt;</pre>

<p>Возможно, нам понадобится добавить цвета акцентированному тексту:</p>

<pre class="brush: css">strong, em {
  color: #a60000;
}</pre>

<p>Однако не стоит сильно менять стандартную стилизацию акцентирующих элементов. Стандартный вид полужирного и курсивного текста хорошо узнаваем, поэтому изменение стилизации может вызывать путаницу. Для более подробной информации смотрите <a href="/ru/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals#Акцент_и_важность">Акцент и важность</a>.</p>

<h4 id="Abbreviations">Аббревиатуры</h4>

<p>Элемент, который позволяет разметить аббревиатуру или акроним и указать их расшифку:</p>

<pre class="brush: html">&lt;p&gt;Веб-контент верстается с помощью &lt;abbr title="Hypertext Markup Language"&gt;HTML&lt;/abbr&gt;.&lt;/p&gt;</pre>

<p>И вновь, возможно, нам понадобится немного стилизовать наши аббревиатуры:</p>

<pre class="brush: css">abbr {
  color: #a60000;
}</pre>

<p>Стандартная стилизация для аббревиатур — это пунктирное подчёркивание, не стоит от этого сильно отклоняться. Для более подробной информации смотрите <a href="/ru/docs/Learn/HTML/Introduction_to_HTML/Advanced_text_formatting#Аббревиатуры">Аббревиатуры</a>.</p>

<h4 id="Links">Ссылки</h4>

<p>Гиперссылки помогают нам переходить из одного места в сети в другое:</p>

<pre class="brush: html">&lt;p&gt;Посетите &lt;a href="https://www.mozilla.org"&gt;домашнюю страницу Mozilla&lt;/a&gt;.&lt;/p&gt;</pre>

<p>Ниже приведена базовая стилизация для ссылок:</p>

<pre class="brush: css">a {
  color: #ff0000;
}

a:hover, a:visited, a:focus {
  color: #a60000;
  text-decoration: none;
}

a:active {
  color: #000000;
  background-color: #a60000;
}</pre>

<p>Стандартные соглашения по стилизации ссылок — подчёркивание и отличный от стандартного цвет (по умолчанию, синий) в обычном состоянии, другой цвет в случае, если ссылка ранее была посещена (по-умолчанию, фиолетовый) и еще один цвет для состояния нажатости (по-умолчанию, красный). Кроме того при наведении указателя мыши на ссылку указатель начинает отображаться в виде руки, а также ссылка выделяется, когда находится в фокусе (при перемещении по странице с помощью клавиши tab) или активна. Изображение ниже показывает выделение в Firefox (пунктирная обводка) и Chrome (синяя обводка):</p>

<p><img alt="" src="focus-highlight-firefox.png" style="display: block; margin: 0px auto;"></p>

<p><img alt="" src="focus-highlight-chrome.png" style="display: block; margin: 0px auto;"></p>

<p>До тех пор, пока пользователь получает обратную связь при взаимодействии со ссылками, можно проявлять определённую креативность относительно их стилизации. Что-нибудь обязательно должно происходить при изменении состояния. Не следует также отключать стандартную иконку указателя мыши или обводку — она вносит очень важный вклад в доступность для тех, кто при навигации по сайту использует клавитуру.</p>

<h4 id="Form_elements">Формы</h4>

<p>Формы - это DOM-элементы, которые позволяют пользователям вводить данные на веб-страницах:</p>

<pre class="brush: html">&lt;div&gt;
  &lt;label for="name"&gt;Введите имя&lt;/label&gt;
  &lt;input type="text" id="name" name="name"&gt;
&lt;/div&gt;</pre>

<p>Мы подготовили пример хорошей стилизации формы, который вы можете найти здесь: <a href="https://github.com/mdn/learning-area/blob/master/accessibility/css/form-css.html">form-css.html</a> (а также <a href="https://mdn.github.io/learning-area/accessibility/css/form-css.html">посмотреть вживую</a>).</p>

<p>При стилизации форм обычно производится подгонка размеров элементов, выравнивание лейблов и полей ввода, а также придание им приятного внешнего вида.</p>

<p>Не следует сильно отклоняться от стандартной стилизации состояния фокуса на элементах формы. По умолчанию, оно выглядит так же, как у ссылок (смотрите изображения выше). Можно стилизовать фокус и наведение указателя мыши на элементы формы, например, для придания им универсального внешнего вида в разных браузерах или же для лучшего соответствия дизайну сайта. При этом не стоит совсем отключать отображение этих состояний, потому что с их помощью пользователи ориентируются в происходящем на странице.</p>

<h4 id="Tables">Таблицы</h4>

<p>Таблицы используются для отображения табличных данных.</p>

<p>Вы можете найти хороший образец HTML и CSS для таблицы в нашем примере: <a href="https://github.com/mdn/learning-area/blob/master/accessibility/css/table-css.html">table-css.html</a> (а также <a href="https://mdn.github.io/learning-area/accessibility/css/table-css.html">посмотреть вживую</a>).</p>

<p>Стилизуют таблицы обычно для придания им более симпатичного внешнего вида и лучшего вписывания в общий дизайн страницы. Не стоит отказываться от выделения заголовков (обычно с помощью полужирного начертания) и чередования двух цветов строк для лучшего восприятия информации.</p>

<h3 id="Color_and_color_contrast">Цвета и контраст</h3>

<p>При выборе цветовой палитры для сайта, следует следить за тем, чтобы цвет текста имел высокий уровень контрастности относительно цвета фона. Дизайн может выглядеть очень стильно, однако это не будет иметь никакого смысла, если люди с дефектами зрения (такими как дальтонизм) не смогут прочитать ваш контент.</p>

<p>К счастью, проверить, всё ли в порядке с уровнем контрастности, весьма просто. Существует множество онлайн-инструментов, которые помогут сравнить пару цветов и вычислить значение контрастности. Например, <a href="http://webaim.org/resources/contrastchecker/">Color Contrast Checker</a> от WebAIM. Это довольно простой в использовании инструмент, который также предоставляет инструкции, как можно добиться соответствия критериям WCAG по контрастности цветов.</p>

<div class="note">
<p><strong>Примечание</strong>: Высокий уровень контрастности также позволяет пользователям мобильных устройств с глянцевыми экранами комфортнее читать текст при ярком освещении.</p>
</div>

<p>Кроме того, не следует полагаться только на цвет при выделении важной информации, потому что некоторые пользователи не распознают цвета. Например, стоит не просто пометить обязательные поля формы красным, но также добавить рядом звёздочку.</p>

<h3 id="Hiding_things">Скрытые элементы</h3>

<p>Существует множество ситуаций, когда не нужно показывать сразу весь контент. Например, в нашем прототипе <a href="https://mdn.github.io/learning-area/css/css-layout/practical-positioning-examples/info-box.html">панели вкладок</a> (здесь можно посмотреть <a href="https://github.com/mdn/learning-area/blob/master/css/css-layout/practical-positioning-examples/info-box.html">исходный код</a>) имеется три секции с информацией, но мы <a href="/ru/docs/Learn/CSS/CSS_layout/Positioning">располагаем</a> их одна над другой и предоставляем набор вкладок, которые позволяют при кликах по ним переключаться между секциями (они также доступны при помощи клавиатуры — их можно выбирать клавишами Таб и Enter/Return).</p>

<p><img alt="" src="tabbed-info-box.png" style="display: block; margin: 0px auto;"></p>

<p>При этом, такой подход никак не мешает пользователям скринридеров — до тех пор, пока контент в вёрстке расположен в правильном порядке, у них не будет никаких проблем. Именно поэтому абсолютное позиционирование (как в примере выше) считается одним из лучших механизмов для визуального скрытия контента.</p>

<p>А вот {{cssxref("visibility")}}<code>:hidden</code> и {{cssxref("display")}}<code>:none</code>, напротив, использовать для скрытия контента не следует, потому что они скрывают его не только визуально, но и от скринридеров. Поэтому применять эти свойства стоит, только если совсем скрыть контент и является вашей задачей.</p>

<div class="note">
<p><strong>Примечание</strong>: В статье <a href="http://webaim.org/techniques/css/invisiblecontent/">Невидимый контент только для пользователей скринридеров (EN)</a> содержится множество полезной информации по этой теме.</p>
</div>

<h3 id="Accept_that_users_can_override_styles">Помните, что пользователи могут переопределять стили</h3>

<h4 id="Accept_that_users_can_override_your_styles">Помните, что пользователи могут переопределять ваши стили</h4>

<p>У пользователей есть возможность переопределять ваши стили своими, например:</p>

<ul>
 <li>В руководстве Сары Мэддокс <a class="external external-icon" href="https://www.itsupportguides.com/knowledge-base/computer-accessibility/how-to-use-a-custom-style-sheet-css-with-firefox/" rel="noopener">Как использовать пользовательские таблицы стилей (CSS) в Firefox (EN)</a> можно найти подробные инструкции по пользовательским стилям в Firefox, а в статье <a href="https://www.itsupportguides.com/knowledge-base/computer-accessibility/how-to-use-a-custom-style-sheet-css-with-internet-explorer/">Как использовать пользовательские таблицы стилей (CSS) в Internet Explorer (EN)</a> за авторством Адриана Гордона, соответственно, для <abbr title="Internet Explorer">IE</abbr>.</li>
 <li>Также можно воспользоваться браузерными расширениями. Например, расширение Stylish доступно для <a href="https://addons.mozilla.org/en-US/firefox/addon/stylish/">Firefox</a>, <a href="https://safari-extensions.apple.com/details/?id=com.sobolev.stylish-5555L95H45">Safari</a>, <a href="https://addons.opera.com/en/extensions/details/stylish/">Opera</a> и <a href="https://chrome.google.com/webstore/detail/stylish/fjnbnpbmkenffdnngjfgmeleoegfcffe">Chrome</a>.</li>
</ul>

<p>Пользователи могут переопределять стили по множеству причин. Людям со слабым зрением может понадобиться сделать текст крупнее на всех сайтах, которыми они пользуются. А пользователю с монохромазией потребуется перекрасить все сайты в высококонтрастные цвета, которые ему проще различать. Какая бы ни была причина, следует оставлять дизайн сайта достаточно гибким, чтобы подобные изменения в нём работали. Например, важно убедиться, что область с главным контентом будет нормально обрабатывать более крупные размеры шрифта — она не должна просто обрезать текст или совсем ломаться.</p>

<h2 id="JavaScript">JavaScript</h2>

<p>При неправильном использовании JavaScript тоже может вредить доступности.</p>

<p>Современный JavaScript — это очень мощный язык, с помощью которого можно делать кучу разных вещей: от простых обновлений пользовательского интерфейса до полноценных 2D- и 3D-игр. Понятно, что нельзя сделать абсолютно любой тип контента доступным на 100% для всех — нужно просто прилагать все усилия, чтобы делать веб-приложения доступными настолько, насколько это возможно.</p>

<p>Сравнительно несложно сделать доступным простой контент — например, текст, изображения, таблицы, формы и кнопки. Вспомним основные тезисы из статьи <a href="/ru/docs/Learn/Accessibility/HTML">HTML: Хорошая основа для доступности</a>:</p>

<ul>
 <li>Хорошая семантика: использование каждого элемента для своей задачи. Следует убедиться, что используются различные типы элементов: заголовки, параграфы, {{htmlelement("button")}}, {{htmlelement("a")}} и так далее.</li>
 <li>Контент должен быть доступен либо как обычный текст, либо как <a href="/ru/docs/Learn/Accessibility/HTML#Альтернативный_текст">альтернативный текст</a>, например атрибут alt для изображений.</li>
</ul>

<p>Мы также показали пример использования JavaScript для добавления некоторым элементам возможностей, которых они лишены по умолчанию — смотрите в разделе <a href="/ru/docs/Learn/Accessibility/HTML#Добавление_доступности_с_клавиатуры">Добавление доступности с клавиатуры</a>. Такое решение стоит рассматривать только в случае, когда по какой-то причине у вас нет доступа к изменению разметки. Намного надежнее и универсальнее будет использовать для каждой задачи соответствующий элемент. Также улучшить доступность несемантичных JavaScript-виджетов можно использованием <abbr title="Web Accessibility Initiative — Accessible Rich Internet Applications">WAI-ARIA</abbr> атрибутов — с их помощью можно добавить некоторой искусственной семантики для пользователей скринридеров. В следующей статье мы рассмотрим эту тему подробнее.</p>

<p>Сложные приложения, например 3D-игры, сделать доступными непросто — написанная с использованием <a href="/ru/docs/Web/API/WebGL_API">WebGL</a> игра рендерится в элементе {{htmlelement("canvas")}}, который в настоящее время не предоставляет никаких возможностей для использования людьми с дефектами зрения. Можно успокаивать себя тем, что данная группа пользователей не входит в целевую аудиторию, поэтому не стоит ожидать полной доступности для них. Тем не менее, вы можете реализовать <a href="/ru/docs/Games/Techniques/Control_mechanisms/Desktop_with_mouse_and_keyboard">управление с помощью клавиатуры</a> для игроков, которые не могут использовать мышь, а также сделать цветовую схему достаточно контрастной для игроков с дальтонизмом.</p>

<h3 id="The_problem_with_too_much_JavaScript">Проблема с чрезмерным использованием JavaScript</h3>

<p>Данная проблема возникает, когда разработчики слишком сильно полагаются на JavaScript. Порой вы можете встретить сайт, на котором всё генерируется с помощью JavaScript — HTML, CSS и так далее. Такое решение точно так же требует поддержания всех видов доступности и решения связанных с ними проблем.</p>

<p>Для каждой задачи хорош свой инструмент — это правило справедливо как для выбора HTML-элементов, так и для используемой технологии в целом. Стоит хорошенько обдумать, нужно ли использовать тот сияющий, написанный на JavaScript информационный 3D-блок или же воспользоваться старым добрым и обыкновенным текстовым блоком? Нужен ли тот сложный нестандартный виджет в форме, или будет достаточно простого поля для ввода текста? Не следует генерировать весь HTML при помощи JavaScript, если это возможно.</p>

<h3 id="Keeping_it_unobtrusive">Ненавязчивый JavaScript</h3>

<p>При создании веб-страниц, стоит помнить об идее <strong>ненавязчивого JavaScript</strong>. Идея гласит, что JavaScript следует использовать только для дополнительного улучшения пользовательского опыта — базовые возможности должны работать без JavaScript. Здесь мы говорим в основном об использовании стандартных браузерных возможностей, когда это возможно.</p>

<p>Хорошие примеры использования подхода с ненавязчивым JavaScript:</p>

<ul>
 <li>Валидация формы на клиенте, которая показывает пользователю сообщение о проблемах в заполнении формы без необходимости отправлять данные для проверки на сервер. Если скриптов не будет, то форма продолжит работать, просто валидация будет несколько медленнее.</li>
 <li>Создание нестандартных элементов управления для HTML5 <code>&lt;video&gt;</code>, которыми возможно пользоваться с клавиатуры. И в то же самое время, указание прямой ссылки на видео, которой можно воспользоваться, если JavaScript отключён (стандартные элементы управления <code>&lt;video&gt;</code> недоступны с клавиатуры в большинстве браузеров).</li>
</ul>

<p id="Client-side_form_validation">Для примера, мы подготовили простенькую черновую версию клиентской валидации формы — <a href="https://github.com/mdn/learning-area/blob/master/accessibility/css/form-validation.html">form-validation.html</a> (здесь можно <a href="https://mdn.github.io/learning-area/accessibility/css/form-validation.html">посмотреть вживую</a>). Если попытаться нажать на кнопку отправки, не заполнив одно из полей, то форма на сервер отправлена не будет, зато появится сообщение с информацией об ошибках.</p>

<p>Такая валидации формы соответствует принципам ненавязчивости — форму можно будет абсолютно полноценно использовать вообще без JavaScript. Форма всё равно будет провалидирована. Так как злонамеренные пользователи могут очень просто обойти клиентскую валидацию (например, отключив JavaScript в браузере), для важных форм её всегда дублируют на сервере. При этом валидация на стороне клиента всё ещё остаётся очень полезной для показа ошибок — пользователи узнают о проблемах с заполнением формы мгновенно, вместо того, чтобы ждать цикла: отправка на сервер - валидация - перезагрузка страницы. Это очень хорошее улучшение пользовательского опыта.</p>

<div class="note">
<p><strong>Примечание</strong>: В этом простом примере серверная валидация не реализована.</p>
</div>

<p>Также мы постарались сделать эту форму довольно доступной. Мы использовали элементы {{htmlelement("label")}} и связали их со своими полями ввода, таким образом скринридеры смогут корректно их озвучить:</p>

<pre class="brush: html">&lt;label for="name"&gt;Введите ваше имя:&lt;/label&gt;
&lt;input type="text" name="name" id="name"&gt;</pre>

<p>Чтобы избежать слишком частого обновления пользовательского интерфейса и возможных проблем для пользователей скринридеров, мы производим валидацию только при попытке отправки формы:</p>

<pre class="brush: js">form.onsubmit = validate;

function validate(e) {
  errorList.innerHTML = '';
  for (let i = 0; i &lt; formItems.length; i++) {
    const testItem = formItems[i];
    if (testItem.input.value === '') {
      errorField.style.left = '360px';
      createLink(testItem);
    }
  }

  if (errorList.innerHTML !== '') {
    e.preventDefault();
  }
}</pre>

<div class="note">
<p><strong>Примечание</strong>: В данном примере мы скрываем и показываем сообщение об ошибке с помощью абсолютного позиционирования, а не каким-то иным методом, потому что такой способ не мешает скринридерам озвучивать контент.</p>
</div>

<p>В реальности валидация формы будет в разы сложнее. Возможно, вы захотите проверить, что введённое имя действительно выглядит как имя, а возраст — как число, да ещё и реалистичное (например, не отрицательное и состоящее не более чем из 3 цифр). Здесь мы реализовали лишь примитивную проверку на наличие хоть какого-то текста в полях ввода (<code>if (testItem.input.value === '')</code>).</p>

<p>Когда валидация проходит успешно, форма отправляется на сервер. Если же были обнаружены ошибки (<code>if (errorList.innerHTML !== '')</code>), то мы прерываем отправку формы (при помощи <code><a href="/en-US/docs/Web/API/Event/preventDefault">preventDefault()</a></code>) и отображаем сообщения обо всех найденных ошибках (смотрите далее).</p>

<p>Для каждого пустого на момент отправки формы поля ввода мы создаем элемент списка с ссылкой и добавляем в <code>errorList</code>.</p>

<pre class="brush: js">function createLink(testItem) {
  const listItem = document.createElement('li');
  const anchor = document.createElement('a');

  anchor.textContent = 'Поле ввода ' + testItem.input.name + ' пусто: введите ' + testItem.input.name + '.';
  anchor.href = '#' + testItem.input.name;
  anchor.onclick = function() {
    testItem.input.focus();
  };
  listItem.appendChild(anchor);
  errorList.appendChild(listItem);
}</pre>

<p>Каждая ссылка выполняет две задачи — она рассказыает, какая ошибка случилась, а также при клике на неё можно перейти прямо в связанное поле ввода и скорректировать введённое значение.</p>

<div class="note">
<p><strong>Примечание</strong>: Часть этого примера, связанная с <code>focus()</code>, довольно хитрая. Браузеры Chrome и Edge (а также новые версии IE) не нуждаются в коде <code>onclick</code>/<code>focus()</code> — они сами переведут фокус на элемент после клика по ссылке. Safari лишь выделит нужный элемент, так что этот блок кода нужен для корректной установки фокуса. В Firefox же трюк с выделением элемента при клике по ссылке не работает вообще. Данная ошибка должна быть вскоре исправлена — тогда Firefox придет к паритету с прочими браузерами (смотрите {{bug(277178)}}).</p>
</div>

<p>Дополнительно, то что <code>errorField</code> расположено в вёрстке в самом начале (тогда как визуально в интерфейсе расположено иначе при помощи CSS), позволяет пользователям увидеть, что именно не так с заполнением формы, и легко вернуться обратно к нужным полям ввода в начале страницы.</p>

<p>Кроме того, мы использовали несколько WAI-ARIA атрибутов в нашем примере, чтобы решить проблемы с доступностью, вызванные обновлением контента без перезагрузки страницы (по умолчанию, скринридеры не могут подхватить эти изменения и уведомить об этом пользователя):</p>

<pre>&lt;div class="errors" role="alert" aria-relevant="all"&gt;
  &lt;ul&gt;
  &lt;/ul&gt;
&lt;/div&gt;</pre>

<p>Мы разберем данные атрибуты в следующей статье, которая подробно описывает <a href="/ru/docs/Learn/Accessibility/WAI-ARIA_basics">WAI-ARIA</a>.</p>

<div class="note">
<p><strong>Примечание</strong>: Кто-то из читателей мог задуматься о том факте, что в HTML5 формах есть встроенные механизмы валидации, такие как атрибуты <code>required</code>, <code>min</code>/<code>minlength</code> и <code>max</code>/<code>maxlength</code> (смотрите подробнее на странице элемента {{htmlelement("input")}}). Мы не использовали их в примере, потому что поддержка браузерами у HTML5 валидации весьма варьируется (например, только IE10 и новее).</p>
</div>

<div class="note">
<p><strong>Примечание</strong>: Статья <a href="http://webaim.org/techniques/formvalidation/">Удобная и доступная валидация форм (EN)</a> от WebAIM содержит дополнительную полезную информацию по этой теме.</p>
</div>

<h3 id="Other_JavaScript_accessibility_concerns">Прочие проблемы доступности, связанные с JavaScript</h3>

<p>Здесь мы собрали прочие аспекты, о которых стоит задумываться при написании JavaScript, если вы беспокоитесь о доступности. Мы будем обновлять данный раздел.</p>

<h4 id="mouse-specific_events">Специфичные события мыши</h4>

<p>Большая часть интерактивности в пользовательских интерфейсах реализуется в JavaScript при помощи обработчиков событий, которые позволяют запускать код, когда происходит определённое событие. У некоторых таких событий имеются проблемы с доступностью. Хороший пример — это специфичные события мыши, например <a href="/ru/docs/Web/API/Element/mouseover_event">mouseover</a>, <a href="/ru/docs/Web/API/Element/mouseout_event">mouseout</a>, <a href="/ru/docs/Web/API/Element/dblclick_event">dblclick</a> и так далее. Функции, которые активируются при срабатывании этих событий, не будут доступны при использовании других устройств ввода, например клавиатуры.</p>

<p>Чтобы избежать проблем подобного рода, следует дублировать функциональность при помощи независимых от устройств событий. Например, события <a href="/ru/docs/Web/API/Element/focus_event">focus</a> и <a href="/ru/docs/Web/API/Element/blur_event">blur</a> будут работать как для мыши, так и для клавиатуры.</p>

<p>Рассмотрим пример, который проиллюстрирует, когда это может быть важно. Допустим, у нас есть миниатюрное изображение, при наведении на которое или при фокусе на котором должна показываться его увеличенная версия (примерно как карточки товаров в каталоге интернет-магазина).</p>

<p>Мы подготовили простой пример, который можно посмотреть здесь <a href="https://mdn.github.io/learning-area/accessibility/css/mouse-and-keyboard-events.html">mouse-and-keyboard-events.html</a> (а здесь можно посмотреть <a href="https://github.com/mdn/learning-area/blob/master/accessibility/css/mouse-and-keyboard-events.html">исходный код</a>). В коде представлены две функции, которые показывают и скрывают увеличенное изображение. Они устанавливаются в качестве обработчиков событий следующими строками кода:</p>

<pre class="brush: js">imgThumb.onmouseover = showImg;
imgThumb.onmouseout = hideImg;

imgThumb.onfocus = showImg;
imgThumb.onblur = hideImg;</pre>

<p>Первые две строки кода запускают функцию, когда указатель мыши наводится на изображение или уходит с него, соответственно. Такая реализация не позволит открыть увеличенное изображение при помощи клавиатуры. Чтобы решить эту проблему, мы добавили последние две строки, которые запускают функции в случаях, если фокус перешёл на изображение или же ушёл с него. Таким образом, увеличенное изображение будет открываться при переходе на миниатюру при помощи клавиши tab (это возможно, потому что мы добавили миниатюрам <code>tabindex="0"</code>).</p>

<p>Событие <a href="/ru/docs/Web/API/Element/click_event">click</a> довольно любопытное — выглядит так, будто бы оно специфичное для мыши, однако большинство браузеров при нажатии клавиши Enter/Return активируют обработчики событий <a href="/ru/docs/Web/API/GlobalEventHandlers/onclick">onclick</a> на находящихся в фокусе ссылках или элементах формы, а также при тапе по элементам на сенсорном экране. Впрочем, это не работает автоматически, если вы позволяете принимать фокус неинтерактивному по умолчанию элементу при помощи tabindex — в таких случаях нужно специально прослушивать нажатие нужных кнопок (смотрите <a href="/ru/docs/Learn/Accessibility/HTML#Добавление_доступности_с_клавиатуры">Добавление доступности с клавиатуры</a>).</p>

<h2 id="Test_your_skills!">Проверьте ваши навыки!</h2>

<p>Вы дочитали до конца, но хорошо ли вы усвоили материал? Перед тем как двигаться дальше, вы можете пройти тесты, которые мы специально подготовили — смотрите <a href="/en-US/docs/Learn/Accessibility/CSS_and_JavaScript/Test_your_skills:_CSS_and_JavaScript_accessibility">Проверьте ваши навыки: CSS и JavaScript доступность (EN)</a>.</p>

<h2 id="Summary">Заключение</h2>

<p>Надеемся, что данная статья даст вам хорошую базу в решении проблем с доступностью, которые могут возникнуть при использовании CSS и JavaScript на веб-страницах.</p>

<p>Далее WAI-ARIA!</p>

<div>{{PreviousMenuNext("Learn/Accessibility/HTML","Learn/Accessibility/WAI-ARIA_basics", "Learn/Accessibility")}}</div>

<h2 id="In_this_module">В этом модуле</h2>

<ul>
  <li><a href="/ru/docs/Learn/Accessibility/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>