От автора: в этой статье я постараюсь объяснить, как создать панель навигации, которая адаптируется к различным размерам экрана, используя Flexbox вместе с медиа-запросами.
Установка
Давайте начнём с разметки для очень простой панели навигации:
<nav> <ul class="container"> <li>Home</li> <li>Profile</li> <li class="search"> <input type="text" class="search-input" placeholder="Search"> </li> <li>Logout</li> </ul> </nav>
Элемент ul — это наш flex-контейнер, а li элементы — это flex-элементы. Чтобы преобразовать это в Flexbox макет, вот что мы сделаем:
.container { display: flex; }
И получим следующий макет:
Я добавил некоторые стили, но это не касается Flexbox. Как видите, у нас есть немного лишнего места с правой стороны. Причиной является то, что Flexbox располагает элементы слева направо и каждый элемент имеет такую ширину, насколько определяет его содержимое.
Поскольку flex-контейнер по умолчанию является блочным элементом (и является шире, чем четыре элемента), мы получим пустое место в конце.
Причина, по которой панель поиска шире, чем другие, заключается в том, что поля ввода по умолчанию имеют размер size=»20″, что различные браузеры и операционные системы интерпретируют по-разному.
Адаптивность #1
Чтобы наделить панель навигации базовой адаптивностью, мы просто зададим поисковым элементам flex значение 1.
.search { flex: 1; }
В результате этого поисковые элементы будут расширяться и уменьшаться вместе с шириной контейнера, а значит у нас не будет лишнего пространства справа.
Понятно, что панель поиска растёт во время того, как остальные остаются фиксированными, но возникает опасение, что она может стать слишком широкой по сравнению с остальными элементами. Поэтому если вам лучше, чтобы все элементы увеличивались вместе с шириной контейнера, то можете просто задать всем им значение flex 1.
.container > li { flex: 1; }
Вот что получается:
Вы можете также задать элементам разные значения flex, и это заставит их увеличиваться с разной скоростью. Не бойтесь экспериментировать с этим на площадке Scrimba. Дальше в этом руководстве мы продолжим работать с первым решением, где только панель поиска имеет значение flex.
Адаптивность #2
Наша панель навигации работает очень хорошо на широких экранах. Однако, на более узких экранах могут появится проблемы, как показано здесь:
В определённый момент становится нецелесообразным размещение всех элементов в одном ряду, потому что контейнер становится слишком узким. Чтобы решить данную проблему, мы добавим медиа-запросы и разделим четыре элемента на два ряда. Медиа-запрос вступает в действие, когда ширина экрана будет составлять 600px:
@media all and (max-width: 600px) { .container { flex-wrap: wrap; } .container > li { flex-basis: 50%; } }
Первым делом давайте мы обернем Flexbox макет в flex-wrap. По умолчанию мы имеем nowrap, так что нам придётся это изменить на wrap.
Далее мы зададим значение элемента flex-basis 50%. Это укажет Flexbox, чтобы каждый элемент занимал 50% доступной ширины, и, как результат, мы получим два элемента в ряд, вот так:
Примечание: Я также выровнял текст заполнителя по центру поля ввода.
Теперь у нас два разных состояния. Однако, этот макет всё ещё не работает на очень маленьких экранах, например, экранах мобильных телефонов в портретном режиме. Если мы продолжим уменьшать экран, то в результате получим следующееe:
Дело здесь в том, что во втором ряду больше не помещаются два элемента. Поле поиска просто слишком широкое, потому что вы не можете сделать его ширину меньше минимальной, ведь иначе оно не сможет содержать нужный контент.
Элементы «Вернуться на главную» и «Профиль» всё ещё могут выводиться в одном ряду, поэтому Flexbox позволяет им это. Такое решение неоптимально, так как мы хотим, чтобы все ряды выглядели одинаково.
Адаптивность #3
Как только один из рядов не может уместить два элемента, нам больше не нужно, чтобы эти ряды вмещали два элемента. Другими словами, на очень маленьких экранах мы сделаем панель навигации вертикальной. Мы разместим элементы один под другим.
Чтобы добиться этого, нам просто нужно изменить ширину с 50% до 100%, чтобы каждый ряд умещал только один элемент. Мы добавим контрольную точку 400px.
@media all and (max-width: 400px) { .container > li { flex-basis: 100%; } .search { order: 1; } }
Кроме того, я бы хотел добавить поле поиска в самый низ, поэтому я задаю ему значение order 1. Таким образом, получаем следующий результат:
order: 1; выдаёт нам перемещение поискового элемента вниз, потому что flex-элементы по умолчанию имеют нулевое значение, и любой элемент будет иметь большее значение, чем то, которое будет размещено после остальных. Чтобы увидеть, как это сработает, вот gif-изображение с начала статьи:
Поздравляю! Теперь вы знаете, как создавать полностью адаптивную панель навигации, используя Flexbox и медиа-запросы.
Автор: Per Harald Borgen
Источник: https://medium.freecodecamp.org/
Редакция: Команда webformyself.