Dropdown меню на CSS

Пример и реализация выпадающего меню на css


Поступило от одного клиента задача переделать меню в его небольшом проекте, но при условии, чтобы оно было выпадающим (подпункты меню плавно появляются) и с минимумом js кода, а лучше и без него вообще, и Боже упаси использовать каких то «монстров», типа jquery. Решил поделиться этим примером, так как сам не раз сталкивался с подобной проблематикой, где даже чихнуть не могут без «джиэса» :-) Это прекрасный язык, но все нужно в меру.

Постановка задачи

  • Пункты меню должны быть распределены по ширине плашки и центрированы по вертикали
  • Подменю должно появляться при наведении на пункт меню, если оно соответственно в этом элементе присутствует (ul c классом .sub)
  • Необходимо рядом с пунктами меню, имеющими выпадающее подменю располагать иконку-стрелочку вниз, а при наведении заменять ее на стрелочку вверх
  • Меню должно быть адаптивным и сворачиваться при просмотре на планшетах и мобильных

Анализ и выбор решения

Первый пункт легко реализуется с помощью флексбокс, скоро (или уже?) эта технология css будет поддерживаться вообще всеми браузерами, так что выбор современного разработчика очевиден. Следующие пункты меню это тупо css, трюк с абсолютным позиционированием и сокрытием за экраном и появлении при наведении, тоже самое и с иконками-стрелочками. Последний пункт медиа-запросы и дальнейшем, возможно прикрутить «бургер» меню (пару строк нативного JS чтобы повесить обработчик клика на кнопку раскрыть меню), потом обновлю заметку.

Реализация

Построим небольшой шаблон странички (средняя часть и подвал исключительно для примера), основное, — это конечно же, header с выпадающим меню.

HTML

<!DOCTYPE html>
<html>
<head lang="en">
    <title>Elegant Menu</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="css/reset.css"/>
    <link rel="stylesheet" href="css/min/style.css"/>
</head>
<body>
<div id="wrap">
    <header class="top">
        <span class="burger"></span>
        <ul>
            <li><a href="#">Главная</a></li>
            <li><a href="#">Акции</a></li>
            <li>
                <a href="#">Новости <span class="arrow"></span></a>
                <ul class="sub">
                    <li><a href="#">Бесплатная диагностика</a></li>
                    <li><a href="#">Повышение цен на услуги</a></li>
                    <li><a href="#">Заправка картриджей</a></li>
                    <li><a href="#">Мы открылись!</a></li>
                </ul>
            </li>
            <li>
                <a href="#">Компьютеры <span class="arrow"></span></a>
                <ul class="sub">
                    <li><a href="#">Десктопы</a></li>
                    <li><a href="#">Ноутбуки</a></li>
                </ul>
            </li>
            <li><a href="#">Конструктор</a></li>
            <li><a href="#">Доставка</a></li>
        </ul>
    </header>
    <section class="middle">

        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Architecto consequuntur dolore dolorem earum enimeum libero non, quae quidem ratione rerum soluta tempore! Aliquam deleniti ex hic iste, maiores officia?</p>

        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Architecto consequuntur dolore dolorem earum enim eum libero non, quae quidem ratione rerum soluta tempore! Aliquam deleniti ex hic iste, maiores officia?</p>

        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Architecto consequuntur dolore dolorem earum enim eum libero non, quae quidem ratione rerum soluta tempore! Aliquam deleniti ex hic iste, maiores officia?</p>

        <div class="flx">
            <p>CONTENT</p>
        </div>
    </section>
</div>
<footer class="bottom">
    <p>FOOTER</p>
</footer>
<!-- Скрипт тут пустой, это в дальнейшем для обработки нажатия на кнопку раскрытия меню в мобильной версии -->
<script src="js/min/menu-min.js"></script>
</body>
</html>

Ну и конечно, не забываем про препроцессоры css:

CSS (SCSS)

// цвет рамок и фона
$gray: #ccc;

// высота меню
$menuH: 50px;

// переход к мобильной версии
$break: 730px;

// ширина всей страницы с меню
$width: 1000px;

// минимальная высота средней части
$middleH: 500px;

// время плавной анимации показа меню
$delay: 0.35s;

/*
 * — Миксины —
 */
