2 октября 2012 в 10:59

Создаем адаптивную навигацию на сайте перевод tutorial

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



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

HTML


Прежде всего необходимо в тег HEAD добавить meta viewport для масштабирования на любом устройстве:

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


Затем добавляем пункты меню в виде обычного списка:

<nav class="clearfix">  
    <ul class="clearfix">  
        <li><a href="#">Home</a></li>  
        <li><a href="#">How-to</a></li>  
        <li><a href="#">Icons</a></li>  
        <li><a href="#">Design</a></li>  
        <li><a href="#">Web 2.0</a></li>  
        <li><a href="#">Tools</a></li>    
    </ul>  
    <a href="#" id="pull">Menu</a>  
</nav>  


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

CSS


Основные CSS-стили:
body {  
    background-color: #ece8e5;  
}  
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;  
}  


Пункты меню должны следовать друг за другом, используем float:

nav li {  
    display: inline;  
    float: left;  
}  


Используем clearfix-хак:

.clearfix:before,  
.clearfix:after {  
    content: " ";  
    display: table;  
}  
.clearfix:after {  
    clear: both;  
}  
.clearfix {  
    *zoom: 1;  
}  


Каждый пункт меню шириной 100 пикселей:

nav a {  
    color: #fff;  
    display: inline-block;  
    width: 100px;  
    text-align: center;  
    text-decoration: none;  
    line-height: 40px;  
    text-shadow: 1px 1px 0px #283744;  
}  
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;  
}  
nav a:hover, nav a:active {  
    background-color: #8c99a4;  
}  


Дополнительный пункт на больших экранах должен быть скрыт:

nav a#pull {  
    display: none;  
} 


Сейчас меню корректно отображается только на большом экране:



Media Queries


CSS3 media queries определяют, какие стили будут использоваться в каждой конкретной ситуации (например при разных разрешениях экрана).



В нашем меню при разрешении менее 600 пикселей в ширину пункты навигации должны отображаться в два столбца:



@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;  
    }  
}  


При разрешении экрана менее 480 пикселей, должна появляться дополнительная кнопка меню, по нажатию которой раскрывается вся навигация:



@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;  
        rightright: 15px;  
        top: 10px;  
    }  
}  


При разрешении менее 320 пикселей меню должно отображаться в один столбец:

@media only screen and (max-width : 320px) {  
    nav li {  
        display: block;  
        float: none;  
        width: 100%;  
    }  
    nav li a {  
        border-bottom: 1px solid #576979;  
    }  
}  


Отображение навигации


