Адаптивное меню для экранов Retina Адаптивное меню для экранов Retina



 

В данном уроке мы рассмотрим процесс создания адаптивного меню которое подходит для экранов Retina, меню было разработано под вдохновением цветовой гаммы создателей игры Borderlands, компании Maliwan. Меню автоматически преобразуется в необходимый размер при определенном разрешении экрана, Чтобы меню отлично подходило под экраны retina, мы воспользуемся иконическим шрифтом, чтобы иконки меню не теряли качества при масштабировании. и так, давайте посмотрим, что у нас с этого получилось.

 

ДЕМО
ИСХОДНИКИ

 

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

Подготавливаем иконический шрифт

Для начала нам необходимо создать иконки для меню. Я буду использовать Illustrator, но вы можете работать с любым графическим редактором вроде Inkscape. Нам нужно создать каждую иконку отдельно и экспортировать их в SVG-файл. Чтобы убедиться в том, что иконка будет работать корректно во всех браузерах, нам нужно конвертировать все линии в полноценные объекты, и затем соединить объекты в одну большую фигуру для каждой иконки. Как только мы закончили экспорт в SVG-файлы, мы можем импортировать их в инструмент IcoMoon App:

Мы также можем расширить наш шрифт иконками из большой библиотеки, которую предлагает IcoMoon. Как только у нас в распоряжении окажутся все необходимые иконки, мы нажимаем кнопку Font в самом низу страницы, чтобы перейти к подробным настройкам.

Когда мы нажимаем Download, мы получаем zip-файл с 4 шрифтами в разных форматах (SVG, EOT, TTF и WOFF), css-стили и демо-страницу. C иконками мы разобрались, переходим к следующему шагу.

Шаг 1. HTML

Для начала нам необходимо построить достаточно простую разметку:

<nav id="menu" class="nav">
 <ul>
 <li>
 <a href="#">
 <span class="icon">
 <i aria-hidden="true" class="icon-home"></i>
 </span>
 <span>Главная</span>
 </a>
 </li>
 <li>
 <a href="#">
 <span class="icon">
 <i aria-hidden="true" class="icon-services"></i>
 </span>
 <span>Сервис</span>
 </a>
 </li>
 <li>
 <a href="#">
 <span class="icon">
 <i aria-hidden="true" class="icon-portfolio"></i>
 </span>
 <span>портфолио</span>
 </a>
 </li>
 <li>
 <a href="#">
 <span class="icon">
 <i aria-hidden="true" class="icon-blog"></i>
 </span>
 <span>Блог</span>
 </a>
 </li>
 <li>
 <a href="#">
 <span class="icon">
 <i aria-hidden="true" class="icon-team"></i>
 </span>
 <span>Команда</span>
 </a>
 </li>
 <li>
 <a href="#">
 <span class="icon">
 <i aria-hidden="true" class="icon-contact"></i>
 </span>
 <span>Контакты</span>
 </a>
 </li>
 </ul>
 </nav>

Чтобы использовать иконки, мы просто добавляем класс "icon-iconname" к нужному элементу. Также отметьте, что мы не стали добавлять класс no-js, который используется с библиотекой Modernizr.

Шаг 2. CSS

Первым, что мы должны сделать это определить базовые параметры для всех экранов:

.nav ul {
 max-width: 1240px;
 margin: 0;
 padding: 0;
 list-style: none;
 font-size: 1.5em;
 font-weight: 300;
}
.nav li span {
 display: block;
}
.nav a {
 display: block;
 color: rgba(249, 249, 249, .9);
 text-decoration: none;
 transition: color .5s, background .5s, height .5s;
}
.nav i{
 /* гладкий шрифт для Chrome */
 transform: translate3d(0, 0, 0);
}
a, button {
 -webkit-tap-highlight-color: rgba(0,0,0,0);
}

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

.no-touch .nav ul:hover a {
 color: rgba(249, 249, 249, .5);
}
.no-touch .nav ul:hover a:hover {
 color: rgba(249, 249, 249, 0.99);
}

Затем нам нужно добавить цвет фона для каждого элемента. Приведенный ниже код использует технику nth-child для выбора элементов списка.

.nav li:nth-child(6n+1) {
 background: rgb(208, 101, 3);
}
.nav li:nth-child(6n+2) {
 background: rgb(233, 147, 26);
}
.nav li:nth-child(6n+3) {
 background: rgb(22, 145, 190);
}
.nav li:nth-child(6n+4) {
 background: rgb(22, 107, 162);
}
.nav li:nth-child(6n+5) {
 background: rgb(27, 54, 71);
}
.nav li:nth-child(6n+6) {
 background: rgb(21, 40, 54);
}

Нам необходимо использовать медиа-запросы min-width,  при этом можно будет ориентироваться на экранах, которые больше чем 800px, для преобразования нашего списка в горизонтальную навигацию:

