Выезжающее боковое меню на JS+CSS

Боковая панель сайта на чистом js и jquery

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

Сегодня поделюсь опытом создания своего бокового меню для сайта без использования тяжелых фреймворков и плагинов. Это меню будет выезжать по нажатию на кнопку гамбургера с правого бока. Кроме того это меню будет обладать эффектом акордеона – раскрывать подменю по нажатию. Ну а затем я покажу, как можно вывести обычное меню wordpress в виде нашего выезжающего меню.

Протестировать работу и посмотреть как все выглядит можно тут:

Весь процесс мы разобьем на несколько частей:

  1. Напишем на HTML кнопку-гамбургер и сам блок с меню.
  2. Опишем CSS стили как будет все выглядеть
  3. Оживим наше меню при помощи JavaScript
  4. Прикрутим наше меню к шаблону на 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>. В результате мы получим точно такое же меню как у нас было раньше, только теперь оно генерируется автоматом движком.

Пишите в комментариях получилось ли у вас сделать такое меню, и задавайте вопросы если не получается

Like this post? Please share to your friends:
Leave a Reply

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: