Меню навигации всегда были довольно простыми в создании. Сверстайте неупорядоченный список, установите float:left
и готово. С адаптивным дизайном, который сейчас очень популярен, вы столкнётесь с некоторыми новыми трудностями.
Сейчас мы с нуля сверстаем простое, но эффектное адаптивное навигационное меню, которое вы сможете легко модифицировать и многократно использовать в своих проектах.
Что мы создаём
Если вы такой человек, которому сначала нужно увидеть результат, вот демо нашего будущего проекта. Обязательно измените размер окна своего браузера, чтобы увидеть адаптивные концепции в действии.
HTML
Давайте отбросим лишние рассуждения и сразу перейдём к делу. Вы ведь хотите добраться до интересного материала?
В первую очередь нам необходимо определиться с некоторой разметкой. Т.к. мы делаем меню навигации, это идеальный случай, чтобы использовать HTML5 элемент nav
.
1 2 |
<nav> </nav> |
Хотите верьте, хотите нет, но этот маленький кусочек кода доставил много хлопот, когда дело дошло до проверки. По непонятным причинам, стили просто не давали никакого эффекта в IE6-8! Наконец, через десять минут бесполезных попыток, нас осенило, что, были использованы элементы HTML5, которые, конечно же, не поддерживаются IE версии ниже 9.
К счастью, решение довольно просто, нужно только подключить известную библиотеку
1 2 3 |
<!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> |
Добавляем список
Теперь, когда мы определились с контейнером, пришло время добавить UL с восемью ссылками. В этой статье важно количество элементов, так что убедитесь, что используете именно восемь ссылок, если не уверены, что сможете самостоятельно справиться с некоторыми проблемами.
1 2 3 4 5 6 7 8 9 10 11 12 |
<nav> <ul> <li><a href="#">PixelsDaily</a></li> <li><a href="#">About</a></li> <li><a href="#">Clients</a></li> <li><a href="#">Work</a></li> <li><a href="#">Podcast</a></li> <li><a href="#">Downloads</a></li> <li><a href="#">Blog</a></li> <li><a href="#">Contact</a></li> </ul> </nav> |
Добавляем дополнительные теги
Чтобы сделать меню немного интереснее и информативнее, давайте добавим ещё одну строку текста под заголовком каждого элемента. Есть множество способов это сделать, и вы вполне можете пойти своим путем. Но мы добавили тег br
и использовали элемент small
для второй строки. Т.к. второй элемент действительно будет маленьким, у нас получится прекрасная семантическая разметка без лишних div
’ов, ID
или классов.
1 2 3 4 5 6 7 8 9 10 11 12 |
<nav> <ul> <li><a href="#">PixelsDaily<br /> <small>Go Home</small></a></li> <li><a href="#">About<br /> <small>Meet Us</small></a></li> <li><a href="#">Clients<br /> <small>Meet Our Friends</small></a></li> <li><a href="#">Work<br /> <small>See Our Work</small></a></li> <li><a href="#">Podcast<br /> <small>Hear Us</small></a></li> <li><a href="#">Downloads<br /> <small>Steal Our Stuff</small></a></li> <li><a href="#">Blog<br /> <small>Read About Us</small></a></li> <li><a href="#">Contact<br /> <small>Email Us</small></a></li> </ul> </nav> |
Результаты
После этого у нас должен быть простой, нестилизованный список ссылок. Заметьте, что без каких-либо усилий, наши теги small уже работают и уменьшают размер соответствующих строк.
Начальные стили
Начнём писать CSS. В первую очередь вспомним про старый добрый универсальный селектор и, воспользовавшись советом Пола Ириша (Paul Irish), применим box-sizing: border-box
ко всем элементам. Это поможет нам легко устанавливать размер наших элементов в процентах, даже при том, что будем использовать borders.
1 2 3 4 5 6 7 8 |
* { padding: 0; margin: 0; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } |
Стили контейнера
Прежде чем мы перейдём к стилям отдельных элементов списка, применим некоторые базовые стили для родительских элементов. Во-первых, для элемента nav
установим ширину на 90% от ширины body
. Это растянет меню на достаточно большое пространство, но всё же оставит небольшой отступ вокруг него. Убедитесь, что центрировали его на странице с помощью margin:auto
.
Также включите необходимые стили для неупорядоченного списка, чтобы сбросить список и избавиться от маркеров.
1 2 3 4 5 6 7 8 9 |
nav { width: 90%; margin: 50px auto; } nav ul { list-style: none; overflow: hidden; } |
Стили меню
Теперь, когда родительские элементы работают правильно, самое время поработать с элементами меню, к которым мы можем обратиться через элемент nav
вместе с тегами ссылок и элементов списка.
Здесь достаточно большой отрывок кода, но не пугайтесь, мы всё постепенно объясним.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
nav li a { background: #444; border-right: 1px solid #fff; color: #fff; display: block; float: left; font: 400 13px/1.4 'Cutive', Helvetica, Verdana, Arial, sans-serif; padding: 10px; text-align: center; text-decoration: none; text-transform: uppercase; width: 12.5%; } /*SMALL*/ nav small { color: #aaa; font: 100 11px/1 Helvetica, Verdana, Arial, sans-serif; text-transform: none; } |
Здесь свойства предоставлены в алфавитном порядке, для более простого поиска, но если честно это не лучший способ. Лучше группировать стили по функциям, так они имеют немного больше смысла. Если мы упорядочим свои стили таким образом, их будет легче рассматривать.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
nav li a { display: block; float: left; width: 12.5%; padding: 10px; background: #444; border-right: 1px solid #fff; color: #fff; font: 400 13px/1.4 'Cutive', Helvetica, Verdana, Arial, sans-serif; text-align: center; text-decoration: none; text-transform: uppercase; } |
Сначала идёт часть кода, определяющая форму и разметку каждого элемента списка. Мы изменили ссылки на элементы уровня блока, поставили float:left
, определили ширину и добавили небольшой padding
. Так мы получаем хороший большой прямоугольник для каждой ссылки в меню. Почему 12.5% для ширины? Потому что у нас восемь пунктов меню, а 100% / 8 даёт нам 12.5% ширины на каждый элемент.
Затем следует часть кода, отвечающая за визуальные стили блоков, которые мы создали. Мы даём им цвет фона и границу справа толщиной 1px.
Наконец, мы завершаем стили свойствами, отвечающими за текст меню. Здесь всё довольно просто, шрифт мы использовали “Cutive”, его вы можете найти здесь.
Для стилей small, мы изменили цвет, удалили text-transformation: uppercase
и установили шрифт на Helvetica.
Результаты
Эти стили имеют достаточно большое значение. Теперь меню выглядит намного лучше. Пользовательский шрифт работает, ссылки расположены в одной строке, небольшой текст отображается отлично; всё очень красиво.
Стили при наведении
Когда пользователь проводит курсор мыши над элементом списка, мы изменим его цвет на чёрный. Чтобы это смотрелось ещё лучше, добавим плавный полусекундный переход.
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 |
nav li a { background: #444; border-right: 1px solid #fff; color: #fff; display: block; float: left; font: 400 13px/1.4 'Cutive', Helvetica, Verdana, Arial, sans-serif; padding: 10px; text-align: center; text-decoration: none; text-transform: uppercase; width: 12.5%; /*ПЕРЕХОДЫ*/ -webkit-transition: background 0.5s ease; -moz-transition: background 0.5s ease; -o-transition: background 0.5s ease; -ms-transition: background 0.5s ease; transition: background 0.5s ease; } /*HOVER*/ nav li a:hover { background: #222; } |
Границы
Сейчас вы не можете это видеть, поскольку у нас белый фон, но на самом деле у нас есть проблема с границами (border). Мы использовали границы, чтобы разделить соседние элементы, поэтому у последнего элемента имеется ненужная нам граница. Чтобы это исправить, мы можем использовать псевдо-элемент last:child
.
1 2 3 |
nav li:last-child a { border: none; } |
Ниже мы применили временный цвет фона, только для того, чтобы вы смогли увидеть различия в меню до и после.
Адаптивность
Этот проект послужит отличным примером отличия адаптивного дизайна от резинового. Сейчас наше меню резиновое (оно использует ширину, указанную в процентах), но не адаптивное. Мы можем ясно это увидеть, когда попытаемся сильно уменьшить размер окна браузера:
Как видно, всё работает ужасно! Давайте попробуем использовать несколько media queries, чтобы посмотреть, сможем ли мы устранить эту проблему. Лучший способ узнать, где нам нужны media queries — просто открыть проект и посмотреть, где разметка ломается, а затем исправить это.
1220px
Первая проблема в нашем проекте возникает примерно при ширине 1200 пикселей. Здесь длинные строки текста начинают обрезаться и перестают быть полностью читабельными.
Чтобы это исправить, нам только нужно подогнать размер шрифта. Мы указали область непосредственно перед возникновением проблемы (1220px) и установили шрифт на 10px.
1 2 3 4 5 6 7 8 9 10 11 |
/* MEDIA QUERIES*/ @media only screen and (max-width : 1220px), only screen and (max-device-width : 1220px){ nav li a { font: 400 10px/1.4 'Cutive', Helvetica, Verdana, Arial, sans-serif; } nav small { font: 100 10px/1 Helvetica, Verdana, Arial, sans-serif; } } |
С этой правкой, проблема больше не возникает. Как только мы уменьшаем размер окна, меню реагирует и уменьшает размер шрифта.
930px
Снова уменьшаем размер окна и находим, что разметка ломается при отметке 900px. Здесь у нас проблема с переполнением:
Мы не будем делать шрифт всё меньше и меньше до тех пор, пока вы не перестанете его видеть, вместо этого мы полностью переупорядочим меню, разбив его на две строки. Теперь каждая ссылка будет большой и красивой.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@media only screen and (max-width : 930px), only screen and (max-device-width : 930px){ nav li a { width: 25%; border-bottom: 1px solid #fff; font: 400 11px/1.4 'Cutive', Helvetica, Verdana, Arial, sans-serif; } nav li:last-child a, nav li:nth-child(4) a { border-right: none; } nav li:nth-child(5) a, nav li:nth-child(6) a, nav li:nth-child(7) a, nav li:nth-child(8) a { border-bottom: none; } } |
Обратите внимание, что сейчас нам пришлось пересмотреть то, как работают наши границы. Теперь нам нужно, чтобы верхняя строка имела нижнюю границу, но не нужно, чтобы эта граница была у нижней строки. Опять же, с селекторами псевдо-классов это довольно просто.
580px и 320px
Формат из двух строк работает хорошо до тех пор, пока мы не пересекаем черту в 600px, после чего теряются все разрывы. Разметка полностью разваливается.
Чтобы решить эту проблему, мы завершаем наши media queries форматом меню из двух колонок и четырёх строк. Эту разметку мы используем при ширине ниже 580px и уменьшаем размер шрифта на отметке 320px.
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 only screen and (max-width : 580px), only screen and (max-device-width : 580px){ nav li a { width: 50%; font: 400 12px/1.4 'Cutive', Helvetica, Verdana, Arial, sans-serif; padding-top: 12px; padding-bottom: 12px; } nav li:nth-child(even) a { border-right: none; } nav li:nth-child(5) a, nav li:nth-child(6) a { border-bottom: 1px solid #fff; } } @media only screen and (max-width : 320px), only screen and (max-device-width : 320px){ nav li a { font: 400 11px/1.4 'Cutive', Helvetica, Verdana, Arial, sans-serif; } } |
Сейчас наше меню хорошо выглядит даже при очень маленьком разрешении. Обратная сторона медали заключается в том, что оно отнимает достаточно много вертикального пространства, но вы можете сократить padding
, если это вас беспокоит.
Selectivizr
Внимательные читатели заметят, что мы подстроились под старые версии IE с помощью html5shiv, чтобы селекторы псевдо-классов работали в IE. Кроме того, вам следует загрузить и подключить
Выводы
Адаптивный дизайн — это не прогулка по парку. Все это отнимает время, требует от вас определённых усилий и знаний “know how”, которые нужно уметь эффективно осуществлять. Нам нравится разбивать обучение на отдельные части, например, меню навигации в этой статье или одна из прошлых статей Создание адаптивной галереи миниатюр, так вы можете досконально изучить весь процесс верстки.
Теперь вы вполне сможете создать собственный проект с адаптивным меню без особых усилий. Можете оставить комментарий и показать, чего вы добились. С какими трудностями вы столкнулись во время работы?
Ребята, огромное спасибо за статью!
Только помощь нужна =)
Следуя вашему примеру, сделал такое меню:
Работает и отображает, как задумал, но только на экране монитора.
Попробовал на КПК (Win Mobile 6.1) и в Opera Mobile Emulator — там такой эффект:
Перекопал кучу интернета и, видимо, недокопал.
Пробовал добавить handheld в @media query: не помогло.
Пожалуйста, помогите, люди добрые =)
Максим, трудно вам ответить не имея на руках исходников. Нужно посмотреть на ваш код.
Alex, я залил архив наwww.boomerang.dn.ua/tmp/html2.rar
Заранее спасибо!
Alex, вот еще любопытная деталь.
Я скопировал коды из этой страницы:dabblet.com/gist/2030070
И вставил их у себя в соответствующие файлы html и css.
Результат получился с таким же эффектом, как и у меня: на мобильных устройствах и в Opera Mobile Emulator адаптивность потеряна. Как думаете, в чем пожет быть проблема?
А архив — здесь:www.boomerang.dn.ua/tmp/sample.rar
Возможно проблема заключается именно в браузере. Не могу сказать точно, но насколько я знаю, у Opera на некоторых устройствах есть привычка масштабировать сайт под размер дисплея.
Может быть это и влияет на адаптивность.
Alex, большое спасибо за информацию! Я разобрался: в Opera Mini все отлично.
Есть отличный инструмент, чтоб проверить адаптивность верстки сайта