Гамбургер меню на css с анимацией

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

В этой статье я объясню как сделать его с помощью CSS, ни одной строчки JavaScript не будет написано. Для достижения почти точно такой же анимации как на картинке, мы применим несколько приемов CSS (и SCSS).

Гамбургер меню на css с анимацией

Html разметка для гамбургер меню

Давайте начнем с html разметки которую мы будем использовать. Для лучшего понимания прочтите комментарии в коде.

<div class="container">
    <!-- Этот checkbox позволит управлять состоянием меню, он будет визуально скрыт -->
    <input id="toggle" type="checkbox">

    <!-- ВАЖНО: Любой элемент который мы хотим изменить когда меняется состояние checkbox размещаем здесь. Что бы обратится к нему используем "sibling" селектор относительно checkbox -->

    <!-- Этот label будет связан с checkbox, и будет содержать кнопку -->
    <label class="toggle-container" for="toggle">
        <!-- Если меню будет открыто, будет отображаться иконка вида "X", иначе иконка гамбургер меню -->
        <span class="button button-toggle"></span>
    </label>

    <!-- Навигация -->
    <nav class="nav">
        <a class="nav-item" href="">Панель управления</a>
        <a class="nav-item" href="">История</a>
        <a class="nav-item" href="">Статистика</a>
        <a class="nav-item" href="">Настройки</a>
    </nav>
</div>

Базовые CSS стили

Теперь давайте добавим немного базовых стилей. Эти css правила очень просты, думаю не вызовут у вас трудностей в понимании.

/* Базовые стили */

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
}

body {
  font-family: sans-serif;
  background-color: #F6C390;
}

a {
  text-decoration: none;
}

.container {
  position: relative;
  margin: 35px auto 0;
  width: 300px;
  height: 534px;
  background-color: #533557;
  overflow: hidden;
}

Функциональность открытия и закрытия

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

// Скрываем checkbox
#toggle {
  display: none;
}

// Стили для состояния "открыто", если checkbox чекнут
#toggle:checked {
  // Любые элементы котрым нужно изменить стили при состоянии "открыто" пишем здесь, используя селектор (~)
  // К примеру, стили для открытого навигационного меню
  & ~ .nav {
  }
}

Создание меню в закрытом состоянии

Что бы создать закрытое состояние, нам нужно трансформировать элементы меню в линии что бы создать иконку гамбургер меню. Есть несколько вариантов решения, мы решили остановится на следующем:

burger menu на css

Ниже код который воплощает это в жизнь.

$transition-duration: 0.5s;

// Отображение элементов как линий, в виде иконки меню
.nav-item {
  position: relative;
  display: inline-block;
  float: left;
  clear: both;
  color: transparent;
  font-size: 14px;
  letter-spacing: -6.2px;
  height: 7px;
  line-height: 7px;
  text-transform: uppercase;
  white-space: nowrap;
  transform: scaleY(0.2);
  transition: $transition-duration, opacity 1s;

  // Задаем ширину для первой линии
  &:nth-child(1) {
    letter-spacing: -8px;
  }

  //  Задаем ширину для второй линии
  &:nth-child(2) {
    letter-spacing: -7px;
  }

  //  Задаем ширину для четвертой линии и ниже
  &:nth-child(n + 4) {
    letter-spacing: -8px;
    margin-top: -7px;
    opacity: 0;
  }

  // Стилизация иконки гамбургер меню
  &:before {
    position: absolute;
    content: '';
    top: 50%;
    left: 0;
    width: 100%;
    height: 2px;
    background-color: #EC7263;
    transform: translateY(-50%) scaleY(5);
    transition: $transition-duration;
  }
}

Обратите внимание, что здесь только основные стили для элементов навигации, они самые важные. Вы можете посмотреть весь код на github.

Создание открытого меню

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

$transition-duration: 0.5s;

#toggle:checked {

  // Открытое меню
  & ~ .nav {

    // Трансформация элементов меню из "линий"
    .nav-item {
      color: #EC7263;
      letter-spacing: 0;
      height: 40px;
      line-height: 40px;
      margin-top: 0;
      opacity: 1;
      transform: scaleY(1);
      transition: $transition-duration, opacity 0.1s;

      // Скрываем линии
      &:before {
        opacity: 0;
      }
    }
  }
}

Магия в деталях

We can do that in CSS too! Basically we need to select each element (using :nth-child) and set a progressively increased transition-delay. But that is certainly a repetitive work. And, what if we have more items? Don’t worry, we can do it better with a bit of SCSS magic:

Если мы посмотрим внимательно на gif изображение с меню, мы заметим что все элементы меню появляются и скрываются не одновременно, а друг за другом. Мы также можем сделать с помощью SCSS!

В основном нам нужно выбрать каждый элемент (используя :nth-child) и задать свойство transition-delay с значением которое увеличивается постоянно. Согласитесь, это очень рутинная работа. И что если у нас будет огромное количество элементов меню? В такой ситуации мы можем использовать преимущества SCSS.

$items: 4;
$transition-delay: 0.05s;

.nav-item {

  @for $i from 1 through $items {
    &:nth-child(#{$i}) {
      $delay: ($i - 1) * $transition-delay;
      transition-delay: $delay;
      &:before {
        transition-delay: $delay;
      }
    }
  }
}

Здесь мы используем цикл, переменную и немного простых арифметических операций. С помощью этого кода мы получим постепенную анимацию элементов. Задержку мы просчитываем с помощью следующей строки:

$delay: ($items - $i) * $transition-delay;

Подведем итоги

Так мы добавили элементы которые есть на gif изображении и вы можете посмотреть финальный результат здесь.

Мы создали крутое и функциональное гамбургер меню на CSS. Так же вы можете реализовать логику изменения состояния с помощью javaScript написав пару строк кода.

Полную версию кода вы можете просмотреть на github репозитории, а так же поиграться с примером на codepen.

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

Автор статьи Luis Manuel редакция и перевод webupblog.

Добавить комментарий

Ваш адрес email не будет опубликован.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>