Настройка мобильного меню на сайте
Тема не новая, просто хочу вынести пример мобильного меню, который я использую чаще всего. На данный момент у каждого современного человека есть смартфон, с помощью которого из любой точки мира можно зайти на любой сайт и на данный момент (2021 год) каждый сайт должен быть адаптирован под мобильные телефоны, тем более, что сейчас в эпоху IoT даже холодильник и духовка Bosch имеют интерфейс для выхода в интернет.
Не забываем добавить параметры Viewport — это видимая пользователю область веб-страницы. Т.е. это то, что может увидеть пользователь, не прибегая к прокрутке.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Для примера будет взята самая простая и примитивная верстка для меню. Естественно, что вариантов для верстки хедера и меню множество и этот пример не является шаблоном для универсального меню. Данный макет нужен просто, чтобы понять логику и можно было применить ее в любой другой структуре.
HTML макет для меню
<header class="header" id="header">
<div class="wrap">
<a href="" class="logo">
LOGO
</a>
<ul class="main-menu" id="main-menu">
<li class="menu-item"><a href="">Home</a></li>
<li class="menu-item"><a href="">About</a></li>
<li class="menu-item"><a href="">Services</a></li>
<li class="menu-item"><a href="">Blog</a></li>
<li class="menu-item"><a href="">Contacts</a></li>
</ul>
<button class="btn-menu" id="btn-menu" type="button">
<span class="lines"></span>
<span class="lines"></span>
<span class="lines"></span>
</button>
</div>
</header>
Простой хедер, внутри контейнера находится Логотип и Меню, для мобильного меню добавлена кнопка btn-menu
.
Стили для данного меню (используется SCSS)
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background-color: #fff;
border-bottom: 1px solid #ccc;
z-index: 10;
.wrap {
position: relative;
max-width: 992px;
margin: 0 auto;
padding: 20px 15px;
display: flex;
align-items: center;
justify-content: space-between;
transition: 0.4s;
}
}
.main-menu {
display: flex;
align-items: center;
justify-content: flex-start;
.menu-item {
margin-right: 30px;
&:last-child {
margin-right: 0;
}
}
}
.btn-menu {
display: none;
}
Стили для красивой кнопки вызова мобильного меню.
Не обязательно делать такую кнопку, можно просто добавить иконку сендвича — будет чуть меньше кода, но вид будет примитивнее и проще. Кнопка .btn-menu
скрыта по умолчанию и отображается на определённой ширине экрана.
.btn-menu {
display: none;
position: relative;
width: 32px;
height: 22px;
background-color: transparent;
cursor: pointer;
border: none;
outline: none;
transition: 0.4s;
.lines {
display: block;
width: 32px;
height: 2px;
border-radius: 2px;
background-color: #000;
position: absolute;
transform: rotate(0deg);
transform-origin: 50% 50%;
transition: 0.25s ease-in-out;
will-change: transform;
&:nth-child(1) {
left: 0;
top: 0;
}
&:nth-child(2) {
left: 0;
top: 50%;
margin-top: -1px;
}
&:nth-child(3) {
left: 0;
bottom: 0;
}
}
&.active .lines {
left: 50%;
top: 50%;
margin-left: -16px;
margin-top: 0;
&:nth-child(1) {
transform: rotate(45deg);
}
&:nth-child(2) {
width: 0;
opacity: 0;
}
&:nth-child(3) {
transform: rotate(-45deg);
}
}
}
Стили для мобильного вида меню
Скрываем меню, отображаем кнопку мобильного меню и задаем новые стили для активного меню:
@media (max-width: 768px) {
.btn-menu {
display: block;
}
.main-menu {
display: none;
flex-direction: column;
justify-content: center;
align-items: center;
position: absolute;
top: 100%;
left: 0;
width: 100%;
padding: 20px 0;
background-color: #fff;
.menu-item {
text-align: center;
margin: 0;
margin-bottom: 25px;
&:last-child {
margin-bottom: 0;
}
}
}
.main-menu.active {
display: flex;
}
}
В случае, если отображение/скрытие меню активируется скриптом лучше подстраховаться, чтобы меню при изменении ширины экрана всегда отображалось на десктопе:
@media (min-width: 769px) {
.main-menu {
display: flex !important;
}
}
Разбор кода javaScript
Функция checkScrolledHeader()
нужна для того, чтобы кастомизировать внешний вид хедера при прокрутке, эта функция не обязательна, но она часто используется для дизайна при скроле.
(function checkScrolledHeader() {
var $header = $("#header");
$(window).scroll(checkScroll);
function checkScroll() {
if ($(window).scrollTop() > 1) {
$header.addClass("scrolled");
} else {
$header.removeClass("scrolled");
}
}
checkScroll();
})();
Функция initMobHeaderMenu()
нужна для отображения/скрытия мобильного меню. Там всё понятно. Нажатие на кнопку меняет классы хедеру, меню и кнопке, хотя можно обойтись и одним хедером, поскольку остальные элементы являются его дочерними. Но иногда нужно вынести мобильное меню из хедера, например, чтобы разместить в нем больше элементов (соцсети, поиск, логин/авторизация), поэтому для более широких возможностей повесим классы на нужные нам элементы.
(function initMobHeaderMenu() {
var $header = $("#header"),
$btnMenu = $("#btn-menu"),
$mainMenu = $("#main-menu");
$btnMenu.on("click touchend", function (e) {
$header.toggleClass("active");
$(this).toggleClass("active");
$mainMenu.toggleClass("active");
return false;
});
// Hide menu on scroll for Landing Page
$(window).scroll(deactivateHeader);
function deactivateHeader() {
$header.removeClass("active");
$btnMenu.removeClass("active");
$mainMenu.removeClass("active");
}
})();
Функция deactivateHeader()
нужна для скрытия открытого мобильного меню при скроле, это больше нужно для Landing Page — когда меню является навигацией по одной странице, чтобы при прокрутке к якорю меню скрывалось.
// Hide menu on scroll for Landing Page
$(window).scroll(deactivateHeader);
function deactivateHeader() {
$header.removeClass("active");
$btnMenu.removeClass("active");
$mainMenu.removeClass("active");
}
Полный код можно найти ниже в примере на Codepen.
Рабочий пример мобильного меню на Codepen
Чтобы увидеть как выглядит десктопная/мобильная версия меню — отключите отображение других вкладок кроме Результата:
See the Pen
Mobile Menu by Denis (@deniscreative)
on CodePen.dark
Полезный инструмент, чтобы быстро перевести много небольших текстов на разные языки с помощью Google Sheets…
Пример простого скрипта с добавление к числу случайного числа в выбранном диапазоне. Для чего это…
Задача такая, слева размещена картинка, а справа блок, внутри которого какой-то контент или другие блоки….
Задача — выводить в десктопной версии несколько слайдов с определенным дизайном, а в мобильной версии…