Формы ставят перед нами ряд проблем в удобстве и доступности, многие из которых усложняются, когда мы пытаемся уместить форму в крошечном пространстве среди других элементов веб-страницы. Компактные формы выглядят эффектно, но часто они совершенно не учитывают проблем доступности.
Одним из наиболее широко распространенных вариантов дизайна компактных форм использует способ, при котором название поля ввода располагается внутри этого поля.
Стандартный способ разметки в такой ситуации — подстановка имени поля в атрибут value
каждого поля ввода input
. Потом можно создать обработчик события на JavaScript и каком-либо серверном языке, чтобы не допустить отправку формы со значениями по умолчанию (например, «логин» и «пароль»). Однако поля для ввода паролей (типа password
) замаскируют ввод данных с помощью замены каждого вводимого символа звездочкой или точкой. Таким образом, мы не можем поместить название внутрь атрибута value
в поле типа password
— дело даже не в этом, просто значения по умолчанию (атрибут value
) предназначены совершенно для других целей.
В этой статье мы займемся созданием компактной формы, которая обеспечила бы высокую степень доступности, несмотря на свои уменьшенные размеры. Заметьте, что я не говорю, что крошечные формы — это хороший выбор. Скорее, я выражаю мнение о необходимости согласования требования компактности, предъявленного вашим клиентом, с вашими собственными желаниями.
Начнем с доступной разметки
Чтобы сохранить доступность, нужно к каждому элементу формы добавить метку (тег label
), которая определяла бы название этого элемента. Создавая дизайн компактных форм, нет причин не следовать этим рекомендациям. Так же как и для любого сайта или веб-страницы мы начнем с обычной разметки, функционально правильной и соответствующей признакам доступности, а потом мы применим таблицы стилей и JavaScript, улучшив внешний вид и функциональность.
В нашем подходе мы будем использовать таблицы стилей, чтобы разместить обычные метки поверх самих полей ввода, но, в сущности, они будут независимыми элементами.
<form name="login" action="#" method="post"> <div id="username"> <label for="username-field" class="overlabel">Логин</label> <input id="username-field" type="text" name="username" title="Логин" value="" tabindex="1" /> </div> <div id="password"> <label for="password-field" class="overlabel">Пароль</label> <input id="password-field" type="password" name="password" title="Пароль" value="" tabindex="2" /> </div> <div id="submit"> <input type="submit" name="submit" value="Вход" tabindex="3" /> </div> </form>
Каждый тег label
и input
заключен в блок div
, чтобы форма имела нормальный вид при отображении страницы без таблиц стилей. Вместо этого вы можете заключить их в теги fieldset
, но, по моему мнению, в нашем случае недостаточно оснований применять тег fieldset
всего лишь для одного поля ввода.
Мы назначили каждой метке класс с именем overlabel
. Прежде чем использовать этот класс в CSS, мы применим JavaScript для того, чтобы найти все теги label
этого класса и привязать обработчик события к каждому из них. Использование классов вместо идентификаторов позволяет нам легко добавлять новые элементы, не отслеживая их уникальные идентификаторы.
В дополнение к тегам label
мы также добавили атрибут title
к каждому полю ввода, чтобы повысить удобство ввода данных, так как метка будет скрыта, когда пользователь начнет вводить информацию.
Далее мы добавим стили для наложения меток.
form#login { position:relative; } div#username, div#password { position:relative; float:left; margin-right:3px; } input#username-field, input#password-field { width:10em; } label.overlabel { position:absolute; top:3px; left:5px; z-index:1; color:#999; }
Использование абсолютного позиционирования меток позволяет «вырвать» их из формы, а так как блоки div
"плавают" по левому краю формы, то нет необходимости использовать пробел между полями формы. Тегам label присваивается свойство z-index
для того, чтобы они располагались перед другими элементами формы.
В зависимости от размеров шрифта и полей формы, вам может понадобиться трюк с позиционированием меток, но этот пример выглядит идентично во всех современных браузерах. Мы используем масштабируемые единицы измерения — в нашем случае, em
— что дает возможность пользователям изменять размер текста в браузере, и гарантирует, что поля ввода и метки будут изменяться в размерах пропорционально друг другу.
Создание скрипта
Когда в соответствующее поле формы осуществляется ввод, то метка для этого поля должна быть скрыта. В том случае если в поле есть введённые данные, то его метка также остается скрытой. Это условие будет выполняться как для значений по умолчанию, так и для значений, введённых пользователем.
Мы используем JavaScript, чтобы для каждой метки произвести замену уже определенного нами класса overlabel
на новый класс. Метки должны быть видимы, даже если JavaScript не поддерживается браузером.
label.overlabel { color:#999; } label.overlabel-apply { position:absolute; top:3px; left:5px; z-index:1; color:#999; }
Чтобы сохранить доступность меток, мы используем отрицательное свойство text-indent
для скрытия текста, а не присваиваем свойству display значение none.
function initOverLabels () { if (!document.getElementById) return; var labels, id, field; // Определить обработчики событий focus и blur, чтобы // скрыть или показать метки с именем класса 'overlabel'. labels = document.getElementsByTagName('label'); for (var i = 0; i < labels.length; i++) { if (labels[i].className == 'overlabel') { // Игнорировать метки, не связанные с какими-либо полями. id = labels[i].htmlFor || labels[i].getAttribute('for'); if (!id || !(field = document.getElementById(id))) { continue; } // Изменить класс меток. labels[i].className = 'overlabel-apply'; // Скрыть метки, которые связаны с полями, имеющими // значения атрибута value, отличное от значения по умолчанию. if (field.value !== '') { hideLabel(field.getAttribute('id'), true); } // Определить обработчики событий для отображения и скрытия меток. field.onfocus = function () { hideLabel(this.getAttribute('id'), true); }; field.onblur = function () { if (this.value === '') { hideLabel(this.getAttribute('id'), false); } }; // Обработчик события onclick для тегов label (для Safari). labels[i].onclick = function () { var id, field; id = this.getAttribute('for'); if (id && (field = document.getElementById(id))) { field.focus(); } }; } } }; function hideLabel (field_id, hide) { var field_for; var labels = document.getElementsByTagName('label'); for (var i = 0; i < labels.length; i++) { field_for = labels[i].htmlFor || labels[i].getAttribute('for'); if (field_for == field_id) { labels[i].style.textIndent = (hide) ? '-1000px' : '0px'; return true; } } } window.onload = function () { setTimeout(initOverLabels, 50); };
Скрипт действует на все теги label
на странице, которые имеют класс overlabel. Он находит связанные с ними поля ввода (input
), основываясь на значении атрибута for
меток, которое должно совпадать с идентификатором тега input
. Новый класс overlabel-apply назначается каждой из меток. Кроме того, полям ввода назначаются обработчики событий onfocus
и onblur
для изменения свойства text-indent
, тем самым скрывая или показывая метки.
Как было сказано выше, этот скрипт работает независимо от имен и идентификаторов полей ввода. Классы могут быть использованы для изменения стилей целого набора элементов на странице, поэтому мы можем использовать этот механизм для скрытия или отображения нескольких элементов на странице.
Вас могло удивить то, что в обработчике onload используется небольшая задержка. Она позволяет нам приспособить браузеры, которые запоминают пароли часто посещаемых сайтов. Эти браузеры вставляют сохраненные логины и пароли в HTML-формы после того, как страница полностью загрузится, а задержка гарантирует нам, что метка будет скрыта даже после вставки логина или пароля.
Заметьте, что только в конце функции initOverLabels
мы используем код для конкретных браузеров. Обычно при щелчке на элементе label
фокус передается связанному с ним полю ввода, но в браузере Safari это правило игнорируется. Чтобы исправить эту ситуацию, мы добавили обработчик onclick
к метке, чтобы даже в Safari передать фокус полю ввода.
В итоге
Последний вариант формы создан с использованием универсального метода для размещения имени поля ввода внутри него без манипуляций со значением по умолчанию, сохраняя доступность на высоком уровне. При отправке формы без изменения значений полей скрипт получает пустой набор данных, а не набор — логин и пароль. Кроме того, мы можем легко добавить такие же метки в форму на любой странице, просто добавив имя класса, немного кода CSS и JavaScript, описанные выше.
В дополнение ко всему этому, если пользователь посещает сайт без включенных JavaScript или CSS, форма останется удобной, а метки будут располагаться рядом с каждым полем, как это изначально предполагалось до привлечения дизайнерской задумки.
Статья основана на оригинальной статье online-журнала A List Arart «Making Compact Forms More Accessible».Категории этой статьи
Новости, близкие по теме
Опросы, близкие по теме