Статьи

Создание мега-меню с Flexbox

Мега Меню с Flexbox

Как вы, наверное, знаете, Flexbox в последнее время набирает обороты благодаря расширению поддержки браузеров . Это позволяет разработчикам создавать сложные пользовательские интерфейсы, не сталкиваясь с нежелательными взломами CSS и JavaScript.

Flexbox использует модель линейного макета, которая позволяет нам размещать наш контент по горизонтали или по вертикали без использования вычислений для пробелов. Гибкая компоновка реагирует на элементы в контейнере, что требует меньше медиа-запросов.

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

Я не буду подробно обсуждать отдельные свойства Flexbox, но вместо этого основное внимание будет уделено практическому использованию функций. Для базового знакомства с Flexbox, пожалуйста, обратитесь к следующим ресурсам:

Что мы строим?

Чтобы получить представление о том, что я покажу вам, как создавать, взгляните на полноэкранный CodePen .

Этот урок разделен на три части:

  1. Создание панели навигации: использование flexbox для создания простой панели навигации для нашей воображаемой платформы электронной коммерции
  2. Создание единого раскрывающегося раздела
  3. Ограничение одного раскрывающегося раздела тремя столбцами

Построение панели навигации

Разметка для панели навигации проста. Я буду обрабатывать все с двумя классами ( navbarmenu CSS здесь исключит любые стили, не связанные с учебником.

 <nav class="navbar">
  <ul class="menu">
    <li>
      <a href="#">
        Electronics
        <!-- FontAwesome icon -->
        <i class="fa fa-angle-down"></i>
      </a> 
    </li>

    <!-- ... More nav items here... -->

  <ul>
</nav>

Класс navbarmenu

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

Во-первых, мне нужно установить контекст гибкого форматирования для элемента .menudisplay: flex Теперь все прямые .menuflex: 1

Далее я хочу, чтобы пункты меню были одинаковыми по ширине. Я добавил .navbar .menu {
display: flex;
position: relative;
}

.navbar .menu li {
flex: 1;
display: flex;
text-align: center;
}

.navbar .menu a {
flex: 1;
justify-content: center;
color: #ffffff;
padding: 20px;
} Вот код:

 display: flex

Глядя на код, вы можете спросить, почему я повторил .navbar .menu lidisplay

В демоверсии, когда вы наводите курсор мыши на элемент меню, цвет его фона меняется. Если я не установлю свойство flexlia

Чтобы содержимое расширялось до полной ширины его родительского элемента, я сам превратил flex-элементы в flex-контейнеры. Имея это в виду, я могу сделать так, чтобы каждый вложенный элемент увеличивался в ширину по сравнению с его родительским элементом (используя flex: 1

В качестве альтернативы, я мог бы также добиться этого без создания гибких контейнеров элементов lidisplay: inline-blockwidth: 100%box-sizing: border-box

Эта демонстрация показывает, что сделано до сих пор .

Всего пять свойств CSS Flexbox, и панель навигации готова. Как видите, это чистое решение.

В следующем разделе я покажу вам, как создать отдельный раздел мега-навигации.

Создание единого раскрывающегося раздела

Ниже приведена разметка, которую я собираюсь использовать для создания одного раскрывающегося раздела, который будет охватывать несколько разделов. Элемент container__list

 <ul class="container">
  <!-- single column -->
  <div class="container__list">
    <!-- menu item -->
    <div class="container__listItem">
      <div>Televisions</div>
    </div>

    <!-- ... other menu items here -->

  </div>
</ul>

containercontainer__list У каждого container__listcontainer__listItem Я завернул содержимое в div

Вот CSS:

 .container {
  /* initially hidden; display:flex on hover */
  display: none;
  position: absolute;
  top: 56px;
  left: 0;
  right: 0;
  background-color: #ffffff;
  padding: 20px;
  text-align: left;
}

.container__list {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
}

.container__listItem {
  flex: 0 0 25%;
  padding: 10px 30px;
}

.container__listItem > div {
  color: #DB6356;
}

Обратите внимание, что я использовал свойство flex-wrapcontainer__list Как упоминалось ранее, я не хочу, чтобы элементы навигационной панели переносились на следующую строку при недостатке места. Вместо этого они уменьшаются в равной степени при уменьшении доступного горизонтального пространства.

Однако для элементов container__list Я хочу, чтобы мой элемент списка занимал 25% пространства, таким образом вмещая максимум четыре элемента в строке, что я могу сделать, используя flex-wrap: wrap

Я также установил flex-grow0 Это полезно, потому что это препятствует тому, чтобы пункты, которые меньше чем четыре, были на одинаковом расстоянии. Установив его на 0

А как насчет содержимого, заключенного в div Я хотел охватить случай, когда вы можете предотвратить переполнение контента. Это довольно просто, когда ваш контент находится непосредственно внутри дочернего элемента flex (т.е. container__listItem Я могу использовать следующий код, чтобы заменить вырезанный текст многоточием («…»).

 .example {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

Но в этом случае я поместил содержимое в divcontainer__listItem Таким образом, вышеуказанное решение не будет работать. Статья Flexbox и усеченный текст предлагает решение. В приведенном ниже коде строки под «обновленными» комментариями в каждом блоке декларации относятся к этой проблеме:

 .container__list {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  /* updated */
  min-width: 0;
}

.container__listItem {
  flex: 0 0 25%;
  padding: 10px 30px;
  /* updated */
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.container__listItem > div {
  color: #DB6356;
  /* updated */
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

Ограничение одного раскрывающегося раздела тремя столбцами

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

Как уже упоминалось, я дважды скопирую container__list Это сделано для демонстрационных целей. В примере с реальным миром вы можете создать сгенерированный список с помощью JavaScript или с помощью внутреннего языка.

Я добавлю класс has-multi Используя этот класс мне нужно переопределить несколько свойств.

 .container.has-multi .container__list {
  flex-basis: 33.333%;
}

.container.has-multi .container__list:not(:last-child) {
  border-right: solid 1px #f3f3f3;
  margin-right: 20px;
}

.container.has-multi .container__listItem {
  flex-basis: 100%;
}

Здесь я установил для flex-basis Я изменил только flex-basisflex-growflex-shrink
Это дает мне гибкость, когда у меня есть container__list В случае только двух списков элементы container__list То есть каждый будет занимать 50% от общей ширины.

Обратите внимание, что .container__listItemflex-basis: 100%container__list Я мог бы использовать 50%, чтобы разрешить два столбца в каждом разделе.

Несколько замечаний о юзабилити Mega Menu

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

На мой взгляд, навигация по мегаменю полезна для отображения всех опций, и этот стиль навигации может эффективно использоваться на сайтах электронной коммерции. Мне нравится навигация Intel .

Заключительные слова

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

Мега выпадающая система навигации по меню — достойный способ продемонстрировать мощь и простоту Flexbox, которую, я надеюсь, я изложил в этом руководстве. Как видите, flexbox полезен не только для центрирования контента.

Если вы использовали другую технику на основе flexbox для создания системы мегаменю, не стесняйтесь сообщить нам об этом в комментариях.

Обновление: я создал адаптивную мобильную версию этих мегаменю , которую вы можете найти в этой демонстрации CodePen .