jQuery & CSS3 меню аккордеон с помощью CSS Menu Maker
Еще совсем недавно, работая над очередным шаблоном, мне приходилось перелопачивать кучу кода, подбирать цветовую гамму, чтобы сделать оригинальное меню навигации. Уверен, вы проделывали тужу работу и не раз. Сейчас, на просторах глобальной сети появляются различные онлайн-генераторы и целые конструкторы, с помощью которых можно за несколько минут забабахать вполне себе достойное меню любого типа, горизонтальное, вертикальное, многоуровневое и полностью адаптивное.
Какие-то сервисы предлагают работать с чистого листа, предоставляя лишь выбор различных инструментов и визуальный предпросмотр результата, а более продвинутые, предлагают готовые шаблоны менюшек, которые вы с легкость можете подстроить в соответствии вашему вкусу и требованиям дизайна вашего проекта.
CSS Menu Maker как раз и является таким онлайн-конструктором, загляните на досуге, и я уверен, ваша обойма инструментов, обязательно пополнится.
В подтверждение всему вышеизложенному, хочу продемонстрировать вам меню созданное с помощью этого онлайн-конструктора.
Если вы дорожите каждым пикселем свободного места в боковой колонке своего сайта, то это компактное меню стиле «аккордеон» именно для вас! Посмотрите живой пример работы этого замечательного меню, а затем без суеты, разберём его на составляющие.
CSS Menu Maker отлично справляется со своим делом, на выхлопе мы получаем прилично структуированную разметку HTML и хорошо читаемый, упорядоченный код css, все необходимые библиотеки подключены, расклад предельно ясен и понятен.
HTML Разметка
<ul id="menu"> <ul> <li><a href="#"><i class="fa fa-home fa-fw"></i> <span>Главная</span></a></li> <li class="active has-sub"><a href="#"><i class="fa fa-sitemap"></i> <span>Категории</span></a> <ul> <li class="has-sub"><a href="#"><span>Категория 1</span></a> <ul> <li><a href="#"><span>Подкатегория 1</span></a></li> <li><a href="#"><span>Подкатегория 2</span></a></li> <li class="last"><a href="#"><span>Подкатегория 3</span></a></li> </ul> </li> <li class="has-sub"><a href="#"><span>Категория 2</span></a> <ul> <li><a href="#"><span>Подкатегория 1</span></a></li> <li class="last"><a href="#"><span>Подкатегория 2</span></a></li> </ul> </li> </ul> </li> <li><a href="#"><i class="fa fa-life-ring"></i> <span>О Сайте</span></a></li> <li class="last"><a href="#"><i class="fa fa-envelope"></i> <span> Контакты</span></a></li> </ul> </ul> |
<ul id=”menu”> <ul> <li><a href=”#”><i class=”fa fa-home fa-fw”></i> <span>Главная</span></a></li> <li class=”active has-sub”><a href=”#”><i class=”fa fa-sitemap”></i> <span>Категории</span></a> <ul> <li class=”has-sub”><a href=”#”><span>Категория 1</span></a> <ul> <li><a href=”#”><span>Подкатегория 1</span></a></li> <li><a href=”#”><span>Подкатегория 2</span></a></li> <li class=”last”><a href=”#”><span>Подкатегория 3</span></a></li> </ul> </li> <li class=”has-sub”><a href=”#”><span>Категория 2</span></a> <ul> <li><a href=”#”><span>Подкатегория 1</span></a></li> <li class=”last”><a href=”#”><span>Подкатегория 2</span></a></li> </ul> </li> </ul> </li> <li><a href=”#”><i class=”fa fa-life-ring”></i> <span>О Сайте</span></a></li> <li class=”last”><a href=”#”><i class=”fa fa-envelope”></i> <span> Контакты</span></a></li> </ul> </ul>
Как видите, меню построено в виде неупорядоченного списка с вложениями. Основным пунктам добавлены иконки из коллекции Font Awesome, <i>
тэг с названием значка в конкретном CSS классе:
<i class="fa fa-home fa-fw"> |
<i class=”fa fa-home fa-fw”>
Иконки подгружаются из библиотеки Bootstrap, которую мы заблаговременно подключили в разделе <head>...</head>
нашего документа:
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet"> |
<link href=”http://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css” rel=”stylesheet”>
Возникнет потребность изменить иконки, узнать класс той или иной шрифт-иконки, можно непосредственно на сайте разработчика: Тынц>>.
Каркас выстроен, осталось самое интересное, сформировать стили CSS, чтобы наш «аккордеон», визуально выглядел, как надо.
Стили CSS
В оформлении внешнего вида задействованы современные свойства CSS3, лёгкая наружная тень с помощью box-shadow
, мягкий налёт градиента через background: linear-gradient
и добавим чуточку тени для текста. Как вы понимаете, в старых версиях браузера IE, наш замечательный аккордеон, будет выглядеть, мягко говоря, немного иначе (((.
/* * Стили для меню аккордеон */ @import url(http://fonts.googleapis.com/css?family=Open+Sans:400,300,700&subset=latin,cyrillic); #menu, #menu ul, #menu ul li, #menu ul li a { position: relative; display: block; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; margin: 0; padding: 0; border: 0; list-style: none; line-height: 1; } #menu {margin: 0 auto; width: 200px; box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.45); color: #ffffff; font-family: 'Open Sans', Calibri, Arial, sans-serif; } #menu ul ul { display: none; } .align-right { float: right; } #menu > ul > li > a { z-index: 2; padding: 15px 20px; border-top: 1px solid #1682ba; border-right: 1px solid #1682ba; border-left: 1px solid #1682ba; background: #36aae7; background: -webkit-linear-gradient(#36aae7, #1fa0e4); background: -moz-linear-gradient(#36aae7, #1fa0e4); background: -o-linear-gradient(#36aae7, #1fa0e4); background: -ms-linear-gradient(#36aae7, #1fa0e4); background: linear-gradient(#36aae7, #1fa0e4); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15); color: #fff; text-decoration: none; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35); font-weight: 400; font-size: 14px; cursor: pointer; } #menu > ul > li > a:hover, #menu > ul > li.active > a, #menu > ul > li.open > a { background: #1fa0e4; background: -webkit-linear-gradient(#1fa0e4, #1992d1); background: -moz-linear-gradient(#1fa0e4, #1992d1); background: -o-linear-gradient(#1fa0e4, #1992d1); background: -ms-linear-gradient(#1fa0e4, #1992d1); background: linear-gradient(#1fa0e4, #1992d1); color: #eeeeee; } #menu > ul > li.open > a { border-bottom: 1px solid #1682ba; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.15); } #menu > ul > li:last-child > a, #menu > ul > li.last > a { border-bottom: 1px solid #1682ba; } .holder { position: absolute; top: 0; right: 0; width: 0; height: 0; } .holder::after, .holder::before { position: absolute; right: 20px; z-index: 10; display: block; width: 6px; height: 6px; content: ""; -webkit-transform: rotate(-135deg); -moz-transform: rotate(-135deg); -ms-transform: rotate(-135deg); -o-transform: rotate(-135deg); transform: rotate(-135deg); } .holder::after { top: 17px; border-top: 2px solid #ffffff; border-left: 2px solid #ffffff; } #menu > ul > li > a:hover > span::after, #menu > ul > li.active > a > span::after, #menu > ul > li.open > a > span::after { border-color: #eeeeee; } .holder::before { top: 18px; border-top: 2px solid; border-top-color: inherit; border-left: 2px solid; border-left-color: inherit; } #menu ul ul li a { z-index: 1; padding: 10px 20px; border-right: 1px solid #32373e; border-bottom: 1px solid #32373e; border-left: 1px solid #32373e; background: #49505a; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); color: #eeeeee; text-decoration: none; font-size: 13px; cursor: pointer; } #menu ul ul li:hover > a, #menu ul ul li.open > a, #menu ul ul li.active > a { background: #424852; color: #fff; } #menu ul ul li:first-child > a { box-shadow: none; } #menu ul ul ul li:first-child > a { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); } #menu ul ul ul li a { padding-left: 30px; } #menu > ul > li > ul > li:last-child > a, #menu > ul > li > ul > li.last > a { border-bottom: 0; } #menu > ul > li > ul > li.open:last-child > a, #menu > ul > li > ul > li.last.open > a { border-bottom: 1px solid #32373e; } #menu > ul > li > ul > li.open:last-child > ul > li:last-child > a { border-bottom: 0; } #menu ul ul li.has-sub > a::after { position: absolute; top: 11.5px; right: 20px; z-index: 10; display: block; width: 5px; height: 5px; border-top: 2px solid #eeeeee; border-left: 2px solid #eeeeee; content: ""; -webkit-transform: rotate(-135deg); -moz-transform: rotate(-135deg); -ms-transform: rotate(-135deg); -o-transform: rotate(-135deg); transform: rotate(-135deg); } #menu ul ul li.active > a::after, #menu ul ul li.open > a::after, #menu ul ul li > a:hover::after { border-color: #ffffff; } |
/* * Стили для меню аккордеон */ @import url(https://fonts.googleapis.com/css?family=Open+Sans:400,300,700&subset=latin,cyrillic); #menu, #menu ul, #menu ul li, #menu ul li a { position: relative; display: block; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; margin: 0; padding: 0; border: 0; list-style: none; line-height: 1; } #menu {margin: 0 auto; width: 200px; box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.45); color: #ffffff; font-family: ‘Open Sans’, Calibri, Arial, sans-serif; } #menu ul ul { display: none; } .align-right { float: right; } #menu > ul > li > a { z-index: 2; padding: 15px 20px; border-top: 1px solid #1682ba; border-right: 1px solid #1682ba; border-left: 1px solid #1682ba; background: #36aae7; background: -webkit-linear-gradient(#36aae7, #1fa0e4); background: -moz-linear-gradient(#36aae7, #1fa0e4); background: -o-linear-gradient(#36aae7, #1fa0e4); background: -ms-linear-gradient(#36aae7, #1fa0e4); background: linear-gradient(#36aae7, #1fa0e4); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15); color: #fff; text-decoration: none; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35); font-weight: 400; font-size: 14px; cursor: pointer; } #menu > ul > li > a:hover, #menu > ul > li.active > a, #menu > ul > li.open > a { background: #1fa0e4; background: -webkit-linear-gradient(#1fa0e4, #1992d1); background: -moz-linear-gradient(#1fa0e4, #1992d1); background: -o-linear-gradient(#1fa0e4, #1992d1); background: -ms-linear-gradient(#1fa0e4, #1992d1); background: linear-gradient(#1fa0e4, #1992d1); color: #eeeeee; } #menu > ul > li.open > a { border-bottom: 1px solid #1682ba; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.15); } #menu > ul > li:last-child > a, #menu > ul > li.last > a { border-bottom: 1px solid #1682ba; } .holder { position: absolute; top: 0; right: 0; width: 0; height: 0; } .holder::after, .holder::before { position: absolute; right: 20px; z-index: 10; display: block; width: 6px; height: 6px; content: “”; -webkit-transform: rotate(-135deg); -moz-transform: rotate(-135deg); -ms-transform: rotate(-135deg); -o-transform: rotate(-135deg); transform: rotate(-135deg); } .holder::after { top: 17px; border-top: 2px solid #ffffff; border-left: 2px solid #ffffff; } #menu > ul > li > a:hover > span::after, #menu > ul > li.active > a > span::after, #menu > ul > li.open > a > span::after { border-color: #eeeeee; } .holder::before { top: 18px; border-top: 2px solid; border-top-color: inherit; border-left: 2px solid; border-left-color: inherit; } #menu ul ul li a { z-index: 1; padding: 10px 20px; border-right: 1px solid #32373e; border-bottom: 1px solid #32373e; border-left: 1px solid #32373e; background: #49505a; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); color: #eeeeee; text-decoration: none; font-size: 13px; cursor: pointer; } #menu ul ul li:hover > a, #menu ul ul li.open > a, #menu ul ul li.active > a { background: #424852; color: #fff; } #menu ul ul li:first-child > a { box-shadow: none; } #menu ul ul ul li:first-child > a { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); } #menu ul ul ul li a { padding-left: 30px; } #menu > ul > li > ul > li:last-child > a, #menu > ul > li > ul > li.last > a { border-bottom: 0; } #menu > ul > li > ul > li.open:last-child > a, #menu > ul > li > ul > li.last.open > a { border-bottom: 1px solid #32373e; } #menu > ul > li > ul > li.open:last-child > ul > li:last-child > a { border-bottom: 0; } #menu ul ul li.has-sub > a::after { position: absolute; top: 11.5px; right: 20px; z-index: 10; display: block; width: 5px; height: 5px; border-top: 2px solid #eeeeee; border-left: 2px solid #eeeeee; content: “”; -webkit-transform: rotate(-135deg); -moz-transform: rotate(-135deg); -ms-transform: rotate(-135deg); -o-transform: rotate(-135deg); transform: rotate(-135deg); } #menu ul ul li.active > a::after, #menu ul ul li.open > a::after, #menu ul ul li > a:hover::after { border-color: #ffffff; }
Шрифт текста пунктов меню, используем из семейства Open Sans с поддержкой кирилицы, подключив его к CSS через @import
, напрямую из огромной библиотеки шрифтов Google. Вам ничто не мешает использовать любой другой шрифт, лишь бы в радость и на пользу дела.
Вот и всё! Мы построили каркас, обернули его в красивую обёртку, теперь необходимо «ударить по мехам», завести наш аккордеон. Для этого нам понадобится помощь jQuery. Если у вас ещё не подключена актуальная версия этой популярнейшей javscript библиотеки, смело подключайте, добавив в конец документа, пред тегом следующее:
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script> |
<script src=”http://code.jquery.com/jquery-latest.min.js” type=”text/javascript”></script>
И тут же след за этой строчкой, остаётся подключить сам исполняющий плагин, заблаговременно упакованный в отдельный файл и помещенный в папочку с js.
<script src="js/script.js"></script> |
<script src=”js/script.js”></script>
Хотите посмотреть на js в развёрнутом виде? Пожалуйста:
( function( $ ) { $( document ).ready(function() { $('#menu li.has-sub>a').on('click', function(){ $(this).removeAttr('href'); var element = $(this).parent('li'); if (element.hasClass('open')) { element.removeClass('open'); element.find('li').removeClass('open'); element.find('ul').slideUp(); } else { element.addClass('open'); element.children('ul').slideDown(); element.siblings('li').children('ul').slideUp(); element.siblings('li').removeClass('open'); element.siblings('li').find('li').removeClass('open'); element.siblings('li').find('ul').slideUp(); } }); $('#menu>ul>li.has-sub>a').append('<span class="holder"></span>'); (function getColor() { var r, g, b; var textColor = $('#menu').css('color'); textColor = textColor.slice(4); r = textColor.slice(0, textColor.indexOf(',')); textColor = textColor.slice(textColor.indexOf(' ') + 1); g = textColor.slice(0, textColor.indexOf(',')); textColor = textColor.slice(textColor.indexOf(' ') + 1); b = textColor.slice(0, textColor.indexOf(')')); var l = rgbToHsl(r, g, b); if (l > 0.7) { $('#menu>ul>li>a').css('text-shadow', '0 1px 1px rgba(0, 0, 0, .35)'); $('#menu>ul>li>a>span').css('border-color', 'rgba(0, 0, 0, .35)'); } else { $('#menu>ul>li>a').css('text-shadow', '0 1px 0 rgba(255, 255, 255, .35)'); $('#menu>ul>li>a>span').css('border-color', 'rgba(255, 255, 255, .35)'); } })(); function rgbToHsl(r, g, b) { r /= 255, g /= 255, b /= 255; var max = Math.max(r, g, b), min = Math.min(r, g, b); var h, s, l = (max + min) / 2; if(max == min){ h = s = 0; } else { var d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch(max){ case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return l; } }); |
( function( $ ) { $( document ).ready(function() { $(‘#menu li.has-sub>a’).on(‘click’, function(){ $(this).removeAttr(‘href’); var element = $(this).parent(‘li’); if (element.hasClass(‘open’)) { element.removeClass(‘open’); element.find(‘li’).removeClass(‘open’); element.find(‘ul’).slideUp(); } else { element.addClass(‘open’); element.children(‘ul’).slideDown(); element.siblings(‘li’).children(‘ul’).slideUp(); element.siblings(‘li’).removeClass(‘open’); element.siblings(‘li’).find(‘li’).removeClass(‘open’); element.siblings(‘li’).find(‘ul’).slideUp(); } }); $(‘#menu>ul>li.has-sub>a’).append(‘<span class=”holder”></span>’); (function getColor() { var r, g, b; var textColor = $(‘#menu’).css(‘color’); textColor = textColor.slice(4); r = textColor.slice(0, textColor.indexOf(‘,’)); textColor = textColor.slice(textColor.indexOf(‘ ‘) + 1); g = textColor.slice(0, textColor.indexOf(‘,’)); textColor = textColor.slice(textColor.indexOf(‘ ‘) + 1); b = textColor.slice(0, textColor.indexOf(‘)’)); var l = rgbToHsl(r, g, b); if (l > 0.7) { $(‘#menu>ul>li>a’).css(‘text-shadow’, ‘0 1px 1px rgba(0, 0, 0, .35)’); $(‘#menu>ul>li>a>span’).css(‘border-color’, ‘rgba(0, 0, 0, .35)’); } else { $(‘#menu>ul>li>a’).css(‘text-shadow’, ‘0 1px 0 rgba(255, 255, 255, .35)’); $(‘#menu>ul>li>a>span’).css(‘border-color’, ‘rgba(255, 255, 255, .35)’); } })(); function rgbToHsl(r, g, b) { r /= 255, g /= 255, b /= 255; var max = Math.max(r, g, b), min = Math.min(r, g, b); var h, s, l = (max + min) / 2; if(max == min){ h = s = 0; } else { var d = max – min; s = l > 0.5 ? d / (2 – max – min) : d / (max + min); switch(max){ case r: h = (g – b) / d + (g < b ? 6 : 0); break; case g: h = (b – r) / d + 2; break; case b: h = (r – g) / d + 4; break; } h /= 6; } return l; } });
Наличием большого количества настраиваемых параметров плагин не блещет, но всё то под что он заточен, выполняет исправно. При желании, вы сможете поэкспериментировать с некоторыми значениями, главное не переусердствовать. )))
Вот тетерь уж, точно всё. Компактное меню в стиле «аккордеон», полностью готово к работе. Это был всего лишь маленький пример того, какие горизонты и возможности открывают нам современные веб-инструменты. А в связке с неуёмной фантазией и огромным желанием, можно творить, творить и творить…
С уважением, Андрей.
Удачи! Буду очень благодарен, если поделитесь ссылкой на запись в своих соц. сетях:
При переходе на другую страницу сайта закрывается.
Как устранить.
Так не удобно работать.
Это лишь рабочий пример формирования меню с помощью jQuery и CSS3, чтобы при обновлении страницы открытый пункт меню оставался открытым подключите jQuery Cookie, если не знаете что это такое, воспользуйтесь готовым решениями
Большое спасибо за помощь.
К сожалению пока не получилось.
Меню мелькает в определенном ему месте и исчезает.
Может не поверите но мне 67 годиков и уже тяжеловато угнаться за новым, например с php пока трудновато.
Меню очень понравилось.
Понимаю что в этом случае Вы мне ничем не поможете но всеравно спасибо.
С уважением Оле,г Ковальчук.
Добился. Меню заработало но искажает шрифты на сайте.
Если можно подскажите как побороть.
если открыть пункт меню и закрыть, ссылка исчезает, как убрать это, подскажите пожалуйста
Добрый день!
Подскажите пожалуйста как сделать все пункты сразу раскрытыми?!