Как сделать меню через flex

Обновлено: 06.07.2024

Спецификация Flexbox (Flexible Box Layout Module) – это метод позиционирования элементов в горизонтальном или вертикальном направлениях.

Flexbox объединяет в себе набор свойств для родительского flex-контейнера и для дочерних flex-элементов.

Чтобы элемент стал flex-контейнером, ему надо присвоить display: flex; или display: inline-flex; (блочный или строчный соответственно).

Внутри flex-контейнера создаются две оси: главная и перпендикулярная ей поперечная. Сначала flex-элементы выстраиваются по главной оси, а потом уже по поперечной.

Свойства flex-контейнера

Это свойство не работает для однострочного flex-контейнера.

Свойства flex-элементов

order Определяет порядок следования отдельно взятого flex-элемента внутри flex-контейнера. Задается целым числом. По умолчанию равно 0, тогда элементы следуют друг за другом в порядке естественного потока. Значение order задает вес позиции элемента в последовательности, а не абсолютную позицию.
Пример flex-basis Определяет базовый размер flex-элемента перед распределением пространства в контейнере. Может быть задан в px, %, em и остальных единицах измерения. По сути это своего рода отправная точка, относительно которой происходит растягивание или сжатие элемента. Значение по умолчанию – auto, при этом размер элемента зависит от размера внутреннего контента.

В спецификации CSS Flexible Box Layout Module Level 1 приведена наглядная диаграмма для трех flex-элементов со значениями flex-grow 1, 1, 2 соответственно:

  • flex-start – flex-элемент прижимается к началу поперечной оси (по умолчанию);
  • flex-end – flex-элемент прижимается к концу поперечной оси;
  • center – flex-элемент выравнивается по центру поперечной оси;
  • baseline – flex-элемент выравнивается по базовой линии;
  • stretch – flex-элементы растягивается, занимая все доступное место по поперечной оси. Но если задана высота, то stretch будет проигнорирован.

Особенности применения Flexbox на практике

1. Выравнивание по правому краю

Чтобы прижать заголовок сайта влево, а номер телефона вправо, то заголовку надо задать flex: 1.

Медиа-запросы обычно используются в адаптивном дизайне для отображения разных макетов на разных устройствах, в зависимости от размера экрана. Для этого есть причина — некоторые макеты всегда будут выглядеть слишком сплющенными (или полностью разломаются) при просмотре на узких экранах.

Например, вы можете использовать медиа-запросы для отображения первого макета на широких экранах (настольные компьютеры, ноутбуки и др), второго макета на экранах среднего размера (планшеты, большие телефоны) и третьего макета на узких экранах (мобильные телефоны и др.).

Здесь мы возьмём созданный нами ранее макет и добавим к нему медиа-запрос, чтобы он отображался по-другому на небольших устройствах.

В этом уроке мы узнаем, как создать полноэкранную адаптивную страницу с помощью flexbox. Наша страница будет содержать полноэкранное фоновое изображение, вертикально центрированный контент и футер прижатый к низу.

Вот небольшое превью страницы, которую мы создадим (возможно вам потребуется пересмотреть полную версию):

Примечание: Этот урок предполагает, что вы немного разбираетесь во flexbox. Новичкам я советую пересмотреть эти учебные пособия и курсы:

1. Определите контейнер

Мы начнем с определения контейнера, в который поместим три элемента. А именно, header , main и footer . Вот структура страницы:

Мы хотим, чтобы страница была как минимум полноэкранной, а когда высота страницы превышает высоту окна браузера, нужно, чтобы появился ползунок прокрутки.

Благодаря flexbox мы с легкостью создадим эту функцию. Вот необходимый CSS:

Установив flex-grow: 1 в элементе main , он расширяет блок контента, чтобы покрыть доступное пространство внутри гибкого контейнера. Элементы header и footer имеют ширину по умолчанию в зависимости от их содержимого.

Что касается Internet Explorer

Некоторые версии Internet Explorer не всегда хорошо отображают минимальную высоту гибкого контейнера. В нашем примере (если вы заинтересованы в поддержке IE), одним из способов решения этой проблемы является добавление следующего правила:

Другой простой обходной путь - заменить min-height: 100vh на height: 100vh .

В любом случае, если в ваших проектах требуется поддержка IE, выберите метод, который лучше всего подходит для вашего контента и макета.

