Меню в окончательом виде

Адаптивное меню — немного FlexBox, немного JavaScript

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

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

Html-разметка

Начнем, как обычно, с того, что подготовим наш html-документ. Так как мы будем делать адаптивное меню, нам нужно будет добавить метатег Viewport для того, чтобы страница правильно масштабировалась на устройствах с разной шириной экрана.

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Подключаем файл стилей.
Кроме того, для этого меню мне хотелось воспользоваться шрифтом Open Sans, который можно подключить через Google Fonts.

<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">

Мы создаем меню с помощью тэга nav.

<nav class="top-nav">
<a class="nav-item" href="#">Главная</a>
<a class="nav-item" href="#">Услуги</a>
<a class="nav-item" href="#">Новости</a>
<a class="nav-item" href="#">Контакты</a></nav>

В меню мы вначале вставили ссылку, которая будет иконкой для открытия нашего меню на мобильных устройствах (class=»menu-icon»). Все необходимые детали мы пропишем ей чуть позже. И остальные ссылки — это пункты меню.
Дальше мы прописываем блок, который будет служить в качестве меню на небольших экранах. Это он будет открываться по щелчку на иконке, и будем называть мы его «боковое меню». На широких экранах его видно не будет.

<div id="side-menu" class="side-nav"><a class="close" href="#">×</a>
<a href="#">Главная</a>
<a href="#">Услуги</a>
<a href="#">Новости</a>
<a href="#">Контакты</a></div>

Как видно, мы вставили ссылку в виде крестика для закрытия этого бокового меню, и продублировали все пункты меню.

Добавляем действий

Теперь пришло время добавить немножечко JavaScript для того, чтобы наше меню спокойно открывалось и закрывалось.
Фокус будет состоять в том, что вначале боковое меню будет иметь ширину, равную 0, поэтому его видно не будет. А по щелчку на иконке меню оно будет становиться шириной 250px, т.е. будет видно во всей своей красе.
Поэтому, ссылке, которая будет иконкой, мы добавим событие — при нажатии вызвать функцию showSideMenu, а ссылке, которая будет закрывающим крестиком — при нажатии вызвать функцию hideSideMenu.

<a class="close" href="#">×</a>

А сами эти функции пропишем в скрипте. Мы не будем выносить его в отдельный файл, а укажем прямо здесь, внизу, перед закрывающим тэгом body.

<script>
        function showSideMenu() {
            document.getElementById('side-menu').style.width = '250px';
        }
        function hideSideMenu() {
            document.getElementById('side-menu').style.width = '0';
        }
</script>

Все очень просто. Для открытия бокового меню, мы изменяем его ширину с 0 (изначальное значение) на 250px, а для закрытия — ровно наоборот.

Оформляем стили в CSS

С html мы покончили. Еще ничего не работает как надо, потому что необходимо прописать стили в CSS. Сделаем это.
Для начала оформляем основное меню.

.top-nav {
background: #F08080;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}

Мы задаем ему цвет и размер. Кроме того, мы назначаем ему свойство display: flex для того, чтобы мы могли выравнивать в нем элементы с помощью модели flex. Свойство justify-content отвечает за то, как будут выровнены элементы в контейнере по горизонтали. Оно у нас принимает значение center, что значит, что мы выравниваем эти элементы по центру. Свойство align-items выравнивает элементы по вертикали, и ему мы тоже задаем значение center, чтобы они были выровнены по центру вертикально. И свойство overflow: hidden мы задаем для того, чтобы спрятать все ненужные выступы элементов за пределы меню, если они вдруг появятся.
Теперь займемся иконкой меню. Ее можно отобразить различными способами — через Font Awesome, нарисовать div-ами, нарисовать в svg. Но я решила просто вставить изображение в формате png. Вот оно.

.top-nav .menu-icon {
display: none;
width: 36px;
height: 24px;
padding: 0;
background: url('img/m-menu.png') center;
}

Мы задаем иконке ширину и высоту, чтобы она корректно отображалась, и прописываем путь до изображения. А самое главное, прописываем display: none для того, чтобы оно не показывалось до поры до времени.
Некоторые свойства у нас будут общие для пунктов основного меню и выплывающего — шрифты, размеры, и пр. Укажем их вместе.

.top-nav a, .side-nav a {
display: block;
font-family: 'Open Sans', sans-serif;
text-transform: uppercase;
text-decoration: none;
font-size: 20px;
}

Потом пропишем поля и цвет для пунктов основного меню.

.top-nav a {
color: #fff;
padding: 12px 18px;
}

При наведении на пункты основного меню, они у нас будут подсвечиваться. Чтобы это происходило плавно, укажем свойство transition.

.nav-item:hover {
background-color: #E2C7C7;
transition: .3s;
}

Теперь переходим к основному меню.

.side-nav {
height: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 1;
background: #FFFFFF;
width: 0;
overflow-x: hidden;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
transition: 0.5s;
}

Задаем ему высоту в 100%, чтобы оно было во всю высоту экрана. position: fixed отвечает за то, чтобы оно всегда было на своем месте, а именно в верхнем левом углу экрана (top: 0; left: 0;). z-index указываем для того, чтобы оно всегда было поверх всего остального. Добавляем фоновый цвет и тень. Делаем изначальную ширину 0, как и договаривались. overflow-x: hidden; указываем для того, чтобы содержимое нашего меню не вылазило, и не отображалось, когда у нас ширина равна 0. transition: 0.5s здесь для того, чтобы оно плавно выезжало и убиралось обратно.
Добавляем цвета и подсветки при наведении пунктам меню.

.side-nav a {
color: #F08080;
padding: 20px;
}
.side-nav a:hover {
color: #CE3A3A;
transition: .3s;
}

Оформляем крестик для закрытия.

.side-nav .close {
font-size: 40px;
padding: 0 10px 0 0;
text-align: right;
}

Добавляем еще немного адаптивности

Теперь нужно немного поколдовать над адаптивностью при изменении размеров экрана с помощью медиа-запросов.

@media screen and (max-width: 768px) {
.top-nav {
justify-content: flex-start;
}
.top-nav .menu-icon {
display: block;
margin-left: 15px;
}
.top-nav .nav-item {
display: none;
}
}

Эта запись означает, что если ширина нашего экрана будет меньше 768px, мы кое-что должны поменять. Мы открываем нашу спрятанную до поры иконку, а все остальные пункты меню, наоборот, прячем. И, поскольку я не хочу, чтобы иконка была посередине меню (а изначально мы, если помните, все в меню выравнивали по центру), то указываю justify-content: flex-start для того, чтобы она была у нас слева.
И самый последний момент: когда у нас открыто боковое меню, то при расширении экрана оно не убирается, хотя должно. Исправим это.

@media screen and (min-width: 768px) {
#side-menu {
    display: none;
    }
}

Теперь самый при ширине экрана 768px минимум (т.е. на экранах больше 768px), это меню вообще не будет присутствовать display:none.
Готово! 🙂 Как обычно, файлы с кодом можете скачать по ссылке.


Добавить комментарий