Как создать гамбургер меню, используя только CSS и HTML
Привет! Сегодня мы создадим анимированное гамбургер меню только на CSS и HTML, используя не очевидный для многих новичков способ — чекбоксы.
Начнём!
Подготовим шаблон. В качестве кнопки для открытия / закрытия меню будем использовать тег с свойством for . Таким образом, при клике на лейбл, будет срабатывать чекбокс.
Выглядит это пока достаточно грустно:
Добавим немного стиля для кнопки:
/* скрываем чекбокс */
#menu__toggle opacity: 0;
>/* стилизуем кнопку */
.menu__btn display: flex; /* используем flex для центрирования содержимого */
align-items: center; /* центрируем содержимое кнопки */
position: fixed;
top: 20px;
left: 20px; width: 26px;
height: 26px; cursor: pointer;
z-index: 1;
>/* добавляем "гамбургер" */
.menu__btn > span,
.menu__btn > span::before,
.menu__btn > span::after display: block;
position: absolute; width: 100%;
height: 2px; background-color: #616161;
>
.menu__btn > span::before content: '';
top: -8px;
>
.menu__btn > span::after content: '';
top: 8px;
>
Теперь стилизуем само меню. По-умолчанию оно будет скрыто — visibility: hidden , а открываться будет при установки галки на чекбокс.
/* контейнер меню */
.menu__box display: block;
position: fixed;
visibility: hidden;
top: 0;
left: -100%; width: 300px;
height: 100%; margin: 0;
padding: 80px 0; list-style: none;
text-align: center; background-color: #ECEFF1;
box-shadow: 1px 0px 6px rgba(0, 0, 0, .2);
>/* элементы меню */
.menu__item display: block;
padding: 12px 24px; color: #333; font-family: 'Roboto', sans-serif;
font-size: 20px;
font-weight: 600; text-decoration: none;
>
.menu__item:hover background-color: #CFD8DC;
>
Возможно, вам покажется непонятной строка .menu__btn > span , а именно комбинатор > .
Этот комбинатор находит прямых потомков элементов отобранных первым селектором.
Подробнее о нём можно прочитать здесь — https://developer.mozilla.org/ru/docs/Web/CSS/Child_selectors
Открыть / закрыть меню
Отлично, со стилизацией закончили, однако меню у нас до сих пор не работает. Самое время перейти к главной теме этого туториала — как реализовать открытие / закрытие меню только на CSS, используя чекбокс?
#menu__toggle:checked ~ .menu__btn > span transform: rotate(45deg);
>
#menu__toggle:checked ~ .menu__btn > span::before top: 0;
transform: rotate(0);
>
#menu__toggle:checked ~ .menu__btn > span::after top: 0;
transform: rotate(90deg);
>
#menu__toggle:checked ~ .menu__box visibility: visible;
left: 0;
>
По порядку, начиная с самого простого:
- Свойство transform: rotate(45deg) — поворачивает элемент на 45 градусов. Поворачивая элементы кнопки меню под разным углом, мы получаем значок “крестик”, вместо горизонтальных линий.
- Псевдокласс :checked — находит только выбранные или включенные элементы. В нашем случае при активации чекбокса он становится :сhecked . Подробнее по ссылке — https://developer.mozilla.org/ru/docs/Web/CSS/:checked
- Комбинатор ~ — находит элементы, указанные справа, которые следуют за элементом, указанным слева и имеют с ним общего родителя. Подробнее — https://developer.mozilla.org/ru/docs/Web/CSS/General_sibling_selectors
Вот что у нас получается:
Добавим немного анимации
Для этого просто добавим свойство transition-duration: .25s следующим классам:
.menu__btn > span,
.menu__btn > span::before,
.menu__btn > span::after transition-duration: .25s;
>.menu__box transition-duration: .25s;
>.menu__item transition-duration: .25s;
>
Как сделать бургер меню с разной шириной линий от правого края?
Бургер появляется, но не могу понять как его перевернуть, чтобы короткая линия отталкилавалась не от левого, а от правого края.
span
display: block;
width: 37px;
height: 4px;
margin-bottom: 5px;
position: relative;
background: #000;
>
span:nth-child(2) width: 29px;
>
- Вопрос задан более года назад
- 327 просмотров
1 комментарий
Простой 1 комментарий
Меняющееся гамбургер меню на CSS
Недавно я обнаружил эту потрясающую картинку на dribbble.com от Виталия Рубцова и не мог удержаться от желания её реализовать.
В этом уроке я расскажу, как сделать такое с помощью одного CSS, без какого-либо использования JavaScript. Итак, мы увидим некоторые трюки CSS (и SCSS), которые позволят нам добиться почти такой же плавной анимации, как и этот анимированный gif.
Вот пример того, что мы будем делать:
Разметка
Начнём со структуры HTML, которую мы будем использовать. Смотри комментарии для лучшего понимания.
Начальные стили SCSS
Теперь добавим некоторые базовые стили, чтобы получить желаемый внешний вид. Код довольно простой.
/* Базовые стили */ * < box-sizing: border-box; >html, body < margin: 0; >body < font-family: sans-serif; background-color: #F6C390; >a < text-decoration: none; >.container
Работа переключателя
Прежде чем приступать к созданию остальной части интерфейса, добавим работу переключателя, чтобы легко переходить от одного состояния к другому.
Нужный нам HTML уже на месте. А стиль, который заставляет его работать, примерно такой:
// Прячем чекбокс #toggle < display: none; >// Стили для «открытого» состояния, когда чекбокс выбран #toggle:checked < // Любой элемент, стиль которого вам нужно изменить при открытии меню, идёт здесь с селектором ~ // Стили для открытия навигационного меню, к примеру & ~ .nav < >>
Создание закрытого состояния
Чтобы сделать закрытое состояние, нам нужно преобразовать пункты меню в линии, чтобы получить иконку гамбургера. Есть несколько путей для получения такой трансформации. Мы решили сделать это следующим образом:
И вот код, который это реализует.
$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; >> > >
Магия в мелочах
Если мы посмотрим ближе на gif, то увидим, что все пункты меню перемещаются не одновременно, а в шахматном порядке. Мы можем сделать такое и в CSS! В принципе нам нужно выбрать каждый элемент (с помощью :nth-child ) и задать постепенное повышение значения transition-delay . Это, безусловно, повторяющаяся работа. А что если у нас будет больше элементов? Не волнуйтесь, мы можем сделать всё лучше, используя немного магии SCSS:
$items: 4; $transition-delay: 0.05s; .nav-item < // Задаём задержку для пунктов навигации при закрытии @for $i from 1 through $items < &:nth-child(#) < $delay: ($i - 1) * $transition-delay; transition-delay: $delay; &:before < transition-delay: $delay; >> > >
Здесь мы используем цикл, переменную и некоторые базовые арифметические операции. Вы можете больше узнать об этих и других интересных функциях на сайте документации SASS.
Обратите внимание, что с помощью этого кода мы получим желаемое пошаговое поведение для анимации закрытия. Нам нужно вычислить $delay , немного отличающийся для анимации открытия, чтобы получить обратно ступенчатый переход. Вроде этого:
$delay: ($items - $i) * $transition-delay;
Вывод
Вот мы и закончили с нашим причудливым меню! Мы также включили некоторые фиктивные элементы как в анимированном gif, и вы можете увидеть финальную демонстрацию здесь.
Итак, мы создали простое и функциональное меню только на CSS. Однако, если вы не хотите использовать систему переключения CSS, она может быть идеально заменена с помощью нескольких строк JavaScript без особых усилий.
Надеемся, этот урок оказался вам по душе и вы сочли его полезным!
Как сделать бургер-меню
У меня есть обычное меню и из него мне нужно сделать бургер меню как на этом сайте (https://www.saxoprint.co.uk/), но когда я начинаю его делать сталкиваюсь например с тем, что мое меню не располагается по вертикали. Буду супер благодарна если сможете на основе моего меню сделать хоть немного рабочий бургер-меню. Спасибо)
/* Menu ==========================*/ .menu < display: flex; position: relative; z-index: 100; background: #BDBDBD; /* text-align: center; */ box-shadow: 0px 10px 10px rgba(26, 63, 119, 0.5); >.topmenu < padding: 0 51px; justify-content: space-between; flex-wrap: wrap; display: flex; flex-direction: row; >nav a < display: block; text-align: center; text-decoration: none; transition: .2s linear; >nav ul < list-style: none; margin: 0; padding: 0; >.active < /* font-weight: bold; */ >.topmenu>li < text-align: center; display: inline-block; position: relative; >.topmenu>li>a < width: 100%; height: auto; text-transform: uppercase; color: #fff; >.a < font-weight: 500; padding: 15px 15px; >.topmenu>li:hover>a < color: #184fa3; >.active:after, .submenu-link:after < color: inherit; >.topmenu>li:hover < color: #184fa3; >.submenu li a:hover < color: #DA1111; >.submenu < position: absolute; z-index: 5; width: 300px; border: 1px solid #184fa3; box-sizing: border-box; box-shadow: 0px 4px 5px rgba(1, 102, 174, 0.22); visibility: hidden; opacity: 0; transform: translateY(10px); transition: .3s ease-in-out; >.submenu li < position: relative; >.submenu a < background: #fff; color: #1c1c1c; text-align: left; font-weight: 500; font-size: 16px; padding: 10px 20px; >.submenu .submenu < position: absolute; top: 0; >nav li:hover>.submenu
Отслеживать
задан 7 фев 2022 в 18:38
3 1 1 серебряный знак 2 2 бронзовых знака
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Переписал стили, вёрстка не затронута.
Используется немного JS.
let burger = document.querySelector('.menu-burger__header'), menu = document.querySelector('.menu'); burger.addEventListener('click', function(e) < menu.classList.toggle('active'); >);
.menu < display: block; width: 320px; height: 100%; background-color: #ccc; position: fixed; top: 0; left: 0; transform: translateX(-100%); transition: transform .3s ease-in; >.menu.active < transform: translateX(0); >.menu .container < display: block; width: 100%; height: 100%; >.menu ul < margin: 0; padding: 0; list-style: none; >/* burger */ .menu .menu-burger__header < width: 30px; height: 30px; border-radius: 3px; background: #333; position: absolute; left: calc(100% + 10px); top: 10px; cursor: pointer; >/* burger | open */ .menu .menu-burger__header::before, .menu .menu-burger__header > span, .menu .menu-burger__header::after < content: ''; display: block; width: 20px; height: 2px; border-radius: 2px; background: #fff; position: absolute; left: 50%; transform: translate(-50%, -50%); transition-duration: .3s; transition-timing-function: ease; >.menu .menu-burger__header::before < top: calc(50% - 8px); transform-origin: transition-property: top, transform; >.menu .menu-burger__header > span < top: 50%; transition-property: opacity; >.menu .menu-burger__header::after < top: calc(50% + 8px); transition-property: top, transform; >/* burger active | close */ .menu.active .menu-burger__header::before < top: 50%; transform: translate(-50%, -50%) rotate(45deg); >.menu.active .menu-burger__header > span < opacity: 0; >.menu.active .menu-burger__header::after < top: 50%; transform: translate(-50%, -50%) rotate(-45deg); >/* menu list */ .menu .topmenu < display: block; width: 100%; max-height: 100%; overflow: hidden auto; padding: 10px 20px; box-sizing: border-box; >.menu .topmenu a < display: block; color: inherit; text-decoration: none; >.menu .topmenu > li:not(:last-child) < margin-bottom: 1em; >.menu .topmenu > li > a < font-weight: bold; >/* submenu list */ .menu .topmenu .submenu < display: block; padding-left: 1em; margin-top: .5em; >.menu .topmenu .submenu > li:not(:last-child) < margin-bottom: .5em; >.menu .topmenu .submenu li:hover