Верстка форм
- 
    Не используйте для разметки групп инпутов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