/* флексбокс хэлпер */
@mixin alignment-by-axes() {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  display: -webkit-flex;
  -webkit-flex-direction: row;
  -webkit-justify-content: space-between;
  -webkit-align-items: center;
  @media (max-width: $break) {
    flex-direction: column;
    -webkit-flex-direction: column;
  }
}

/* сменяем формат отображения при переходе к мобильной версии */
@mixin auto-block() {
  display: block;
  height: auto;
}

/* Центруем wrap и footer */
@mixin fix-container() {
  max-width: $width;
  margin: 10px auto;
}

#wrap {
  min-height: 100%;
  @include fix-container();
  header {
    position: relative;
    height: $menuH;
    border: 1px solid $gray;
    .burger {
      cursor: pointer;
      display: none;
      position: absolute;
      right: 7%;
      top: 10px;
      width: 30px;
      height: 30px;
      background: url("../../img/list.svg");
      background-size: contain;
      @media (max-width: $break) {
        display: block;
      }
    }
    ul {
      height: 100%;
      @include alignment-by-axes();
      li {
        position: relative;
        display: table;
        height: 100%;
        a {
          display: table-cell;
          height: 100%;
          vertical-align: middle;
          text-decoration: none;
          padding: 0 15px;
          @media (max-width: $break) {
            @include auto-block();
            padding: 15px;
          }
        }
        &:hover {
          background: $gray;
        }
        &:hover ul.sub {
          left: 0;
          opacity: 1;
          border-top: 1px dotted $gray;
          @media (max-width: $break) {
            margin-top: -5px;
            display: block;
          }
        }
        &:hover .arrow {
          background: url("../../img/up-arrow.svg");
          background-size: contain;
        }
        .sub {
          display: block;
          left: -5555px;
          opacity: 0;
          position: absolute;
          top: $menuH;
          transition: $delay linear opacity;
          -webkit-transition: $delay linear opacity;
          li {
            border-bottom: 1px solid $gray;
            border-left: 1px solid $gray;
            border-right: 1px solid $gray;
            min-width: 250px;
            white-space: nowrap;
            background: #f1f1f1;
            a {
              padding: 15px;
            }
            &:hover a {
              background: $gray;
              opacity: 0.85;
            }
          }
          @media (max-width: $break) {
            position: static;
            left: 0;
            display: none;
          }
        }
        .arrow {
          display: inline-block;
          width: 10px;
          height: 10px;
          position: absolute;
          right: 44%;
          top: 65%;
          background: url("../../img/down-arrow.svg");
          background-size: contain;
          @media (max-width: $break) {
            right: 50%;
            top: 40%;
          }
        }
        @media (max-width: $break) {
          @include auto-block();
          width: 100%;
        }
      }
      @media (max-width: $break) {
        /*display: none;*/
        height: auto;
      }
    }
    @media (max-width: $break) {
      height: auto;
    }
  }

  /*
   * Средняя часть страницы section — для примера *
   */
  section {
    min-height: $middleH;
    margin: 10% 0 0 0;
    border: 1px solid $gray;
    padding: 25px;
    p {
      margin: 10px 0;
    }
    .flx {
      min-height: 300px;
      @include alignment-by-axes();
      opacity: 0.4;
      p {
        width: 100%;
        text-align: center;
      }
    }
    @media (max-width: $break) {
      margin-top: 50px;
    }
  }
  /*
   * Section End
   */

  @media (max-width: $break) {
    margin: 0;
  }
}

/*
 * Подвал — для примера *
 */
footer {
  @include fix-container();
  padding: 2% 0;
  border: 1px solid $gray;
  @include alignment-by-axes();
  p {
    width: 100%;
    text-align: center;
  }
}

Просмотр

Исходники

elegantMenu »



Похожие заметки:

Многогранный front-end. Адаптивная верстка и флексбоксы

Приемы верстки с использованием flexbox, легкое выравнивание элементов в два клика. В заметке рассказывается про адаптивную верстку, а также как без использования готового css фреймворка сделать свой адаптивный шаблон, на примере 2-колоночного макета с правой колонкой, шапкой и подвалом

Открыть здесь

Индивидуальная страница настроек в админке WordPress

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

Открыть здесь


Перед тем как писать комментарии, рекомендую ознакомиться:

Markdown синтаксис »

Оформление кода »

Нужна аватарка »

Комментарии