Создаем адаптивное меню для сайта

      CSS

Здравствуйте, уважаемые читатели XoZbloga! Порой, одной из самых сложных частей при создании сайта является, проектирование и реализация навигации. Много времени уходит на выдумывание структуры и дизайна, последующую верстку меню и создание эффектов. Так же не мало важным является кроссбраузерность и возрастающая адаптивность к мобильным устройствам. Так вот, в этом уроке попытаемся, и создадим простенькое адаптивное меню для сайта. Использовать будем CSS3 медиа запросы и немного jQuery. Итак, давайте приступим.

Адаптивное меню

HTML разметка

Для начала давайте добавим мета тег viewport внутри тега head. Он поможет браузерам отображать страницу в должном масштабе, на любом устройстве в особенности на мобильном.

1
2
3
4
5
<head>
...
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
...
</head>

В качестве параметров для содержимого страницы, здесь задается максимально возможная ширина для устройства width=device-width, коэффициент масштабирования initial-scale=1 при загрузке и максимальный коэффициент масштабирования.

Теперь структура меню. Меню основано на маркированном списке ul.

1
2
3
4
5
6
7
8
9
10
11
<nav class="clearfix">
      <ul class="clearfix">
         <li><a href="#">Главная</a></li>
         <li><a href="#">Новости</a></li>
         <li><a href="#">Статьи</a></li>
         <li><a href="#">Инфо</a></li>
         <li><a href="#">Скачать</a></li>
         <li><a href="#">Контакты</a></li>
      </ul>
      <a href="#" id="pull">Меню</a>
</nav>

Также с помощью тега nav определяем навигационную область. Как вы можете заметить у нас 6 основных пунктов меню и еще одна дополнительная ссылка. Она будет появляется когда размер экрана будет минимальным и основные пункты скроются. Для того чтобы их развернуть будем кликать по этой ссылке.

Стили

В этом разделе мы начнем оформление создаваемой навигации. Nav тег, который определяет навигационную область будет иметь 100% ширины окна браузера, в то время как список с пунктами меню будет 600px по ширине. Также выровняем его по центру (margin: 0 auto).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
nav {  
    height: 40px;  
    width: 100%;  
    background: #455868;  
    font-size: 11pt;  
    font-family: 'PT Sans', Arial, sans-serif;  
    font-weight: bold;  
    position: relative;  
    border-bottom: 2px solid #283744;  
}  
nav ul {  
    padding: 0;  
    margin: 0 auto;  
    width: 600px;  
    height: 40px;  
}

Теперь для выстроим элементы списка в линию.

1
2
3
4
nav li {  
    display: inline;  
    float: left;  
}

Если вы заметили, из разметки HTML выше, мы уже добавили название классов, как для навигационной области так и для списка ul. В данном случае используется метод Clearfix, позволяющий избавиться от бага, с НЕ изменением высоты блока родителя под действием дочерних плавающих блоков. Попробуйте убрать этот метод и посмотрите, что получиться. Итак, давайте добавим следующие правила стиля в таблицу стилей.

1
2
3
4
5
6
7
8
9
10
11
.clearfix:before,  
.clearfix:after {  
    content: " ";  
    display: table;  
}  
.clearfix:after {  
    clear: both;  
}  
.clearfix {  
    *zoom: 1;  
}

Так как у нас есть шесть пунктов меню, и мы также указали, что их контейнер шириной в 600px, соответственно каждый элемент меню ссылки будут иметь 100px в ширину.

1
2
3
4
5
6
7
8
9
nav a {  
    color: #fff;  
    display: inline-block;  
    width: 100px;  
    text-align: center;  
    text-decoration: none;  
    line-height: 40px;  
    text-shadow: 1px 1px 0px #283744;  
}

Ссылки меню будут разделены одним пикселем правой границы, за исключением последнего (псевдокласс :last-child). Но если мы добавим к элементу меню правую границу в один пиксель то его ширина изменится на 101px, чтобы этого избежать воспользуемся свойством CSS3 box-sizing. Значение border-box означает что ширина элемента включает в себя границы (border). Таким образом ширина элемента меню не измениться.

1
2
3
4
5
6
7
8
9
nav li a {  
    border-right: 1px solid #576979;  
    box-sizing:border-box;  
    -moz-box-sizing:border-box;  
    -webkit-box-sizing:border-box;  
}  
nav li:last-child a {  
    border-right: 0;  
}

Установим цвет ссылки при наведении.

1
2
3
nav a:hover, nav a:active {  
    background-color: #8c99a4;  
}

А также пока скроем дополнительную ссылку id=pull.

1
2
3
nav a#pull {  
    display: none;  
}

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

Адаптивное меню - Обычное состояние

Медиа запросы

CSS3 медиа запросы используются, чтобы определить, некоторые технические характеристики устройства посетителя веб-страницы, в частности какой стиль будет применяться в зависимости от размеров экрана устройства.

Разрешения экранов

Так как наше меню изначально имеет 600px фиксированной ширины, мы сначала определим стили, когда окно браузера 600px или меньше.

При таком размере экрана, каждый из двух пунктов меню будет отображаться рядом друг с другом, поэтому ширина списка (nav ul) здесь будет 100% окна браузера, в то время как в пункты меню (nav li) будут иметь 50% ширины окна браузера. Наверно, проще посмотреть на изображение.

Адаптивное меню в действии

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@media screen and (max-width: 600px) {  
    nav {  
        height: auto;  
    }  
    nav ul {  
        width: 100%;  
        display: block;  
        height: auto;  
    }  
    nav li {  
        width: 50%;  
        float: left;  
        position: relative;  
    }  
    nav li a {  
        border-bottom: 1px solid #576979;  
        border-right: 1px solid #576979;  
    }  
    nav a {  
        text-align: left;  
        width: 100%;  
        text-indent: 25px;  
    }  
}

Теперь, мы определим каким будет наше меню, когда ширина экрана примет значение 480px или меньше.

В этой ситуации, появляется дополнительная ссылка, лучше сказать кнопка (nav a#pull), и теперь чтобы увидеть пункты меню необходимо кликнуть по ней. Для того чтобы прикрепить иконку используем псевдо-элемент :after. Кнопка задается как блочный элемент с относительным позиционированием, а иконка встраивается в нее.

Адаптивное меню - основные пункты скрыты

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@media only screen and (max-width : 480px) {  
    nav {  
        border-bottom: 0;  
    }  
    nav ul {  
        display: none;  
        height: auto;  
    }  
    nav a#pull {  
        display: block;  
        background-color: #283744;  
        width: 100%;  
        position: relative;  
    }  
    nav a#pull:after {  
        content:"";  
        background: url('nav-icon.png') no-repeat;  
        width: 30px;  
        height: 30px;  
        display: inline-block;  
        position: absolute;  
        right: 15px;  
        top: 10px;  
    }  
}

Наконец, когда экран становится 320px и меньше, меню отображается вертикально, сверху вниз. То есть ширина в 100% от ширины окна браузера.

1
2
3
4
5
6
7
8
9
10
@media only screen and (max-width : 320px) {  
    nav li {  
        display: block;  
        float: none;  
        width: 100%;  
    }  
    nav li a {  
        border-bottom: 1px solid #576979;  
    }  
}

Теперь, Вы можете попробовать изменить размер окна браузера и увидите, что произойдет с меню.

Немного волшебства jQuery

На данный момент меню скрыто. Для его открытия надо нажать на кнопку «Меню», раскрытие меню реализуется за счет метода jQuery slideToggle(). Для удобства создадим две переменные pull и menu. Куда с помощью селектора поместим элементы, область кнопки (ссылки) и список (все пункты меню), соответственно.

1
2
3
4
5
6
7
8
9
$(function() {  
    var pull        = $('#pull');  
        menu        = $('nav ul');    
 
    $(pull).on('click', function(e) {  
        e.preventDefault();  
        menu.slideToggle();  
    });  
});

Далее, отслеживаем событие клик, по кнопке и методом slideToggle() раскрываем все пункты меню, при повторном нажатии на кнопку пункты скроются.

Однако, при изменении размера окна браузера сразу после того, как Вы скрыли пункты меню, оно будет оставаться скрытым. Потому что display: none, порожденное jQuery все еще привязано к элементу.

Следовательно, нам нужно при увеличении окна браузера более 320px, удалить (removeAttr) у элемента ul атрибут style со значениями.

1
2
3
4
5
6
$(window).resize(function(){  
    var w = $(window).width();  
    if(w > 320 && menu.is(':hidden')) {  
        menu.removeAttr('style');  
    }  
});

На этом все. Создание данного меню — отличный пример адаптивной верстки. ВОТ отличный инструмент для тестирования сайта на дружелюбность к мобильным устройствам.

Чтобы оставаться в курсе свежих статей и уроков подписывайтесь на страницу ВКонтакте или подпишитесь на почтовую рассылку. Не забывайте оставлять комментарии к статьям и урокам. Спасибо!

Чтобы оставаться в курсе свежих статей и уроков подписывайтесь на еженедельную почтовую рассылку или на новостную ленту RSS. Спасибо!