От автора: в этом руководстве мы рассмотрим простой, но эффективный способ создания 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; }
Теперь немного JavaScript
На этом этапе мы будем использовать простой код JavaScript для управления состоянием off-canvas меню. Ниже приводится описание необходимых действий:
Когда нажата кнопка .menu-open, меню должно выводиться с красивым эффектом слайда, а элемент наложения должен одновременно сдвигаться вправо. По желанию мы можем сделать больше вещей. В нашем примере мы добавляем тень к псевдо-элементу ::before для элемента наложения и выводим список меню, используя эффект проявления.
Когда нажата кнопка .menu-close, меню должно скрываться с красивым эффектом слайда, а элемент наложение должен одновременно смещаться влево.
Вот код 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.
Единственная небольшая проблема, с которой я столкнулся при тестировании, — это изменение текста, которое происходит при анимации элемента наложения. Хотя я пробовал различные подходы, я не смог найти простое решение для всех операционных систем и браузеров. Поэтому имейте в виду, что вы можете столкнуться с небольшими проблемами, связанными с отображением шрифтов.
Заключение
Вот и все, ребята! Нам удалось создать off-canvas меню с использованием относительно простого кода. Надеюсь, вам понравился конечный результат, и вы используете его для вдохновения при создании других, более функциональных off-canvas меню. И, конечно, если вы их создадите, не забудьте поделиться с нами!
Автор: George Martsoukos
Источник: https://webdesign.tutsplus.com/
Редакция: Команда webformyself.