Верстка форм
-
Не используйте для разметки групп инпутов
divиh1-h6#- Почему? #
-
Для разметки групп полей есть более подходящие теги:
fieldsetиlegend. Они не только внесут разнообразие в код, но также сделают вашу форму более доступной. - А как надо? #
-
С чистыми
fieldsetиlegendмогут возникать затруднения при стилизации и позиционировании контента, но это легко решается дополнительными обёртками.Например, так как
fieldsetиспользуется для групп полей, а у каждого поля есть лейбл, каждой пареinput+labelобычно требуется обёртка, и здесь можно удобно использовать ненумерованные списки (ul). После этого можно всё позиционирование делать для списка и его элементов, и с раскладкой больше не будет никаких проблем. Чтобы вместе с инпутом не читалась информация об элементах списка, его нужно скрыть от скринридеров, задавrole="none".legendведёт себя своеобразно, но его можно вырвать со своего места с помощьюfloat: left, а для позиционирования текста внутриlegendзавернуть текст в спаны.-
Плохо
<div> <h3>Контакты</h3> <label for="name">Имя</label> <input type="text" name="name" id="name"> <label for="surname">Фамилия</label> <input type="text" name="surname" id="surname"> </div> -
Хорошо
<fieldset> <legend>Контакты</legend> <ul role="none"> <li> <label for="name">Имя</label> <input type="text" name="name" id="name"> </li> <li> <label for="surname">Фамилия</label> <input type="text" name="surname" id="surname"> </li> </ul> </fieldset>
-
-
Не используйте
legendвместоlabel#- Почему? #
-
В некоторых макетах можно увидеть, что название для
textareaвыглядит какlegend, и возникает соблазн поместитьtextareaвfieldset, а название поля поместить вlegend.Это будет не самым правильными решением, потому что у всех инпутов должны быть лейблы. Если добавить скрытый лейбл, его содержимое будет дублировать уже имеющийся
legend, и всё это вместе будет выглядеть довольно странно. - Как это увидеть? #
-
Посмотрите на форму без стилей:
- А как надо? #
-
Для одиночного текстового поля не нужны
fieldsetиlegend, они для групп полей. Если такому полю требуется обёртка, можно использоватьdiv. Название поля нужно поместить вlabel.Если стилизация
legendне привязана к тегу, вы без проблем можете использовать эти же стили (а лучше класс) для стилизации лейбла.-
Плохо
<fieldset class="form-group"> <legend class="form-group__title"> Опишите привычки кота </legend> <label class="form-group__label visually-hidden" for="cat-habits"> Опишите привычки кота </label> <textarea class="form-group__textarea" id="cat-habits" placeholder="Введите текст" ></textarea> </fieldset> -
Хорошо
<div class="form-group"> <label class="form-group__title" for="cat-habits"> Опишите привычки кота </label> <textarea class="form-group__textarea" id="cat-habits" placeholder="Введите текст" ></textarea> </div>
Теперь ничего не дублируется:
-
-
Не используйте
display: noneдля скрытия инпутов #-
Инпуты, спрятанные таким образом, становятся полностью недоступны для скринридеров и навигации с клавиатуры
-
Установите фокус в первое поле и перемещаясь по форме с помощью
Tabи стрелок попробуйте выбрать цвет кота:Ничего не получится, с клавиатуры выбор цвета недоступен.
-
Для скрытия инпутов используйте класс
.visuallyhidden:.visuallyhidden { position: absolute; width: 1px; height: 1px; margin: -1px; border: 0; padding: 0; white-space: nowrap; clip-path: inset(100%); clip: rect(0 0 0 0); overflow: hidden; }Это скроет инпут для обычных пользователей, но оставит его доступным для скринридеров. Почитать подробнее можно тут.
Попробуйте теперь с помощью
Tabи стрелок выбрать цвет кота (чтобы выбрать цвет нажмите пробел):Всё работает.
-
Итого
- Не используйте для разметки групп инпутов
divиh1-h6, есть более подходящие теги:fieldsetиlegend. - Не используйте
legendвместоlabelдля одиночного поля, ему не нужныfieldsetиlegend, достаточноdivиlabel. - Не используйте
display: noneдля скрытия инпутов, они становятся недоступны для скринридеров и навигации с клавиатуры. Скрывайте с помощью.visuallyhidden