@media (min-width: 50em) {
 .nav li {
 float: left;
 width: 16.66666666666667%;
 text-align: center;
 transition: border .5s;
 }
 .nav a {
 display: block;
 width: auto;
 }

Мы продолжаем использовать технику отбора nth-child, чтобы добавить границу толщиной 4px с разными цветами для каждого пункта меню. Мы применяем этот эффект при наведении курсора, но и также для активных вкладок, чтобы он работал на touch-устройствах и при управлении посредством клавиатуры.

.no-touch .nav li:nth-child(6n+1) a:hover,
.no-touch .nav li:nth-child(6n+1) a:active,
.no-touch .nav li:nth-child(6n+1) a:focus {
 border-bottom: 4px solid rgb(174, 78, 1);
}
.no-touch .nav li:nth-child(6n+2) a:hover,
.no-touch .nav li:nth-child(6n+2) a:active,
.no-touch .nav li:nth-child(6n+2) a:focus {
 border-bottom: 4px solid rgb(191, 117, 20);
}
.no-touch .nav li:nth-child(6n+3) a:hover,
.no-touch .nav li:nth-child(6n+3) a:active,
.no-touch .nav li:nth-child(6n+3) a:focus {
 border-bottom: 4px solid rgb(12, 110, 149);
}
.no-touch .nav li:nth-child(6n+4) a:hover,
.no-touch .nav li:nth-child(6n+4) a:active,
.no-touch .nav li:nth-child(6n+4) a:focus {
 border-bottom: 4px solid rgb(10, 75, 117);
}
.no-touch .nav li:nth-child(6n+5) a:hover,
.no-touch .nav li:nth-child(6n+5) a:active,
.no-touch .nav li:nth-child(6n+5) a:focus {
 border-bottom: 4px solid rgb(16, 34, 44);
}
.no-touch .nav li:nth-child(6n+6) a:hover,
.no-touch .nav li:nth-child(6n+6) a:active,
.no-touch .nav li:nth-child(6n+6) a:focus {
 border-bottom: 4px solid rgb(9, 18, 25);
}

Затем мы помещаем иконки и текст:

.icon {
 padding-top: 1.4em;
}
.icon + span {
 margin-top: 2.1em;
 transition: margin .5s;
}

Анимируем высоту элементов при наведении мышью:

.nav a {
 height: 9em;
}
.no-touch .nav a:hover ,
.no-touch .nav a:active ,
.no-touch .nav a:focus {
 height: 10em;
}
.no-touch .nav a:hover .icon + span {
 margin-top: 3.2em;
 transition: margin .5s;
}

Затем мы помещаем иконки и подготавливаем их к css-переходу:

.nav i {
 position: relative;
 display: inline-block;
 margin: 0 auto;
 padding: 0.4em;
 border-radius: 50%;
 font-size: 1.8em;
 box-shadow: 0 0 0 0.8em transparent;
 background: rgba(255,255,255,0.1);
 transform: translate3d(0, 0, 0);
 transition: box-shadow .6s ease-in-out;
}

Чтобы добавить визуальный эффект, мы добавим переход для тени и изменим его размер с 0.8em до 0, а его цвет от прозрачного до цвета с высокой непрозрачностью.

.no-touch .nav a:hover i,
 .no-touch .nav a:active i,
 .no-touch .nav a:focus i {
 box-shadow: 0 0 0px 0px rgba(255,255,255,0.2);
 transition: box-shadow .4s ease-in-out;
 }
}

Мы также настроим второй media query, чтобы обеспечить нормальное отображение на экранах от 800 до 980px:

@media (min-width: 50em) and (max-width: 61.250em) {
 .nav ul {
 font-size: 1.2em;
 }
}

Давайте при помощи media query max-width позаботимся о «глобальном» CSS для экранов размером меньше 800 пикселей, что здесь равняется 49.938em.

@media (max-width: 49.938em) {
 .no-touch .nav ul li:nth-child(6n+1) a:hover,
 .no-touch .nav ul li:nth-child(6n+1) a:active,
 .no-touch .nav ul li:nth-child(6n+1) a:focus {
 background: rgb(227, 119, 20);
 }
 .no-touch .nav li:nth-child(6n+2) a:hover,
 .no-touch .nav li:nth-child(6n+2) a:active,
 .no-touch .nav li:nth-child(6n+2) a:focus {
 background: rgb(245, 160, 41);
 }
 .no-touch .nav li:nth-child(6n+3) a:hover,
 .no-touch .nav li:nth-child(6n+3) a:active,
 .no-touch .nav li:nth-child(6n+3) a:focus {
 background: rgb(44, 168, 219);
 }
 .no-touch .nav li:nth-child(6n+4) a:hover,
 .no-touch .nav li:nth-child(6n+4) a:active,
 .no-touch .nav li:nth-child(6n+4) a:focus {
 background: rgb(31, 120, 176);
 }
 .no-touch .nav li:nth-child(6n+5) a:hover,
 .no-touch .nav li:nth-child(6n+5) a:active,
 .no-touch .nav li:nth-child(6n+5) a:focus {
 background: rgb(39, 70, 90);
 }
 .no-touch .nav li:nth-child(6n+6) a:hover,
 .no-touch .nav li:nth-child(6n+6) a:active,
 .no-touch .nav li:nth-child(6n+6) a:focus {
 background: rgb(32, 54, 68);
 }
 .nav ul li {
 transition: background 0.5s;
 }
}

