От автора: в этом уроке мы создадим адаптивную форму при помощи flexbox. Интересен и удивителен тот факт, что flexbox позволяет строить формы без медиа запросов.
Давайте взглянем на конечный результат (большая версия, посмотрите, как меняется макет формы):
Структура формы
Сперва, давайте разберем структуру формы. Мы сделаем:
для группировки различных элементов формы мы используем неупорядоченный список .flex-outer;
для группировки чекбоксов возьмем неупорядоченный список .flex-inner;
почти у всех элементов формы есть свои лейблы.
Вот и все! С помощью двух неупорядоченных списков (можно было взять и нумерованные списки) мы построили довольно четкую форму. Вот так она выглядит:
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 |
<form> <ul class="flex-outer"> <li> <label for="first-name">First Name</label> <input type="text" id="first-name" placeholder="Enter your first name here"> </li> <li> <label for="last-name">Last Name</label> <input type="text" id="last-name" placeholder="Enter your last name here"> </li> <li> <label for="email">Email</label> <input type="email" id="email" placeholder="Enter your email here"> </li> <li> <label for="phone">Phone</label> <input type="tel" id="phone" placeholder="Enter your phone here"> </li> <li> <label for="message">Message</label> <textarea rows="6" id="message" placeholder="Enter your message here"></textarea> </li> <li> <p>Age</p> <ul class="flex-inner"> <!-- list items here --> </ul> </li> <li> <button type="submit">Submit</button> </li> </ul> </form> |
Обратите внимание: перед списком .flex-inner мы используем тег p, а не label. В данном конкретном случае тег label использовать абсолютно необязательно. Данный тег необходимо использовать только для ассоциации лейбла и элемента формы. Разметка чекбоксов:
1 2 3 4 5 6 7 8 9 10 11 |
<ul class="flex-inner"> <li> <input type="checkbox" id="twenty-to-twentynine"> <label for="twenty-to-twentynine">20-29</label> </li> <li> <input type="checkbox" id="thirty-to-thirtynine"> <label for="thirty-to-thirtynine">30-39</label> </li> <!—элементы списка --> </ul> |
Форма с разметкой и без стилей выглядит так:
Не самая красивая форма, которую вы видели, но она работает! Форма семантическая, доступная и гибкая – возможно, самые важные аспекты. Теперь можно писать стили.
Стили формы
Добавим в настройках демо normalize и autoprefixer:
Теперь создадим флекс контейнер. В нашем случае это будут:
все элементы списка .flex-outer;
элементы списка .flex-inner с чекбоксами.
Нам нужно вертикально выровнять все флекс элементы вдоль оси. Для этого необходимо задать пару CSS стилей:
1 2 3 4 5 6 |
.flex-outer li, .flex-inner { display: flex; flex-wrap: wrap; align-items: center; } |
Теперь необходимо указать ширину флекс элементов. Начнем с флекс элементов списка .flex-outer. Основные требования:
ширина лейблов должна быть в рамках 120px – 220px;
ширина элементов формы после лейблов должна быть не менее 220px.
Что это нам дает? Все лейблы с привязанными к ним элементами будут отображаться на одной строке при общей ширине формы от 340px и выше. В другом случае все элементы формы выстроятся один над другим (кроме чекбоксов, что мы сейчас увидим). Обратите внимание: вышеупомянутые значения выбраны произвольно, их можно изменить под свои нужды.
1 2 3 4 5 6 7 8 9 10 |
.flex-outer > li > label, .flex-outer li p { flex: 1 0 120px; max-width: 220px; } .flex-outer > li > label + *, .flex-inner { flex: 1 0 220px; } |
Кнопка отправки
Наконец, кнопка отправки является также флекс элементом, ей мы зададим пару базовых стилей:
1 2 3 4 5 6 7 8 9 10 |
.flex-outer li button { margin-left: auto; padding: 8px 16px; border: none; background: #333; color: #f2f2f2; text-transform: uppercase; letter-spacing: .09em; border-radius: 2px; } |
Чекбоксы
Добавим стилей для чекбоксов. Вспомним, что их флекс контейнер имеет минимальную ширину в 220px.
Сперва, зададим ширину 100px для прямых родителей чекбоксов:
1 2 3 |
.flex-inner li { width: 100px; } |
Теперь при помощи свойства justify-content выровняем их вдоль главной оси. У данного свойства несколько значений, нам нужно только space-between:
1 2 3 |
.flex-inner { justify-content: space-between; } |
Значение отлично работает и позволяет достичь точного выравнивания чекбоксов и их лейблов. Единственное но – данное значение может неадекватно расставить элементы последнего ряда. На определенном разрешении экрана вы увидите что-то типа:
Обратите внимание на два последних флекс элемента. Если вам по каким-либо причинам не нравится такое расположение, и вы хотите, чтобы они были рядом, можно попробовать:
удалить свойство justify-content у флекс контейнера;
добавить фиксированную ширину флекс элементов с помощью процентов (т.е. width: 50%);
переписать ширину с помощью медиа запросов. К примеру, когда ширина экрана больше 992px, задавать элементам свойство width: 25%, а не width: 50%.
Самое важное – нужно понять две вещи:
flexbox позволяет быстро создавать красивые формы;
все вышеупомянутые значения отлично работаю в нашем конкретном примере. К примеру, лейблы чекбоксов довольно небольшие, поэтому мы задали для их родителя фиксированную ширину (100px). Но если у них разная ширину, умнее задать flex: 1 100px.
Конечные стили
Добавим немного лоска и сделаем форму более презентабельной. Откройте вкладку CSS в демо ниже, посмотрите, в каких местах мы добавили цвета и отступы:
Заключение
Как видите, с минимальной разметкой и при помощи flexbox нам удалось создать адаптивную форму. Надеюсь, вы вынесли что-то полезное для себя, и будете теперь создавать свои формы на flexbox.
Что дальше
Если вы хотите улучшить данную форму, вам нужно:
улучшить внешний вид, переписав стандартные стили (например, добавить своих чекбоксов);
сделать форму динамичной. К примеру, если вы знакомы с WordPress, проверьте, можно ли создать форму Contact Form 7 или Ninja Form и сохранить структуру и стили от нашей формы.
Автор: George Martsoukos
Источник: //webdesign.tutsplus.com/
Редакция: Команда webformyself.