Эффективные HTML-формы. Часть 2
В предыдущей статье мы выделили несколько необходимых элементов эффективной с точки зрения юзабилити формы. Мы указали на важность использования элемента label, эффективность атрибута placeholder и необходимость создания ассоциированных подсказок, но для того, чтобы ваша форма была действительно дружественной по отношению к пользователю, этого недостаточно.
Выделяйте обязательные поля
До появления HTML5 принятой практикой выделения полей, обязательных для заполнения, был символ звездочки (*), установленный возле названия поля, но в новой спецификации появился специальный атрибут required , который позволяет отметить обязательное поле на уровне разметки.
<input required …>
Этот атрибут дает указание браузеру (при условии, что тот поддерживает HTML5), указание не отправлять данные после нажатия пользователем кнопки отправить , пока указанные поля не заполнены. К сожалению, голосовые браузеры пока не воспринимают этот атрибут, но для них есть его эквивалент: aria-required. Добавление этого атрибута со значение true делает указанное поле обязательным для заполнения до отправки данных формы на сервер.
<input required aria-required=”true” …>
Помечайте ошибки
Критически важно помочь пользователю быстро исправить ошибку, если он ее допустил. По умолчанию браузеры, которые поддерживают HTML5, поставят курсор на первое поле с ошибкой и выведут стандартное сообщение. Существует возможность управлять этим сообщением с помощью setCustomValidity(), но это не самое важное. Давайте сосредоточимся на том, как мы обрабатываем ошибки на серверной стороне. Если сервер столкнулся с ошибкой в полученных данных, лучшее, что он может предпринять перенаправить пользователя обратно на страницу с формой, в которую уже будут забиты введенные ранее данные.
Поля с ошибками должны быть выделены и легко идентифицируемы. Общепринятая практика: выделение полей красным цветом и появление сообщения о том, что была допущена ошибка. Естественно, одного только выделения полей с некорректной информацией недостаточно. Также стоит позаботиться о том, чтобы пользователь в доступной форме получил сведения о том, как можно исправить ошибку.
<input … aria-describedby=”email-error”>
<em id=”email-error” class=”error-msg”>Неверный формат ввода email.</em>
Для голосовых браузеров мы также можем добавить атрибут, который будет указывать на то, что поле заполнено некорректно:
<input … aria-invalid=”true”>
Если вы хотите все сделать абсолютно правильно, вы можете сгенерировать список ошибок с возможностью перехода к соответствующему полю по клику на элементе этого списка.
<div role=”alert”>
<p>There were errors with your form submission:</p>
<ol>
<li><a href=”#message”>Message</a> is required</li>
<! — errors continue… →
</ol>
</div>
У этой практики есть два неоспоримых преимущества:
- Пользователи получают полный список ошибок с возможностью быстрого перехода к нужному полю;
- Атрибут role со значением alert сообщает голосовому браузеру о том, что нужно издать специальный сигнал и начать чтение содержимого этого блока сразу после загрузки страницы.
Отличный UX начинается с контента
Надеемся, что из предыдущих разделов этой статьи стал очевидным тот факт, что понятный и легко читаемый контент способен значительно повысить юзабилити интерфейса. Это простая и прекрасная вещь, но когда мы окружены всеми этими сложностями со стилями, скриптами и разметкой, довольно просто забыть о содержимом.
Кнопки должны быть кнопками
Не так давно мысль о необходимости работы со стилями кнопок вызывала легкую дрожь. Это было связано с тем, что большинство стилей просто не работало с input с типом button, а элемент button обладал фантомными полями, которые было довольно сложно удалить. Для того чтобы избежать борьбы с ветряными мельницами многие использовали другие элементы (a, div и т.д.), чтобы с помощью скриптов создать на их основе кнопку отправки формы.
Однако такой подход имеет довольно значительный недостаток. Другие элементы не воспринимаются парсерами как кнопка, поэтому возникают проблемы с навигацией с клавиатуры и другие неприятности, в том числе и с голосовыми браузерами. Кроме того, вы становитесь зависимыми от сторонних библиотек: если по какой-то причине пользователь не сможет получить jQuery, он не сможет отправить данные из формы.
aria-describedby или aria-labeledby
ARIA (Accessible Rich Internet Applications) поддерживает два подобных подхода: described by (описание) и labeled by (пометка). Так как решения очень похожи, довольно сложно сделать правильный выбор в каждом конкретном случае. Впрочем, есть отличный способ проиллюстрировать разницу между ними:
<label id=”email-label”>Your Email</label>
<input … aria-labeledby=”email” aria-describedby=”email-note”>
<em id=”email-note” class=”note”>We will only use…</em>
Разница в том, как они используются в конечном итоге, и в какой момент считываются. Атрибут aria-labeledby’ будет считан первым, раньше всей другой информации, связанной с этим полем; потом будет считана вся остальная информация, и лишь потом aria-describedby .
Этот простой пример стоит учитывать, когда вы планируете использовать эти атрибуты для повышения доступности вашего интерфейса.