Для размера экрана от 520px (32.5em) и 799px (49.938em), мы разделим на экране наше меню в 2 столбца и 3 строки. Добавляем небольшие отступы, и выведем иконки слева и текст справа.

@media (min-width: 32.5em) and (max-width: 49.938em) {
 /* Cоздаем две колоноки используя плавающий элемент */
 .nav li {
 display: block;
 float: left;
 width: 50%;
 }
 /* Добавление отступов */
 .nav a {
 padding: 0.8em;
 }
 /* Отображение иконок слева, используя inline-block */
 .nav li span,
 .nav li span.icon {
 display: inline-block;
 }
 .nav li span.icon {
 width: 50%;
 }
 .nav li .icon + span {
 font-size: 1em;
 }
 .icon + span {
 position: relative;
 top: -0.2em;
 }

Опять же, для маленьких экранов мы изменяем значения font-size и width.

@media (min-width: 32.5em) and (max-width: 38.688em) {
 .nav li span.icon {
 width: 50%;
 }
 .nav li .icon + span {
 font-size: 0.9em;
 }
}

По умолчанию кнопка меню скрыта. Мы хотим использовать её на небольших экранах, меньше, чем 519px (32.438em):

@media (max-width: 32.438em) {
 .nav .navtoogle{
 margin: 0;
 display: block;
 }

Если javascript отключен, у нас не будет никакой кнопки, мы просто воспользуемся классом no-js, чтобы навигация отображалась постоянно.

.no-js .nav ul {
 max-height: 30em;
 overflow: hidden;
}

Когда поддержка javascript включена, мы по умолчанию скрываем меню, и отображаем его тогда, когда пользователь нажимает на кнопку, которая затем получает класс active:

/* Скрываем меню при включенном JavaScript */
.js .nav ul {
 max-height: 0em;
 overflow: hidden;
}
/* Отображение меню при щелчке по кнопке */
.js .nav .active + ul {
 max-height: 30em;
 overflow: hidden;
 transition: max-height .4s;
}

На небольших экранах, отображаем навигацию в списке элементов со значком с левой стороны и текстом справа:

.nav li span {
 display: inline-block;
 height: 100%;
}
.nav a {
 padding: 0.5em;
}
.icon + span {
 margin-left: 1em;
 font-size: 0.8em;
}

Мы также добавили границу толщиной 8Px с левой стороны для каждого пункта меню, чтобы вид стал более привлекательным:

.nav li:nth-child(6n+1) {
 border-left: 8px solid rgb(174, 78, 1);
}
.nav li:nth-child(6n+2) {
 border-left: 8px solid rgb(191, 117, 20);
}
.nav li:nth-child(6n+3) {
 border-left: 8px solid rgb(13, 111, 150);
}
.nav li:nth-child(6n+4) {
 border-left: 8px solid rgb(10, 75, 117);
}
.nav li:nth-child(6n+5) {
 border-left: 8px solid rgb(16, 34, 44);
}
.nav li:nth-child(6n+6) {
 border-left: 8px solid rgb(9, 18, 25);
}

Если у устройства предусмотрена поддержка touch, то к телу документа добавляется класс touch. Мы можем использовать данный класс для улучшения опыта взаимодействия с пользователями сенсорных устройств:

.touch .nav a {
 padding: 0.8em;
 }
}

Шаг 3. JS

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

var changeClass = function (r,className1,className2) {
 var regex = new RegExp("(?:^|\\s+)" + className1 + "(?:\\s+|$)");
 if( regex.test(r.className) ) {
 r.className = r.className.replace(regex,' '+className2+' ');
 }
 else{
 r.className = r.className.replace(new RegExp("(?:^|\\s+)" + className2 + "(?:\\s+|$)"),' '+className1+' ');
 }
 return r.className;
};

// Создание кнопки меню
var menuElements = document.getElementById('menu');
menuElements.insertAdjacentHTML('afterBegin','<button id="menutoggle" class="navtoogle" type="button"><em class="icon-menu"> </em> Menu</button>');

// Добавление класса для кнопки
document.getElementById('menutoggle').onclick = function() {
 changeClass(this, 'navtoogle active', 'navtoogle');
}

Вот и все. Готово!

Материал взят из зарубежного источника tympanus.net/codrops/2013/05/08/responsive-retina-ready-menu и представлен исключительно в ознакомительных целях.


Top

🔖 Выбор по тегам ×

💌 Написать сообщение ×

Все поля обязательны для заполнения!