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

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

От автора: адаптивное меню для Retina с поддержкой сенсорного ввода и тремя разметками для разных размеров браузера.

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

скачать исходникидемо

Подготовка шрифта-иконки

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

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

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

При щелчке на “Download” мы получаем файл ZIP с 4 форматами шрифта (SVG, EOT, TTF и WOFF), стили CSS и демо-страницу.
Первое, что следует сделать для использования иконок – скопировать и вставить CSS, предоставляемый IcoMoon, в верх своего файла CSS и убедиться, что папка со шрифтом тоже скопирована. Вы, возможно, захотели бы узнать о маленьком хаке сделать шрифты в окнах Chrome еще симпатичнее.

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 для определения поддержки сенсорного ввода.

CSS и JavaScript

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

/* Глобальный 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);
}
 
/*Удалите голубой фон Webkit при касании элемента */
 
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 (50em при размере шрифта body в 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 с разными цветами. Мы применяем ее при проведении мышью, а также в фокусе и при активном состоянии, чтобы она работала на сенсорных устройствах и при работе с клавиатуры.

/* эффекты проведения мышью, фокусирования и активного состояния добавляют разным элементам небольшую цветную рамку */
 
.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, а ее цвет с прозрачного на какой-либо цвет с высокой непрозрачностью. Здесь же закрываем свой первый медиазапрос.

    /* Анимируйте тень блока box-shadow для создания эффекта */
    .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;
    }
         
}

Устанавливаем второй медиазапрос в соответствии с экранами размером от 800 до 980px:

@media (min-width: 50em) and (max-width: 61.250em) {
 
    /*Регулировка размера и шрифта до более подходящих */
    .nav ul {
        font-size: 1.2em;
    }
 
}

Теперь, когда мы закончили с версией для десктопов (под ОГРОМНЫМ вопросом, так как сегодня все больше «таблеток» имеют размеры экрана 1024px и более), позаботимся о глобальном CSS для экранов размером менее 800px, что равняется 49.938em, применив медиазапрос max-width.

/* Версия для «таблеток» и мобильных устройств */
 
@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) нам нужно отобразить свое меню в разметке из двух колонок и трех строк. Добавляем отступ, чтобы элементов можно было легко коснуться, и отображаем иконки слева, а текст справа.

/* CSS для версии с колонками */
 
@media (min-width: 32.5em) and (max-width: 49.938em) {
     
    /* Создаем разметку двух колонок, снова с помощью «плавающих» элементов */
    .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;
    }

Анимация, подходящая для больших экранов, слишком сложна для более мелких, поэтому сделаем ее проще и сдержаннее – просто анимируем рамку. Здесь мы закрываем свой медиазапрос.

    /* Более сдержанно адаптируем иконки к анимации размера и рамки закругленного фона */
    .nav li i {
        display: inline-block;
        padding: 8% 9%;
        border: 4px solid transparent;
        border-radius: 50%;
        font-size: 1.5em;
        background: rgba(255,255,255,0.1);
        transition: border .5s;
    }
 
    /*Эффект перехода цвета рамки */
    .no-touch .nav li:hover i,
    .no-touch .nav li:active i,
    .no-touch .nav li:focus i {
        border: 4px solid rgba(255,255,255,0.1);
    }
 
}

И снова адаптируем размер шрифта и ширину к более маленьким экранам.

/* Адаптируем размер шрифта и ширину для маленьких экранов*/
@media (min-width: 32.5em) and (max-width: 38.688em) {
     
    .nav li span.icon {
        width: 50%;
    }
 
    .nav li .icon + span {
        font-size: 0.9em;
    }
}

Для очень маленьких экранов мы скроем навигацию и отобразим кнопку “menu”, которую может щелкнуть пользователь, если захочет отобразить навигацию. Чтобы сделать это, доверимся нескольким строкам 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, чтобы открыть – назначаем max-height в 30em. При отключенном JavaScript’е у нас нет никакой кнопки, поэтому применим класс no-js, чтобы навигация отображалась всегда.

/* Анимация высоты навигации при щелчке на кнопку */
 
/* Если JavaScript отключен, меню остается открытым */
.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 слева от каждого элемента

/* Добавление слева рамки в 8 px с разными цветами для каждого элемента меню*/
.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);
}

Навигация красиво смотрится при тестировании ее маленькой версии на настольном компьютере. Но на мобильных устройствах может оказаться сложно дотронуться до элементов. С помощью Modernizr’а можно определить сенсорную производительность устройства. Если у устройства есть сенсорные возможности, в body добавляется класс touch. Его можно применять для улучшения впечатления от сенсорных устройств и небольшого увеличения элементов навигации, чтобы их было легче касаться. И тут мы закрываем свой последний медиазапрос.

/* сделайте nav больше на сенсорных экранах */
    .touch .nav a {
        padding: 0.8em;
    }
}

Вот и все, мы создали красивую, удобную для сенсорных и retina-устройств навигацию, отлично работающую как на десктопах, так и на «таблетках» и мобильных устройствах. Надеюсь, она вам понравилась!

Автор: Stephanie Walter

Источник: http://tympanus.net/

Редакция: Команда webformyself.

Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Получить

Метки:

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

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

Комментарии (4)

  1. Николай

    Здравствуйте, а у вас есть курс по адаптивной верстке? Ваш курс резиновая верстка он относится к адаптивной? или это совсем другое?

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree