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

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

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

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

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


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


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

Первое что нам нужно сделать, чтобы иметь возможность использовать иконки, это скопировать и вставить CSS-код, который IcoMoon предоставляет нам в самом верху CSS-файла, и убедиться в том, что мы также скопировали папку шрифтов. Существует небольшой «хак», который позволяет улучшить внешний вид шрифтов в Chrome Windows.

HTML-код для меню

Вот так будет выглядеть HTML-код для нашего навигационного меню:

Код
<nav id="menu" class="nav">  
  <ul>
  <li>
  <a href="#" title="">
  <span class="icon"> <i aria-hidden="true" class="icon-home"></i></span><span>Home</span>
  </a>
  </li>
  <li>  
  <a href="#" title=""><span class="icon"> <i aria-hidden="true" class="icon-services"></i></span><span>Services</span></a>  
  </li>  
  <li>
  <a href="#" title=""><span class="icon"><i aria-hidden="true" class="icon-portfolio"></i></span><span>Portfolio</span></a>
  </li>
  <li>
  <a href="#" title=""><span class="icon"><i aria-hidden="true" class="icon-blog"></i></span><span>Blog</span></a>  
  </li>
  <li>
  <a href="#" title=""><span class="icon"><i aria-hidden="true" class="icon-team"></i></span><span>The team</span></a>  
  </li>
  <li>
  <a href="#" title=""><span class="icon"><i aria-hidden="true" class="icon-contact"></i></span><span>Contact</span></a>
  </li>
  </ul>
</nav>

Чтобы использовать иконический шрифт, мы просто используем класс icon-iconname внутри элемента i (span-элемент также подойдет). Также обратите внимание на то, что мы добавили класс no-js к телу, который будет изменяться на js при помощи Modernizr. Суть заключается в том, чтобы иметь возможность оставить меню включенным на случай, если у пользователя будет отключена поддержка javascript. Мы также воспользуемся Modernizr, чтобы определить, имеется ли поддержка Touch.

CSS и javascript-коды

Обратите внимание, что здесь, в кодах, мы не указывали браузерные префиксы, но вы можете видеть их в исходных файлах.

Общий 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{
  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);
}

Используя media query min-width, мы можем определять экраны, размер которых больше 800 пикселей (50em, при значении font size равным 15px), чтобы преобразовать наш список в привлекательное горизонтальное меню:

Код
@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, а также изменяем цвет с прозрачности до цвета с высоким уровнем непрозрачности. Здесь мы завершаем наш первый этап media-query.

Код
.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) {
   
  /* Size and font adjustments to make it fit better */
  .nav ul {
  font-size: 1.2em;
  }
   
}

Теперь, когда мы разобрались с версией для «настольных» ПК (в больших-больших кавычках, так как сегодня все больше и больше планшетных ПК предоставляют разрешении более 1024 пикселей), давайте при помощи 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;
  }  
   
}

Опять же, для маленьких экранов мы изменяем значения 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;
  }
}

Для очень маленьких экранов мы скрываем навигацию и отображаем кнопку «меню», кликнув по которой, пользователь может увидеть меню. Чтобы сделать это, нам потребуется несколько строк кода javascript:

Код

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 type="button" id="menutoggle" class="navtoogle" aria-hidden="true"><i aria-hidden="true" class="icon-menu"> </i> Menu</button>');

document.getElementById('menutoggle').onclick = function() {
  changeClass(this, 'navtoogle active', 'navtoogle');
}

Чтобы наш HTML-код был более опрятным, мы решили создать кнопку menu и вставить ее в DOM при помощи javascript. Функция changeClass поможет нам переключиться между классами active и no, когда пользователь кликает по кнопке.

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

Код
.nav .navtoogle{
  display: none;  
  width: 100%;
  padding: 0.5em 0.5em 0.8em;
  font-family: 'Lato',Calibri,Arial,sans-serif;
  font-weight: normal;
  text-align: left;
  color: rgb(7, 16, 15);
  font-size: 1.2em;
  background: none;  
  border: none;
  border-bottom: 4px solid rgb(221, 221, 221);
  cursor: pointer;
}
   
.icon-menu {
  position: relative;
  top: 3px;
  line-height: 0;
  font-size: 1.6em;
}

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

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

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

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

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

Код
.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. Мы можем использовать данный класс для улучшения опыта взаимодействия с пользователями сенсорных устройств, и для того, чтобы сделать пункты навигации слегка больше, чтобы исключить возникшую проблему. И на этом мы закрываем наш последний media query.

Код
 .touch .nav a {
  padding: 0.8em;
  }
}

И на этом все! Мы создали вполне привлекательное адаптивное меню с поддержкой Retina и сенсорных устройств, которое будет отлично смотреться и работать как на настольных ПК, так и мобильных устройствах с маленькими экранами! Надеемся, вам понравилось!

  • FalleN

  • 6308

  • 1

  • 296

Ссылки на статью:

Похожие статьи:

Комментарии:

VLADBOLD
FalleN, Скрипт сильно сайт подгружает?
Аватар пользователя FalleN
FalleN
VLADBOLD, как тебе ответить на этот вопрос?? Все же расписано.. Просто по инструкции вставляй туда где тебе нужно... Тут нет никакой привязки к CMS
VLADBOLD
Как его ставить на ucoz?
NiyazovDS
Весь  css-код скопировать в стили сайта и в нужное место вставить код меню. Все просто.