При помощи slideToggle() отображаем все меню на больших экранах и скрываем на маленьких:

		$(function() {
			var pull 		= $('#pull');
				menu 		= $('nav ul');
				menuHeight	= menu.height();

			$(pull).on('click', function(e) {
				e.preventDefault();
				menu.slideToggle();
			});

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



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

Демо Скачать исходники
+44
22313
613
grokru 199,5

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

+2
pluser, #
А без jQuery?
0
anor, #
А без JS, CSS и HTML? =)
+4
pluser, #
В идеале только CSS и HTML но и JS вполне разумно использовать.
jQuery не нужен.
+2
friday, #
Здесь не нужен ни jquery, ни яваскрипт вообще.

Перед добавить, ссылку #pull заменить на и добавить к стилям:

nav > input { position: absolute; left: -9999px; }
nav > input:checked + ul { display: block; }
0
friday, #
Чёрт, хабр съел теги. Перед смиском добавить чекбокс, ссылку заменить на label.
0
Makito, #
А если человек откроет сайт в ие7-8 в уменьшенном окне (ну вот вдруг), то функционал сломается.
0
friday, #
Такие «вдруг» нерепрезентативны. Но если очень хочется, можно и продублировать на яваскрипте.
+2
equand, #
А если слон поедет на трамвае, трамвай тоже сломается…
0
sapegin, #
Хороший способ! Я делал с помощью ссылки, :target и CSS transition. Но без JS меню не уезжало обратно.
–7
sergeisirik, #
Как-то много кода и мало текста. Ну можно ещё и флэш сделать и не париться, тоже будет везде отображаться флэш плеером.
0
Renius, #
Под везде вы наверное iOS устройства подразумеваете?
–1
sergeisirik, #
+3
Renius, #
Я вижу по первой ссылке Mac OS. Flash не работает на устройствах iOS.
+1
TheMengzor, #
Вы еще не проснулись, напишите оправдательный комментарий через пару часиков.
–1
sergeisirik, #
Извините не совсем понял к чему вы?
–1
sergeisirik, #
Я написал своё мнение о статье, и предложил альтернативный вариант. Мне показалось, что более развёрнутые комментарии статье не помешали бы.
0
TheMengzor, #
Вы написали о решении на флеше, а флеша нет на всех мобильных устройствах (iOS в целом, Android последних версий, Windows Phone, Symbian, etc), только у единиц пользователей. А речь идет о создании универсального меню для настольных и мобильных клиентов.
0
snater, #
Вместо clearfix в данном случае можно использовать overflow:hidden для ul
+1
psywalker, #
Или решение Ильи Стрельцына (SelenIT2);)
+1
maxshopen, #
В Fx15 меню не ужалось до одного столбца, в IE8 вообще ничего не работает, меню только для большого экрана, в хроме порядок. Иконка вообще нигде не показывается.
0
xsubst, #
странно, у меня в Firefox 15 ужалось.
0
maxshopen, #
0
macik_spb, #
Если количество пунктов нечетное, в 2 колонки не красиво будет.
+1
anor, #
Можно пустую плашку показывать)
–2
bw3d, #
ну принцепе дельный цсс буду иметь ввиду.
но. всетаки мне кажется для мобильных версий надо делать отдельные страницы и там уже пытаться вписаться в отдельные экраны.
+2
Razbezhkin, #
Суть адаптивного дизайна как раз в том, чтобы сделать одну страницу, которая будет адаптироваться к разным устройствам.
0
bw3d, #
вы определенно правы. в теории так и есть. но реальность такова что полностью адаптивный дизайн может получится неоправданно трудозатратным
+1
Razbezhkin, #
Думаю, что создавать отдельную страницу для разных устройств — более трудозатратная работа. Представьте, что у вас на сайте 50 динамических страниц и вам нужно сделать вариант для экрана, для планшета и для смартфона (три варианта). в результате получается 150 страниц. Когда нужно что-то поменять на одной странице — это нужно сделать на трех страницах. в общем вот такое направление мыслей. Кроме того, наверное, не случайно, появилась тенеденция делать сайты адаптивными — значит этот подход привлекает все большее число разработчиков.
0
Makito, #
Все же адаптивный дизайн не панацея. Скорее даже, адаптивную верстку можно применять в достаточно ограниченном пространстве тематики сайтов
0
bw3d, #
собственно об этом и я.
0
bw3d, #
я не говорил про 150 дизайнов я сказал про 2 варианта страницы
1. для десктопнях браузеров.
2. адаптивный для мобильных устройств.

вы реальные вебклиенты\сайты делали? есть случаи где для десктопа функуилнальность вразы больше чем для мобылы и таких случаев большинство. для мобилы имеем информативную функциональность из серии буть в курсе или сделай что то простое. (ибо больше с мобилы просто не удобно) для десктопа всякие настройки и конфиги. сайты типа домашней страницы или того же баша по сложности вертски приближающихсяк нулю не стоит сравнивать со всеми вместе. для простых сайтов разумеется проще сделать полностью адаптивный дизайн
0
EzS, #
ну принцепе дельный цсс буду иметь ввиду.
но. всетаки мне кажется для мобильных версий надо делать отдельные страницы и там уже пытаться вписаться в отдельные экраны.
Мне казалось, школьные каникулы закончились?
0
Gorky, #
А почему сначала идет «media screen and» а потом «media only screen and»? Эта какая-то особенность адаптивной верстки? Что будет если в первом правиле добавить only или убрать у следующих?
+1
lol2Fast4U, #
only не нужен
+2
MagicWolf, #
Может я чего-то не понимаю, но разве display:inline + float:left не избыточно?
0
yurik417, #
Opera 12.02 — меню сказало: «досвиданья» и скрыло от меня текст пунктов
0
Sergun, #
Интересно, а почему меню получило мобильное представление на телефоне с разрешением экрана 768х1280?
0
Makito, #
Потому что для мобильных устройств включается масштабирование
0
Sergun, #
Каким образом?
0
Sergun, #
Минусануть, вместо того, чтобы нормально пояснить — типичная позиция хабра-жителей.
ОК :-)

Только зарегистрированные пользователи могут оставлять комментарии.
Войдите, пожалуйста.