Адаптивное меню с логотипом. Подходы к реализации адаптивного меню. Не изменяя стандартам
Возвращаясь к теме всё возрастающей значимости мобильных устройств, невозможно обойти стороной меню сайта. По бо́льшей части для создания адаптивных меню используются решения на JavaScript, но всегда ли это оправдано? Пожалуй, нет. Ведь его можно сделать на чистом CSS, изменяя видимость элементов при помощи чекбокса.
Не будем долго разглагольствовать о плюсах и минусах данного подхода, а сразу обратимся к конкретному примеру. В данном случае это будет простое одноуровневное меню.
Что делать с многоуровневыми меню? Здесь есть несколько вариантов:
- начать смотреть решения на JavaScript/jQuery
- открывать второй уровень по наведению (что, надо сказать, не является хорошим решением)
Разметка будет чуть более многословной, чем нам это необходимо: здесь содержатся элементы, которые и вовсе могут не пригодиться. Однако, она довольно проста и разобраться в ней совсем несложно.
Pure CSS Menu
CSS MenuJust css and html
СтилиНа устройствах с экраном менее 640 пикселей пункты меню скрываются и остаётся только стилизованный через label чекбокс. Если чекбокс отмечен, меню становится видимым. Код для реализации:
/* Menu */ #menu-checkbox { /* чекбокс скрыт */ display : none ; } .main-menu { /* пункты меню скрыты */ display : none ; padding : 0 ; margin : 0 ; } .main-menu li { /* пункты меню расположены вертикально */ /* каждый имеет ширину 100% */ font-size : 1em ; display : block ; width : 100% ; } .main-menu a { /* немного стилизуем ссылки */ display : block ; border-bottom : 1px solid blueviolet ; color : lightslategray ; padding : .5em ; text-decoration : none ; } .main-menu a :hover { text-decoration : underline ; } .toggle-button { text-align : center ; display : block ; /* не забываем явно указать каким должен быть курсор */ cursor : pointer ; background-color : #333 ; color : #fff ; } .toggle-button :after { /* получаем данные из атрибута data-open в html */ content : attr (data-open ); display : block ; margin : 10px 0 ; padding : 10px 30px ; } #menu-checkbox :checked + nav [ role = "navigation" ] .main-menu { /* когда чекбокс активен меню становится видимым */ display : block ; } #menu-checkbox :checked + nav [ role = "navigation" ] .toggle-button :after { content : attr (data-close ); }
С мобильными устройствами разобрались. Осталось внести изменения для тех устройств, экран которых >= 640px. Делать это будем через медиа-запросы.
@media screen and (min-width : 640px ) { .toggle-button { /* label скрыт */ display : none ; } .main-menu { display : block ; margin : 0 auto ; background-color : #333 ; height : 30px ; } .main-menu li { /* теги
Посмотрим, что получилось:
Данный пример можно отыскать .
Стилизация меткиРазумеется, вместо data-open/close можно использовать что угодно. Например, добавить иконочный шрифт.
Toggle-button :after { font-family : "fontello" ; content : "\e804" ; cursor : pointer ; padding : 15px ; font-size : 1.5em ; text-align : center ; } #menu-checkbox :checked + .main-menu .toggle-button :after { content : "\e804" ; }
Или иконку с вместе с поясняющим текстом:
Здесь мы получаем значение атрибутов data-open/close , отображаем данные через before , а саму иконку добавляем с помощью псевдоэлемента after .
Toggle-button :before { content : attr (data-close ); font-size : 1rem ; position : relative ; right : 3px ; bottom : 3px ; } .toggle-button :after { content : "\f0c9" ; font-family : "FontAwesome" ; display : inline-block ; } #menu-checkbox :checked + nav [ role = "navigation" ] .menu { display : block ; } #menu-checkbox :checked + nav [ role = "navigation" ] .toggle-button :after { content : "\f0c9" ; font-family : "FontAwesome" ; color : green ; } #menu-checkbox :checked + nav [ role = "navigation" ] .toggle-button :before { color : green ; }
В последних двух примерах читателю нужно будет самостоятельно поиграть с позиционированием иконок и расположением самого текста.
Каких-то невероятных эффектов от подобной реализации меню ждать не приходится, хотя не сто́ит забывать о возможностях CSS-анимации.
Далеко не во всех проектах уместны излишние эффекты, которые могут значительно нагружать страницы, а особенно, если это касается адаптивной верстки, где пользователь может просматривать сайт на смартфонах или планшетах. Большинство таких эффектов, создаются с использованием JavaScript, поэтому, для примера, я решил показать, как можно сделать один из важнейших элементов сайта, а именно меню навигации , практически не прибегая к JS, а в основном только средствами CSS. Совсем нельзя отказаться от использования JS по той причине, что на мобильных устройствах и обычных компьютерах или ноутбуках, многие события отличаются и, если на компьютере в CSS мы можем спокойно использовать свойство :hover , то на планшете это уже не сработает так, как нам бы этого хотелось. Самые нетерпеливые, могут сразу (в примере изменяйте ширину окна браузера ).
Итак, ставим такую задачу: создать резиновое по ширине меню, с переключением на мобильную его версию, где меню будет выпадающим по наведению или нажатию на кнопку. Структура HTML типичная для таких элементов, за исключением того, что мы добавляем еще один элемент - кнопку для раскрытия/скрытия меню в мобильной версии:
≡
CSS не совсем стандартный. Мы сделаем так, что наше меню будет вести себя так, как если бы мы использовали таблицу. Сразу хочу акцентировать внимание на том, что не все браузеры поддерживаю те свойства, которые мы будем использовать. Проблемы могут возникнуть с версиями IE ниже восьмой версии (хотя на них уже пора переставать ориентироваться ) и в пару моментах есть маленькие сложности с IE8, но как решить их - напишу ниже.
* { margin: 0; padding: 0; } header { background-color: #C0C0C0; } #menu { display: table; /* описание ниже */ width: 100%; border-collapse: collapse; -webkit-box-sizing: border-box; /* описание ниже */ -moz-box-sizing: border-box; /* описание ниже */ box-sizing: border-box; /* описание ниже */ } #menu ul { display: table-row; /* описание ниже */ background-color: #FFFFFF; list-style: none; } #menu ul li { display: table-cell; /* описание ниже */ border: 1px solid #999999; } #menu ul li a { display: inline-block; width: 100%; height: 50px; line-height: 50px; font-size: 1.2em; text-align: center; } #menu ul li a:hover { background-color: #990000; color: #FFFFFF; } #nav_button { display: none; width: 50px; height: 50px; font-size: 2.5em; text-align: center; background-color: #FFFFFF; border: 1px solid #949494; cursor: pointer; } @media screen and (max-width: 600px) { /* описание ниже */ #menu { display: inline-block; position: relative; width: auto; } #menu ul { display: none; position: absolute; top: 0; width: 100%; z-index: 20; } #menu ul li { display: list-item; border-top: none; } #nav_button { display: inline-block; } #menu:hover, #menu.open_nav { width: 100%; -webkit-user-select: none; /* описание ниже */ -moz-user-select: none; /* описание ниже */ -webkit-touch-callout: none; /* описание ниже */ } #menu:hover ul, #menu.open_nav ul { display: block; margin-top: 50px; } }
На некоторые стили обращать внимание не нужно; цвет бекграунда, размер шрифта и т.д. - это только для демонстрации. А нас должны интересовать следующие свойства с их значениями:
Display: table; Указывает, что элемент будет себя вести аналогично элементу
или
box-sizing: border-box; (и с вендорными префиксами)
При расчетах ширины и высоты элемента, свойства width и height, будут включать в себя значения полей (padding
) и границ (border
). Нужно для того, чтоб избежать появления горизонтальной прокрутки, т.к. без этого свойства, при ширине меню в 100%, добавится еще и толщина border
, а если есть, то и padding
.
-webkit-user-select: none; и -moz-user-select: none;
Запрещает выделять элемент или текст. Нужно для мобильной версии, чтоб избежать неувязок, когда пользователь проводит по элементам меню, вместо того, чтобы нажать на него.
-webkit-touch-callout: none;
Отменяет всплытие подсказки при нажатии и удержании элемента. Работает только в Chrome и Safari. Так же, как и в предыдущем свойстве, служит для отмены нежелательных действий при работе с элементом.
@media (медиа-запрос)
Тема довольно обширная, но если в двух словах, то указывает браузеру, какие свойства применять для определенных типов носителей или технических характеристик устройства. В нашем случае - применять для screen
(экранов мониторов) и max-width: 600px
(если ширина окна браузера меньше 600px).
Самое интересное, что на этом можно было бы поставить точку, если бы мы не учитывали смартфоны, планшеты и с уверенностью сказать, что меню сделано полностью на HTML и CSS. Но придётся прибегнуть к помощи JS/jQuery, а в данном случае, раз уж решено было сделать с наименьшей нагрузкой, именно к чистому JavaScript. Var d = document, navBut = d.getElementById("nav_button"), // кнопка включение меню navMenu = d.getElementById("menu"); // выпадающее меню // функция определения наличия родительского элемента по ID function hasParent(el, sId){ while(el) { if (el.id == sId) return true; el = el.parentNode; } return false; } // по касанию на кнопке, добавляем класс менюшке, // который соответствует свойству в css "#menu:hover" // и разворачиваем меню navBut.addEventListener("touchstart", function(e) { e.preventDefault(); navMenu.classList.add("open_nav"); }, false); // по касанию в документе, // если событие не было на каком-нибудь элементе меню (определяем с помощью функции "hasParent"), // убираем класс "open_nav" из меню, что привод к его закрытию d.addEventListener("touchstart", function(e) { if(!hasParent(e.target, "menu")) navMenu.classList.remove("open_nav"); }, false); Записываем этот код в отдельный js-файл и подключаем его в самом низу страницы, перед закрывающим тегом . Теперь пару слов о кроссбраузерности... Если вы рассчитываете на Internet Explorer ниже девятой версии, то для корректной работы, нужно подключить два фиксящих скрипта внутри тега : Первый позволяет старым браузерам адекватно воспринимать теги HTML5, а второй - "медиа-запросы", с которыми они так же не дружат. Хотя, с другой стороны, такие браузеры не используются на мобильных устройствах, а тот же тег можно заменить на . Поэтому использовать эти скрипты или нет - дело, конечно же, ваше личное, но я их считаю избыточными. Вот теперь меню готово к использованию на любых устройствах. Очень часто, особенно новички, в погоне за мнимой красочностью сайта, переполняют его лишней графикой, скриптами, которые выполняя какое-то маленькое действие, весят порой больше чем вся страница. Не впадайте в крайности и задумывайтесь о тех пользователях, которые могут заходить к вам не только с разных устройств, но еще и по низкоскоростному интернет-соединению. Успехов! ;) Предлагаю на рассмотрение, технику создания простого, очень гибкого в настройках, и к тому же достаточно эффективного, адаптивного меню, с использованием чистой семантической разметки, для реализации адаптивной конструкции, без подключения javascript. В результате с помощью CSS мы получим меню, которое может быть выравнено влево, вправо или располагаться точно по центру, выделяемые активные/текущие пункты, меню способное при изменении размера окна браузера, быстро перестраиваться в раскрывающуюся, вертикальную навигационную панель, которая замечательно смотрится на экранах различных мобильных пользовательских устройств(планшеты, смартфоны, ноутбуки и мобильные телефоны). Пример посмотрели и убедились в работоспособности нашего меню. Такой способ, в целом очень полезен, когда в меню используется большое количество ссылок. В с легкостью сможете сгрупировать все кнопки в одну, раскрывающуюся при наведении, привлекательную панель. Перво-наперво нам необходимо выполнить разметку всей основной конструкции нашего меню. Мы создаем элемент навигации, а значит логичным и даже практичным, будет применение HTML5-элемента, тега с присвоенным ему одноименным классом, для последующего форматирования CSS стилей, а также создания и абсолютного позиционирования выпадающей навигационной панели. Класс current указывает на активную / текущую ссылку меню, внешний вид которой, сформируем с помощью css.
Как видим, меню, это простой неупорядоченный список с определенным количеством ссылок. Количество пунктов может быть разным, но всё же не стоит городить огород, всё в разумных пределах.
Всё. С основной разметкой мы разобрались, классы прописаны, костыли добавлены. Теперь перейдем к определению стилей пунктов меню, сформируем внешний вид и с делаем наше меню по-настоящему адаптивным. Набор стилей CSS меню под экраны мониторов настольных компьютеров, довольно стандартный, вдаваться в подробности не вижу смысла. Хочу лишь обратить внимание, на то что я указал display:inline-block вместо float:left элемента
/* меню */ .nav { margin: 20px 0; } .nav ul { margin: 0; padding: 0; } .nav li { margin: 0 5px 10px 0; padding: 0; list-style: none; display: inline-block; *display:inline; /* ie7 */ } .nav a { padding: 3px 12px; text-decoration: none; color: #999; line-height: 100%; } .nav a:hover { color: #000; } .nav .current a { background: #999; color: #fff; border-radius: 3px; } За изменения цвета ссылок и фона активных/текущих пунктов меню отвечают секции.nav a:hover и.nav .current a соответственно. Я не стал особо мудрить в этом примере, всё сделал в духе минимализма, при наведении на ссылку меняется цвет, текст становится черным color: #000; , а для активных пунктов добавил фон background: #999; , заменил цвет шрифта на белый color: #fff; и чуточку закруглил края border-radius: 3px; у получившейся кнопки. Вы же можете фантазировать и экспериментировать в этом плане, сколь душе угодно. Выравнивание по центру и вправоКак я уже упоминал выше, мы можем изменять выравнивание пунктов навигации с помощью свойства text-align , для этого добавим в код CSS несколько строк:
/* меню справа */ .nav.right ul { text-align: right; } /* меню по центру */ .nav.center ul { text-align: center; } Адаптируем менюНачинается самое интересное. Наше меню на данном этапе имеет резиновый формат(ширина определяется в процентах) и пока совсем не адаптивное. Начните изменять размер экрана и вы увидите, что меню выстраивается в хаотичное нагромождение кнопок. Будем исправлять ситуацию с помощью медиа запросов. В точке приложения медиа запроса в 600px, выставил относительное позиционирование position: relative; для элемента nav , чтобы мы смогли потом разместить список меню
При наведении на сгруппированную панель навигации все пункты меню должны показываться в виде выпадающего списка, для этого определяем правило.nav ul:hover li с функцией code>display: block . Для активных/текущих пунктов добавляем иконку, чтобы выделить из из остальных. Если необходимо сместить меню вправо или расположить по центру, воспользуйтесь left и right свойствами позиционирования для списка ul нашего меню.
@media screen and (max-width: 600px) { .nav { position: relative; min-height: 40px; } .nav ul { width: 180px; padding: 5px 0; position: absolute; top: 0; left: 0; border: solid 1px #aaa; background: #FAFAFA url(images/icon-menu.png) no-repeat 10px 11px; border-radius: 5px; box-shadow: 0 1px 2px rgba(0,0,0,.3); } .nav li { display: none; /* скрыть все Естественно, на всех сайтах есть свои строки меню, но если ресурс создан на CMS, то намного проще будет создать новое адаптивное меню. BootstrapСоздание адаптивного функционала не является такой серьезной проблемой, если воспользоваться инструментами Bootstrap. Здесь уже заранее заложены шаблоны для создания горизонтального меню. Нужно лишь подключиться к ресурсу файл bootstrap.js. С помощью этого фреймворка веб-мастер получает возможность создавать навигацию любой сложности. Адаптивное меню с Bootstrap создается при помощи определенного кода. Особенности методаПусть этот код и громоздкий, зато понятный. Стоит обратить внимание, что основную роль здесь играет тег nav , что отвечает за создание навигации и ее внешний вид. Также сюда подключены контейнеры container-fluid и container , которые задают ширину пунктов. С их помощью можно заставить меню расширяться на экранах разного разрешения или оставить его фиксированным. Немаловажную роль в создании адаптивного функционала здесь играют классы collapse и navbar-collapse , которые отвечают за стиль. Само меню создается путем записывания пунктов, что размещены горизонтально. Если применить для создания навигации этот код фреймовки, то на широких экранах она будет выглядеть как горизонтальный баннер. В начале будет находиться название ресурса, а затем пункты в строго заданной последовательности. На узких экранах будет отображаться только название сайта и значок гамбургер, при нажатии на который позиции меню отображаются в виде вертикального списка. Выпадающее менюРесурс Bootstrap станет отличным помощником для создания адаптивного выпадающего меню. Для этого достаточно просто заменить строку тега |