Russian (Pусский) translation by Anna Goorikova (you can also view the original English article)
В этом руководстве мы рассмотрим простой, но эффективный метод создания off-canvas меню с помощью HTML, CSS и JavaScript.
Чтобы получить первоначальное представление о том, что мы будем делать, ознакомьтесь с соответствующей демонстрацией в CodePen (ознакомьтесь с полной версией для лучшего понимания):
Примечание: Это руководство не будет фокусироваться на том, как сделать off-canvas меню доступным или отзывчивым, а это, несомненно, были бы правильные следующие шаги.
1. Начнем с разметки
Наша разметка состоит из двух элементов-оберток:
- элемент
.top-banner
- элемент
.top-nav
Вот HTML код:
<section class="top-banner"> <div class="top-banner-overlay"> <!-- content here --> </div> </section> <nav class="top-nav"> <div class="menu-wrapper"> <!-- content here --> </div> <div class="fixed-menu"> <!-- content here --> </div> </nav>
2. Далее нам нужен CSS
Разметка готова, далее давайте рассмотрим наиболее важные стили, которые требуются для нашего меню.
Примечание: Для удобства чтения этот CSS-код не оптимизирован - вы заметите повторяющиеся свойства, которые вы можете убрать в своей собственной версии.
Стилизуем элемент top-banner
Элемент .top-banner
выглядит следующим образом:

Для его стилизации мы делаем следующее:
- Установите его ширину равной ширине окна минус ширина элемента
.menu-wrapper
.
- Установите его высоту, равной высоте окна.
- Определите его как flex контейнер. Это заставит его занять всю высоту родительского контейнера.
- Используйте flexbox для вертикального центрирования контента.
Вот стили, которые нам нужны для достижения всего этого:
.top-banner { display: flex; width: calc(100% - 150px); height: 100vh; transform: translateX(150px); background: url(IMAGE_PATH) no-repeat center / fixed; } .top-banner-overlay { display: flex; flex-direction: column; justify-content: center; width: 350px; padding: 20px; transition: transform .7s; color: white; background: rgba(0, 0, 0, .7); }
Стилизуем элемент top-nav
Элемент .top-nav
выглядит так:

Здесь мы сделаем следующее:
- Задайте прямым дочерним элементам, которые занимают всю высоту окна, фиксированное позиционирование.
- Используйте flexbox, чтобы выровнять элемент
.fixed-menu
по вертикали. - Скроем элемент
.menu-wrapper
по умолчанию. Чтобы сделать это, мы не будем задавать ему такое свойство, какdisplay: none
. Мы используем функциюtranslate()
, чтобы переместить его на 200 пикселей влево. Имейте в виду, что ширина элемента составляет 350 пикселей, поэтому его часть все еще находится в области просмотра. Однако это не видно, потому что элемент расположен под элементом.fixed-menu
. - Скройте список меню.
Посмотрите на соответствующие стили CSS ниже:
.top-nav .menu-wrapper { position: fixed; top: 0; left: 0; bottom: 0; width: 350px; padding: 20px; transform: translateX(-200px); transition: transform .7s; background: #B1FFE5; } .top-nav .menu-wrapper .menu { opacity: 0; transition: opacity .4s; } .top-nav .fixed-menu { position: fixed; top: 0; left: 0; bottom: 0; display: flex; flex-direction: column; width: 150px; padding: 20px; background: aquamarine; }
3. Теперь немного JavaScript
Здесь мы будем использовать простой JavaScript-код для управления состоянием off-canvas меню.
Опишем необходимые действия:
- Когда нажата кнопка
.menu-open
, меню должно появиться с красивым slide-in эффектом, а наложение должно быть одновременно подвинуто вправо. По желанию мы можем сделать намного больше вещей на этом шаге. В нашем примере мы добавляем box shadow к псевдо-элементу оверлея::before
и показываем список меню, используя эффект затухания. - Когда нажата кнопка
.menu-close
, меню должно исчезнуть с красивым slide-out эффектом, а наложение должно быть одновременно подвинуто влево.
Вот код JavaScript, который реализует это поведение:
const menuOpen = document.querySelector(".top-nav .menu-open"); const menuClose = document.querySelector(".top-nav .menu-close"); const menuWrapper = document.querySelector(".top-nav .menu-wrapper"); const topBannerOverlay = document.querySelector(".top-banner-overlay"); function toggleMenu() { menuOpen.addEventListener("click", () => { menuWrapper.classList.add("is-opened"); topBannerOverlay.classList.add("is-moved"); }); menuClose.addEventListener("click", () => { menuWrapper.classList.remove("is-opened"); topBannerOverlay.classList.remove("is-moved"); }); } toggleMenu();
Ниже вы найдете необходимые CSS стили:
.top-banner-overlay.is-moved { transform: translateX(350px); } .top-banner-overlay.is-moved::before { content: ''; position: absolute; top: 0; bottom: 0; right: 100%; width: 20px; box-shadow: 0 0 10px black; } .top-nav .menu-wrapper.is-opened { transform: translateX(150px); } .top-nav .menu-wrapper.is-opened .menu { opacity: 1; transition-delay: .6s; }
4. Поддерживаемые браузеры
Эта демонстрация будет хорошо работать только на настольных браузерах. Для мобильных устройств потребуется другой макет страницы, но это выходит за рамки данного руководства. Как обычно, мы используем Babel для компиляции кода ES6 до ES5.
Единственная небольшая проблема, с которой я столкнулся при тестировании, это изменение текста, которое происходит при анимации оверлея. Хотя я пробовал различные подходы, предлагаемые в разных ветках Stack Overflow, я не смог найти простое решение для всех операционных систем и браузеров. Поэтому имейте в виду, что вы можете увидеть небольшие проблемы с отображением шрифтов из-за анимации оверлея.
Заключение
Вот и все, ребята! Нам удалось создать полезное off-canvas меню с относительно простым кодом.
Надеюсь, вам понравился конечный результат, и вы будете использовать его в качестве вдохновения для создания еще более мощных off-canvas меню. И, конечно, если вы их сделаете, не забудьте поделиться ими с нами!
Узнайте больше Off-Canvas техник
- CSSКак сделать Off-Canvas навигацию с помощью CSS GridIan Yates
- Дизайн НавигацииКак сделать Off-Canvas навигацию с помощью плагина jQuery.mmenuGeorge Martsoukos
- Отзывчивый Веб ДизайнКак сделать off-canvas навигацию с помощью BootstrapThoriq Firdaus
- Отзывчивый Веб ДизайнНебольшой совет: не забудьте метатег ViewportIan Yates
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post