Углубляемся

Вот начальная заготовка на СodePen, элементы которой для ясности выделены разными цветами:

Теперь детально рассмотрим дочерные элементы контейнера.

2. Хедер

Хедер нашей страницы включает в себя три элемента. Логотип, навигация и кнопка призыва к действию. Вот разметка хедера:

Макет меняется в зависимости от размера вьюпорта. На узких экранах (

На более широких экранах макет меняется следующим образом:

The header appearance on wide screens
The header appearance on wide screens
The header appearance on wide screens

Чтобы достичь таких небольших изменений макета, наши стили должны соответствовать некоторым требованиям:

  • Элементы должны быть выровнены по вертикали.
  • На маленьких экранах меню должно быть последним элементом, в то время как на более широких экранах последней должна быть кнопка.
  • На маленьких экранах элементы хедера заключены в два ряда. Сама навигация находится во втором ряду. На больших экранах все элементы равномерно распределены в один ряд.

Следуя предпочтительно мобильному подходу, давайте рассмотрим наиболее важные правила для нашего хедера:

Совет: значение order по умолчанию для flex элементов равно 0 . Элементы с одинаковыми значениями order располагаются в соответствии с порядком их появления в исходном документе. По этой причине на широких экранах кнопка появляется после навигации (≥ 550 пикселей).

3. Контент элемента main

Основное содержание нашей страницы состоит из некоторого вертикально центрированного текста, расположенного поверх фонового изображения.

The appearance of the main section of our page
The appearance of the main section of our page
The appearance of the main section of our page

Вот структура для этого блока:

И самые важные стили, включая переменные CSS:

Здесь нет ничего сложного. Опять же, благодаря flexbox мы можем вертикально центрировать содержимое элемента main . Плюс просто для удовольствия, мы применяем свойство background-blend-mode для браузеров, которые его поддерживают.

4. Футер

Футер страницы включает в себя два элемента; один содержит информацию об авторских правах, а другой - ссылки на социальные сети. Вот разметка:

Опять же, расположение элементов макета должно меняться в зависимости от размера вьюпорта.

На узких экранах (

На более широких экранах макет выглядит следующим образом:

The footer appearance on wide screens
The footer appearance on wide screens
The footer appearance on wide screens

Учитывая скриншоты выше, должно произойти следующее:

  • На маленьких экранах текст должен быть последним элементом, в то время как на более широких экранах последним должен быть список социальных сетей.
  • На маленьких экранах элементы футера обернуты в два ряда. С другой стороны, на больших экранах все элементы расположены вертикально по центру и равномерно распределены в один ряд.

Основные стили для нашего футера:

Иконки

Наконец, что не менее важно, для отображения иконок я подключил пакет иконок Ionicons.

The required CSS settings
The required CSS settings
The required CSS settings

Заключение

В этом уроке мы рассмотрели процесс создания полноэкранной адаптивной страницы с помощью flexbox. Процесс был простым и дал нам возможность улучшить навыки работы с flexbox.

В следующем уроке мы пойдем еще дальше и рассмотрим, как на этой странице анимировать элементы. До встречи!

Первом делом давайте сначала посмотрим на демку, чтобы понять нужно вообще читать дальше или нет. Откройте страницу с меню и уменьшайте размер экрана.

Теперь давайте разберем подробнее как это все работает. Вы можете скачать исходники плагина flexMenu с гитхаб, официальной странички разработчика. Здесь же найдете и демо, и документацию к использованию. Но у кого туго с английским я разберу документацию здесь. Ничего сложного нет, подключается и вызывается плагин также, как и любой другой для jQuery. Также не забываем сначала подключить саму библиотеку jQuery.

Если заметили, мы помимо jQuery и самого flexMenu подключили еще и Modernizr. Подключение библиотеки Modernizr не является обязательным. Оно просто определяет сенсорные устройства, т.е. если меню открыто на мобильном устройстве с сенсорным экраном, то тегу HTML будет добавлен дополнительный класс — js touch. С помощью данного класса мы можем придать другие стили для мобильных устройств, чтобы было удобнее открывать подпункты, щелкая пальцем.

HTML-код меню

Приведу HTML-код меню, чтобы было понятнее использование классов при вызове плагина.

Использование плагина

Дополнительные опции

threshold

(Число, по умолчанию — 2). Честно казать, не знаю в чем полезность данной опции. Более того, я считаю, что она должна работать немного по другому.

Данной опции передаем имеющееся количество пунктов меню и при этом пункты не будут прятаться в подпункты, а будут просто переноситься на новую строку. Для чего это нужно — понятия не имею. На мой взгляд должно быть так — задаем число, при котором пункты меню перестают прятаться в подпункты и переносятся на новую строку. Хотя и это не знаю где может пригодиться. В общем, объяснение я этому не нашел.

cutoff

linkText

linkTitle

linkTextAll

(Строка, по умолчанию — Menu). Текст ссылки раскрытия всех подпунктов. Это когда все пункты прячутся в одну кнопку.

linkTitleAll

(Строка, по умолчанию — Menu). Атрибут title для ссылки раскрытия всех подпунктов. Опять же, можно задать подсказку при наведении курсора.

shouldApply

showOnHover

popupAbsolute

(Boolean, по умолчанию — true). По умолчанию выпадающему списку задается правило — position: absolute . Если вам нужно как-то по другому настроить выпадение без абсолютного позиционирования, то выставьте данное значение в false .

popupClass

(Строка, по умолчанию доп. класс не выводится). Дополнительный класс выпадающему списку. Сделано для удобства, если вас чем-то не устраивает имеющийся класс.

Вот и все опции.

Где можно применить FlexMenu?

Также flexMenu может пригодиться при адаптации хлебных крошек (навигатор на сайте). Бывают длинные пункты у хлебных крошек и они переносятся на следующую строку, что в свою очередь не очень удобно смотрится на мобильных устройствах. Как раз с помощью данного плагина можно оставить в одну строку то количество пунктов, которые помещаются в экран мобильного устройства.

Вот такой вот полезный скрипт. Внедряйте и делайте свои сайты удобными. На этом у меня все. До встречи в следующих постах!

[attention] Если вы хотите внедрить данный скрипт на свой сайт, но не хотите или не понимаете как это делать, то можете обратиться ко мне через форму обратной связи. Я вам помогу. Стоить данная услуга будет — 500 руб. [/attention]

CSS Flexbox — это технология для создания сложных гибких макетов за счёт правильного размещения элементов на странице. О самой технологии пишут здесь. Мы же решили объяснить возможности CSS Flexbox с использованием гифок.

Примечание Вы читаете улучшенную версию некогда выпущенной нами статьи.

display: flex

На ней размещено 4 div разных размеров, которые находятся внутри серого div . У каждого div есть свойство display: block . Поэтому каждый блок занимает всю ширину строки. Чтобы начать работать с CSS Flexbox, нужно сделать контейнер flex-контейнером. Делается это так:

Так у блоков появилось свойство flex-контекст, которое в дальнейшем позволит ими управлять гораздо проще, чем с использованием стандартного CSS.

flex-direction

У flex-контейнера есть две оси: главная и перпендикулярная ей.

CSS Flexbox: оси flex-контейнера

По умолчанию все предметы располагаются вдоль главной оси — слева направо. Именно поэтому блоки в предыдущем примере выстроились в линию, когда мы применили display: flex . А вот flex-direction позволяет вращать главную ось.

Обратите внимание, что flex-direction: column не выравнивает блоки по оси, перпендикулярной главной. Главная ось сама меняет своё расположение, и теперь направлена сверху вниз.

Есть ещё парочка свойств для flex-direction : row-reverse и column-reverse .

justify-content

Отвечает за выравнивание элементов по главной оси:

Justify-content может принимать 5 значений:

  1. flex-start
  2. flex-end
  3. center
  4. space-between
  5. space-around

Space-between задаёт одинаковое расстояние между блоками, но не между контейнером и блоками. Space-around также задаёт одинаковое расстояние между блоками, но теперь расстояние между контейнером и блоками равно половине расстояния между блоками.

align-items

Если justify-content работает с главной осью, то align-items работает с осью, перпендикулярной главной оси. Вернёмся к flex-direction: row и пройдёмся по командам align-items :

  1. flex-start
  2. flex-end
  3. center
  4. stretch
  5. baseline

Стоит заметить, что для align-items: stretch высота блоков должна быть равна auto . Для align-items: baseline теги параграфа убирать не нужно, иначе получится так:


Чтобы получше разобраться в том, как работают оси, объединим justify-content с align-items и посмотрим, как работает выравнивание по центру для двух свойств flex-direction :

align-self

Позволяет выравнивать элементы по отдельности:

Для двух блоков применим align-self , а для остальных — align-items: center и flex-direction: row .

flex-basis

Отвечает за изначальный размер элементов до того, как они будут изменены другими свойствами CSS Flexbox:

flex-basis влияет на размер элементов вдоль главной оси. Давайте посмотрим, что случится, если мы изменим направление главной оси:

Заметьте, что нам пришлось изменить и высоту элементов: flex-basis может определять как высоту элементов, так и их ширину в зависимости от направления оси.

flex-grow

Это свойство немного сложнее. Для начала зададим блокам одинаковую ширину в 120px:

flex-grow

По умолчанию значение flex-grow равно 0. Это значит, что блокам запрещено увеличиваться в размерах. Зададим flex-grow равным 1 для каждого блока:

CSS Flexbox: flex-grow

Теперь блоки заняли оставшееся место в контейнере. Но что значит flex-grow: 1 ? Попробуем сделать flex-grow равным 999:


И… ничего не произошло. Так получилось из-за того, что flex-grow принимает не абсолютные значения, а относительные. Это значит, что не важно, какое значение у flex-grow , важно, какое оно по отношению к другим блокам:

Вначале flex-grow каждого блока равен 1, в сумме получится 6. Значит, наш контейнер разделён на 6 частей. Каждый блок будет занимать 1/6 часть доступного пространства в контейнере. Когда flex-grow третьего блока становится равным 2, контейнер делится на 7 частей: 1 + 1 + 2 + 1 + 1 + 1. Теперь третий блок занимает 2/7 пространства, остальные — по 1/7. И так далее.

flex-grow работает только для главной оси, пока мы не изменим её направление.

flex-shrink

Прямая противоположность flex-grow . Определяет, насколько блоку можно уменьшиться в размере. flex-shrink используется, когда элементы не вмещаются в контейнер. Вы определяете, какие элементы должны уменьшиться в размерах, а какие — нет. По умолчанию значение flex-shrink для каждого блока равно 1. Это значит, что блоки будут сжиматься, когда контейнер будет уменьшаться.

Зададим flex-grow и flex-shrink равными 1:

Теперь поменяем значение flex-shrink для третьего блока на 0. Ему запретили сжиматься, поэтому его ширина останется равной 120px:

flex-shrink основывается на пропорциях. То есть, если у первого блока flex-shrink равен 6, а у остальных он равен 2, то, это значит, что первый блок будет сжиматься в три раза быстрее, чем остальные.

Заменяет flex-grow , flex-shrink и flex-basis . Значения по умолчанию: 0 (grow) 1 (shrink) auto (basis) .

Создадим два блока:

У обоих одинаковый flex-basis . Это значит, что оба будут шириной в 300px (ширина контейнера: 600px плюс margin и padding ). Но когда контейнер начнет увеличиваться в размерах, первый блок (с большим flex-grow ) будет увеличиваться в два раза быстрее, а второй блок (с наибольшим flex-shrink ) будет сжиматься в два раза быстрее:

Ещё больше возможностей свойства вы можете найти в анимированном руководстве по CSS flex​.

Дополнительно

Как с CSS Flexbox меняется размер?

Когда увеличивается первый блок, он не становится в два раза больше второго, и когда уменьшается второй, он также не становится в два раза меньше первого. Это происходит из-за того, что flex-grow и flex-shrink отвечают за темп роста и сокращения.

Немного математики

Начальный размер контейнера: 640px. Вычтем по 20px с каждой стороны для padding , и у нас останется 600px для двух блоков. Когда ширина контейнера становится равной 430px (потеря в 210px), первый блок ( flex-shrink: 1 ) теряет 70px. Второй блок ( flex-shrink: 2 ) теряет 140px. Когда контейнер сжимается до 340px, мы теряем 300px. Первый блок теряет 100px, второй — 200px. То же самое происходит и с flex-grow .

Если вы также интересуетесь CSS Grid, можете ознакомиться с нашей статьёй, где мы рассматриваем Flexbox и Grid.

Читайте также: