Друзья, я уже писал как о том как сделать мобильное меню для сайта, но время идет и в моде уже другой тип меню – выезжающая панель с боку. Это удобно и красиво смотрится на любых дисплеях.
Сегодня поделюсь опытом создания своего бокового меню для сайта без использования тяжелых фреймворков и плагинов. Это меню будет выезжать по нажатию на кнопку гамбургера с правого бока. Кроме того это меню будет обладать эффектом акордеона – раскрывать подменю по нажатию. Ну а затем я покажу, как можно вывести обычное меню wordpress в виде нашего выезжающего меню.
Протестировать работу и посмотреть как все выглядит можно тут:
Весь процесс мы разобьем на несколько частей:
- Напишем на HTML кнопку-гамбургер и сам блок с меню.
- Опишем CSS стили как будет все выглядеть
- Оживим наше меню при помощи JavaScript
- Прикрутим наше меню к шаблону на wordpress
Итак поехали!
Напишем HTML код кнопки-гамбургера и блока с меню
Кнопку можно сделать просто картинкой, но это прошлый век, мы сделаем так чтобы она выглядела достойно и анимировалась при нажатии, это легко. Сам HTML кнопки:
<div id="nav-icon3" class="pushmenu">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
Code language: HTML, XML (xml)
Как видим тут самое главное это класс “pushmenu”, его можно добавить любому тегу и он будет срабатывать как триггер.
В моем случае 3 тега span будут как три палки гамбургера, а четвертая нужна для анимации, но об этом чуть позже.
Давайте напишем блок самой выезжающей панели, но пока без меню, чтобы было нагляднее:
<nav class="sidebar">
<div class="text d-flex p-2">
<h4>МЕНЮ САЙТА</h4>
<div id="nav-icon3" class="pushmenu opened">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
<div class="menu-main-menu-container">
// тут будет наше меню
</div>
</nav>
<div class="hidden-overley"></div>
Code language: HTML, XML (xml)
А в указанном выше месте мы поместим само меню:
<ul id="menu-main-menu">
<li class="current-menu-item"><a href="#" >Главная</a></li>
<li class="menu-parent-item"><a href="#">Услуги<i></i></a>
<ul class="sub-menu">
<li><a href="#">Какая-то услуга 1</a></li>
<li><a href="#">Какая-то услуга 2</a></li>
<li><a href="#">Какая-то услуга 4</a></li>
</ul>
</li>
<li><a href="#">Клиентам</a></li>
<li><a href="#">Контакты</a></li>
</ul>
Code language: HTML, XML (xml)
Отлично, теперь нам нужно как-то все разукрасить и задать размеры.
CSS стили для бокового выезжающего меню и кнопки гамбургера
Кнопка гамбургер имеет следующие стили:
<style>
#nav-icon3 {
width: 40px;
height: 30px;
position: relative;
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
-webkit-transition: .5s ease-in-out;
-moz-transition: .5s ease-in-out;
-o-transition: .5s ease-in-out;
transition: .5s ease-in-out;
cursor: pointer;
}
#nav-icon3 span {
display: block;
position: absolute;
height: 4px;
width: 100%;
background: #90b5cc;
border-radius: 3px;
opacity: 1;
left: 0;
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
-webkit-transition: .25s ease-in-out;
-moz-transition: .25s ease-in-out;
-o-transition: .25s ease-in-out;
transition: .25s ease-in-out;
}
#nav-icon3 span:nth-child(1) {
top: 0px;
}
#nav-icon3 span:nth-child(2),#nav-icon3 span:nth-child(3) {
top: 12px;
}
#nav-icon3 span:nth-child(4) {
top: 24px;
}
#nav-icon3.open span:nth-child(1),#nav-icon3.opened span:nth-child(1) {
top: 12px;
width: 0%;
left: 50%;
}
#nav-icon3.open span:nth-child(2),#nav-icon3.opened span:nth-child(2) {
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
#nav-icon3.open span:nth-child(3),#nav-icon3.opened span:nth-child(3) {
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
}
#nav-icon3.open span:nth-child(4),#nav-icon3.opened span:nth-child(4) {
top: 12px;
width: 0%;
left: 50%;
}
</style>
Code language: HTML, XML (xml)
Стили для блока с меню:
<style>
.sidebar #nav-icon3 span {background: #fff;}
body.sidebar-opened {overflow:hidden;}
.hidden-overley {
position: fixed;
top: 0;
left: 0;
z-index: 99;
background: #000000;
opacity:0;
width:0;
height:0;
transition: opacity 1s;
}
.hidden-overley.show {
height: 100%;
width: 100%;
opacity:0.5;
transition: opacity 1s;
}
.sidebar{
position: fixed;
z-index:100;
width: 300px;
height: 100%;
right: -300px;
top:0;
background: #fff;
transition: right 0.4s ease;
overflow: auto;
}
.sidebar .d-flex.p-2 {display:-webkit-box;display:flex;padding: 10px!important;}
.sidebar .text{
color: white;
font-size: 18px;
font-weight: 600;
line-height: inherit;
text-align: center;
background: #90b5cc;
letter-spacing: 1px;
-webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; -webkit-box-align: center; -ms-flex-align: center; align-items: center;
}
.sidebar .side-tel {font-size:0.8rem;}
.sidebar .text a {color: white;}
.sidebar.show{
right: 0px;
}
.sidebar ul{
background: none;
height: auto;
width: 100%;
list-style: none;
margin: 0;
padding:0;
}
.sidebar ul li{
line-height: 60px;
border-top: 1px solid #eee;
margin: 0;
}
.sidebar ul li:last-child{
border-bottom: 1px solid rgba(255,255,255,0.05);
}
.sidebar ul li a{
box-sizing:border-box;
position: relative;
color: #757575;
text-decoration: none;
font-size: 18px;
padding-left: 30px;
font-weight: 500;
display: block;
width: 100%;
border-left: 3px solid #eee;
}
.sidebar ul li.current-menu-item a{
color: #90b5cc;
background: #F5F5F5;
border-left-color: #90b5cc;
}
.sidebar ul li a:hover{
cursor:pointer;
background: #F5F5F5;
border-left-color: #2196F3;
}
.sidebar ul ul{
position: static;
display: none;
}
.sidebar ul .sub-menu.show{
display: block;
}
.sidebar ul ul li{
line-height: 42px;
border-top: none;
}
.sidebar ul ul li a{
font-size: 17px;
color: #333;
padding-left: 40px;
}
.sidebar ul li.current-menu-item ul li a{
color: #333;
background: #f9f9f9;
border-left-color: transparent;
}
.sidebar ul li ul li.current-menu-item a {color:#2196F3;}
.sidebar ul ul li a:hover{
color: #333!important;
background: #F5F5F5!important;
}
.sidebar ul li a i:before {display:none;}
.sidebar ul li.menu-parent-item a i:before{
content: '';
position: absolute;
top: 50%;
right: 20px;
transform: translateY(-50%);
font-size: 22px;
transition: transform 0.4s;
width: 20px;
height: 20px;
background-repeat:no-repeat;
background-position: 0 0;
background-image: url("data:image/svg+xml;charset=UTF-8,%3c?xml version='1.0' encoding='iso-8859-1'?%3e%3csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 512.011 512.011' style='enable-background:new 0 0 512.011 512.011;' xml:space='preserve'%3e%3cg%3e%3cg%3e%3cpath d='M505.755,123.592c-8.341-8.341-21.824-8.341-30.165,0L256.005,343.176L36.421,123.592c-8.341-8.341-21.824-8.341-30.165,0 s-8.341,21.824,0,30.165l234.667,234.667c4.16,4.16,9.621,6.251,15.083,6.251c5.462,0,10.923-2.091,15.083-6.251l234.667-234.667 C514.096,145.416,514.096,131.933,505.755,123.592z'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e");
background-size: contain;
display: block;
}
.sidebar ul ul a i:before {display:none !important;}
.sidebar ul li a i.rotate:before{
transform: translateY(-50%) rotate(-180deg);
}
</style>
Code language: HTML, XML (xml)
Обратите внимание что я выделил 27 строку, изначально наше меню имеет отрицательный отступ равный ширине самого меню. Так мы добились его скрытия.
На 128 строке я добавил каретку в виде SVG картинки которая показывается внутри тегов <i></i> и только там где есть подменю, при нажатии на родительский пункт меню каретка поворачивается на 180 градусов.
Красота! Подошло время вдохнуть жизнь в наше меню с помощью JS
JS для бокового выезжающего сайдбара
Если у вас уже установлен фреймворк jQuery, то весь код будет таким:
<script>
jQuery(document).ready(function($){
// Клик по кнопке-гамбургеру открывает меню, повторный клик закрывает
$('.pushmenu').click(function(){
$('.pushmenu').toggleClass("open");
$('.sidebar').toggleClass("show");
$('.hidden-overley').toggleClass("show");
$('body').toggleClass("sidebar-opened")
});
// Когда панель открыта, клик по облсти вне панели закрывает ее
$('.hidden-overley').click(function(){
$(this).toggleClass("show");
$('.sidebar').toggleClass("show");
$('.pushmenu').toggleClass("open");
$('body').toggleClass("sidebar-opened")
});
// меняем активность пункта меню по клику (НЕОБЯЗАТЕЛЬНО)
$('.sidebar ul li').click(function(){
$(this).addClass("current-menu-item").siblings().removeClass("current-menu-item");
});
// Для анимации поворота каретки
$('.menu-parent-item a:first-child').click(function(){
$(this).siblings().toggleClass("show");
$(this).find("i").toggleClass("rotate");
});
});
</script>
Code language: HTML, XML (xml)
Но если у вас не подключен jQuery, то вот код который будет делать тоже самое на чистом JavaScript:
<script>
document.addEventListener('DOMContentLoaded', () => {
// получаем все элементы с классом pushmenu
const pushmenu = document.getElementsByClassName('pushmenu');
// получаем элемент с классом hidden-overley
const hiddenOverley = document.querySelector('.hidden-overley');
// отслеживаем клик клика по оверлею
hiddenOverley.addEventListener('click', (e) => {
e.currentTarget.classList.toggle('show');
document.querySelector('.sidebar').classList.toggle('show');
document.querySelector('body').classList.toggle('sidebar-opened');
for( i=0; i < pushmenu.length; i++ ){
pushmenu[i].classList.toggle('open');
}
});
const pushmenuFunction = function() {
document.querySelector('.pushmenu').classList.toggle('open');
document.querySelector('.sidebar').classList.toggle('show');
document.querySelector('.hidden-overley').classList.toggle('show');
document.body.classList.toggle('sidebar-opened')
};
// Отслеживаем клики кнопок с классом pushmenu
for( i=0; i < pushmenu.length; i++ ){
pushmenu[i].addEventListener('click', pushmenuFunction, false);
}
// Получим все родительские элементы в меню
const sidebarAccordeon = document.querySelectorAll('.sidebar .menu-parent-item a:first-child');
const accordeonFunction = function() {
this.parentNode.querySelector('ul').classList.toggle('show');
this.querySelector('i').classList.toggle('rotate');
}
// Отслеживаем клики родительских пунктов меню
for( i=0; i < sidebarAccordeon.length; i++ ){
sidebarAccordeon[i].addEventListener('click', accordeonFunction, false);
}
});
</script>
Code language: HTML, XML (xml)
Итак мы получили рабочий выезжающий сайдбар с акордеонным меню. Я специально сделал названия классов и структуру похожую на ту которую генерирует движок WP, это я сделал на тот случай если мне нужно будет использовать этот сайдбар именно там. Далее об этом детальнее.
Настаиваем вывод WP меню в выезжающем сайдбаре
Для этого в файле шаблона вашей темы WP в том месте где вы будете выводить сайдбар нам нужно не прописывать код HTML меню вручную, а вызвать функцию wp_nav_menu(), которая отвечает за вывод меню, в нее мы може передать какие-то аргументы, чтобы она показывала меню так как нам нужно. Я писал о том как ее использовать здесь
В частности, например мы передадим в нее нужное меню, название класса меню, глубину вложенности, и тег <i> для отображения каретки у родителей:
<?php
wp_nav_menu(
array(
'theme_location' => 'menu-1',
'depth' => 2,
'menu_class' => '',
'link_after' => '<i></i>',
)
);
?>
Code language: HTML, XML (xml)
Этот код нужно вставить на том месте где у нас было меню <ul>. В результате мы получим точно такое же меню как у нас было раньше, только теперь оно генерируется автоматом движком.
Пишите в комментариях получилось ли у вас сделать такое меню, и задавайте вопросы если не получается