Справочник фронт-энд девелопера: виды горизонтальных панелей навигации. Горизонтально центрированное меню с использованием только CSS Что такое верстка меню
Задача центрирования горизонтального меню может оказаться не такой уж простой, особенно для новичков в CSS. Поиск решений приводит к весьма ограниченному списку методов, основная часть которых полагается на трюки CSS, JavaScript или использование нестандартных правил, которые поддерживаются не всеми браузерами. В данном уроке мы разберем метод центрирования горизонтального меню, который использует только стандартные правила CSS и работает во всех браузерах.
Пример центрированного менюНиже приведено горизонтальное центрированное в данной колонке меню, в котором активизирована вторая закладка. Можно попробовать изменить размер окна браузера или страницы, чтобы убедиться в том, что меню всегда остается центрированным и рабочим.
На демонстрационной странице можно увидеть несколько вариантов оформления горизонтально центрированного меню. Любой из них можно использовать в своих проектах.
Разметка HTMLВсе меню, примеры которых приводятся в данном уроке, используют простую структуру. Это обыкновенный неупорядоченный список ссылок, помещенный в элемент div .
- Первая закладка
- Вторая закладка
- Третья закладка
- Четвертая закладка
Ниже приводится полный код CSS, с помощью которого центрируется меню. А объяснения принципа работы приводятся далее в уроке.
#centeredmenu { float:left; width:100%; background:#fff; border-bottom:4px solid #000; overflow:hidden; position:relative; } #centeredmenu ul { clear:left; float:left; list-style:none; margin:0; padding:0; position:relative; left:50%; text-align:center; } #centeredmenu ul li { display:block; float:left; list-style:none; margin:0; padding:0; position:relative; right:50%; } #centeredmenu ul li a { display:block; margin:0 0 0 1px; padding:3px 10px; background:#ddd; color:#000; text-decoration:none; line-height:1.3em; } #centeredmenu ul li a:hover { background:#369; color:#fff; } #centeredmenu ul li a.active, #centeredmenu ul li a.active:hover { color:#fff; background:#000; font-weight:bold; }
Как работает метод центрированияДействие метода основано на относительном позиционировании плавающих блочных элементов один в другом. Для начала посмотрим, как изменяется размер элементов при смещении.
Элемент div (блочный) без смещения растягивается на всю доступную ему ширину.
Но если мы будем смещать элемент div влево, он автоматически будет ужиматься до размеров своего содержимого. Сжатие является ключевым моментом в реализации данного метода центрирования меню. Оно помогает перемещать меню в правильную позицию.
Стандартное выровненное влево менюВозьмем стандартное выровненное влево меню и будем шаг за шагом его переделывать. Для наглядности пункты окрашены в разные цвета, так что сразу понятно, что куда вложено.
Обратите внимание на следующие моменты:
- Элемент centeredmenu div (голубой прямоугольник) смещается влево, но имеет ширину 100%, поэтому остается растянутым на всю страницу.
- Элемент ul (розовый прямоугольник) находится внутри элемента centeredmenu div и смещается влево. Это означает, что он будет ужат до ширины своего содержимого, то есть до суммарной ширины всех закладок.
- Все элементы li (зеленые прямоугольники) находятся внутри элемента ul и смещаются влево. Таким образом, они ужимаются до размеров ссылок в них и выстраиваются в одну горизонтальную линию.
- Внутри каждой ссылки (оранжевые прямоугольники) выводится текст закладки: Закладка 1, Закладка 2 и так далее.
Затем мы смещаем элемент ul вправо на 50% с помощью свойства position:relative; . Когда элемент смещается с указанием процента при таких условиях важно помнить, что суммарная ширина содержащихся в нем элементов не является его шириной. В нашем случае смещение происходит на половину окна браузера (или доступного для вывода пространства).В результате наше меню начинается на середине окна и частично выходит за его пределы. И переходим к следующему шагу.
Сдвигаем положение всех элементов менюОсталось только сдвинуть все элементы li влево на 50%. Это 50% ширины нашего элемента ul (контейнера, который содержит меню). Таким образом, закладки смещаются точно на центр окна.
Несколько важных замечанийПри использовании данного метода центрирования надо помнить о нескольких важных моментах:
- Так как элемент ul частично выходит за рамки окна, то это приводит к выводу полос прокрутки. Поэтому нужно использовать правило overflow:hidden; для элемента centeredmenu div . Таким образом, выступающая часть элемента div будет обрезана.
- Так как элемент ul не выровнен по закладкам, то нельзя использовать никаких визуальных стилей для него. Оставьте элемент ul без фонового цвета и без рамки, чтобы он стал полностью невидимым. А стили для закладок нужно использовать только для элементов li .
- Если нужно задать особенные стили для первой и последней закладки, нужно добавить класс для первого и последнего элементов li , чтобы можно было стилизовать их индивидуально.
Предложенное решение совместимо со всеми браузерами, не использует JavaScript и поддерживает изменяемый размер текста.
Продолжаем серию уроком посвященных выпадающим меню. На очереди горизонтальное выпадающее меню на css своими руками.
Если вы попали сюда случайно или вы искали другую реализацию выпадающего меню советую перейти в родительский раздел .
В этом разделе будет описанное горизонтальное выпадающее меню на CSS и HTML.
Навигация по странице:
И так, наша задача:
сделать горизонтальное меню с выпадающим списком css (на списках ul li) без использования jQuery и Javascript, а также без применения таблиц
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
Горизонтальная панель
|
Горизонтальная панель li { display: inline-block; margin-right: 6px; background: #FF8C00; transform: skewX(-45deg); -webkit-transform: skewX(-45deg); -o-transform: skewX(-45deg); -ms-transform: skewX(-45deg); -moz-transform: skewX(-45deg); } a { display: block; padding: 18px 35px; color: #fff; transform: skewX(40deg); -webkit-transform: skewX(40deg); -o-transform: skewX(40deg); -ms-transform: skewX(40deg); -moz-transform: skewX(40deg); } li:hover { background: #1C1C1C; }
Для второй программы используем за основу предыдущий код. Я захотел, чтобы пункты моего вертикального меню были не скошены, а с округленными углами.
Для этого я воспользовался еще одним свойством css border-radius .
В предыдущих статьях я уже работал с данным параметром, так что сложностей с пониманием его функционирования, думаю, не возникнет.
Вертикальная панель li{ display: block; margin: 13px; padding: 13px; background: #FF8C00; width:20%; text-align:center; font-size:20px; border-radius:10px; } a { color: #fff; } li:hover { background: #1C1C1C; }
Как вы уже заметили, главное изменение в этом коде – это отсутствие объявления display: inline-block , который собственно и отвечал за горизонтальное расположение пунктов навигации.
Подпункты в меню: выпадающий списокМы с вами рассмотрели основные группы навигационных панелей, однако существует еще несколько разновидностей или лучше сказать дополнений.
Иногда возникают такие ситуации, когда некоторые из пунктов дополняют основные. В этом случае не обойтись без выпадающих списков. Они создаются путем преобразований инструментами css.
Ниже я прикрепил код небольшой программки, в которой реализуется данный подход.
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | Выпадающий список body { padding-left: 30%; font-size: 18px; } .m-menu { margin: 0; padding: 9px; width:50%; text-align:center; border: 3px solid #000; background: #FF8C00; } .m-menu > li { position: relative; display: inline-block; } .m-menu a { display: block; margin-left: -2px; padding: 13px; color: #fff; border-left: 3px solid #fff; } .m-menu a:hover { background: #1C1C1C; } .m-menu .s-menu { left: 10px; position: absolute; display: none; width: 155px; margin: 0; padding: 0; list-style: none; background: #FF8C00; } .m-menu .s-menu a { border: 1px solid #000; } .m-menu > |
Выпадающий список body { padding-left: 30%; font-size: 18px; } .m-menu { margin: 0; padding: 9px; width:50%; text-align:center; border: 3px solid #000; background: #FF8C00; } .m-menu > li { position: relative; display: inline-block; } .m-menu a { display: block; margin-left: -2px; padding: 13px; color: #fff; border-left: 3px solid #fff; } .m-menu a:hover { background: #1C1C1C; } .m-menu .s-menu { left: 10px; position: absolute; display: none; width: 155px; margin: 0; padding: 0; list-style: none; background: #FF8C00; } .m-menu .s-menu a { border: 1px solid #000; } .m-menu > li:hover .s-menu { display: block; }
Прежде всего, давайте разберемся, для чего нужно меню, и что оно из себя представляет.
Меню сайта - это список страниц или разделов сайта, размещенный на видном месте, и предназначенный для доступа пользователя к этим страницам или разделам. Меню бывают двух типов: главные и дополнительные. Обычно в главном меню содержатся ссылки на ключевые разделы сайта. В дополнительных меню обычно размещают ссылки на подразделы или конкретные страницы. Кроме того, меню могут иметь иерархическую структуру 3-х видов: выпадающий список, раскрывающийся список и раскрытый список (может иметь древовидную структуру).
Итак, мы выяснили, что меню представляет из себя одноуровневый или многоуровневый список. Соответственно делать мы его будем с помощью элемента, представляющего список. В HTML такие элементы определяются тегами ul и ol , обозначающими маркированный и нумерованный списки соответственно. Каждый элемент списка пределяется тегом li .
В нашем веб-документе, в месте, предназначенном для размещения кода горизонтального меню, запишите следующий HTML-код:
Этот список будет главным меню нашего сайта. Не обязательно делать главное меню в виде закладок. Вы даже можете использовать многоуровневое раскрытое или выпадающее меню, или еще какое-либо, но при разработке меню обратите внимание на удобство навигации. Как правило, чем меньше вложенность любого меню тем удобнее. Таким образом, меню, имееющее более одного уровня вложенности является не самым лучшим выбором. В этом случае, лучше рассмотреть возможность внедрения дополнительного меню, либо еще какого-нибудь способа навигации.
Первый элемент главного меню имеет атрибут class со значением selected , поэтому используя правило CSS, заданное селектором с именем этого класса, мы можем особо выделить вкладку меню, определенную этим элементом. В данном примере мы не будем как-либо выделять выбранный элемент. Тем не менее, именно таким способом создаются меню, которые имеют текущую выбранную вкладку. Кроме того, здесь все ссылки ведут на текущую страницу. В реальном меню, ссылок, ведущих на себя же быть не должно, за исключением разве что ссылки на главную страницу. Также все ссылки заключены в тег span , он нам понадобится чтобы вертикально центрировать текст.
Списки в HTML являются блочными элементами. Если сейчас вы откроете нашу веб-страницу в браузере, вы увидите, что ссылки в нашем меню размещены одна под другой. Поэтому вместе с оформлением каждого элемента, определяющего вкладку, мы должны определить стиль его отображения.
Добавим в файл стилей следующие правила:
#hmenu {
margin-left: 160px; /* служит для выравнивания меню так, чтобы оно начиналось
над областью контента */
}
/* оформляем вкладку */
#hmenu li {
/* задаем шрифт */
font-family: Calibri;
font-size: 14px;
/* отступ сверху */
margin-top: 5px;
/* расстояние между вкладками */
margin-left: 0.5em;
margin-right: 0.5em;
/* указатель мыши */
cursor: pointer;
/* Фон */
background-image: url("mm_button.png");
background-repeat: no-repeat;
/* размеры вкладки */
width: 100px;
height: 40px;
/* делаем элемент линейным и одновременно блочным */
display: inline-block
}
/* оформление активной вкладки */
.selected { /* ... */}
/* вкладка при наведении мыши */
#hmenu li:hover {
background-image: url("mm_button_hover.png");
}
/* оформление текста ссылок */
#hmenu li a {
color: green;
text-decoration: none; /* запрещаем подчеркивание ссылок */
}
/* вертикально центрируем текст */
#hmenu li a span {
display: block; /* делаем элемент блочным */
padding-top: 0.8em;
padding-bottom: 0.8em;
}
Здесь все описано внутри кода, лишь отмечу, используя приведенный выше CSS-код, правильно отобразят страницу только современные браузеры. То есть, в Internet Explorer ниже 8 версии страница будет представлена неправильно. Это связано с тем, что старые браузеры, такие как Internet Explorer 6 и 7 не поддерживают значения inline и inline-block для списков. Решить эту проблему поможет замена строки display: inline-block во втором правиле на
/* для младших версий Firefox */
display: -moz-inline-stack;
/* для всех, кроме IE 7- и Firefox */
display: inline-block;
/* Для IE 7 и ниже */
*display: inline;
_overflow: hidden;
zoom: 1;
Аналогичным образом создадим меню слева.
Оформим с помощью CSS.
#vmenu li a
{
color:Green;
text-decoration:none;
}
#vmenu li
{
font-family:Calibri;
font-size:14px;
font-style:normal;
width:115px;
display:block;
overflow:hidden; /* скроем вылезающие элементы */
padding:0.5em 0em 0.5em 0;
/* сделаем элемент в виде кнопки, задав соответствующий фон */
background-image:url("sm_button.png");
background-position:center;
background-repeat:no-repeat;
}
#vmenu li a span
{
width:100px;
padding-left:1em;
padding-right:100px;
display:block;
}
#vmenu li:hover
{
background-image:url("sm_button_hover.png");
}
Также, как и в предыдущем случае, в Internet Explorer младших версий возникнет ошибка отображения. Связана она с удвоением отступов у элементов в этом браузере.
На следующем уроке мы завершим верстку нашей страницы, разместив логотип нашего сайта, контент и подвал страницы.
Предисловие: работая верстальщиком, ваш покорный слуга заметил, что существует несколько типов меню; при этом для верстки каждого из них следует использовать свои приемы.
Подробности - под катом.
Данная статья нацелена скорее на начинающих верстальщиков, но, может быть, матерые профессионалы тоже найдут в ней что-то новое или будут обращаться к ней как к справочнику.
Топик структурирован следующим образом: сначала ставится задача - описывается вид требуемого навигационного блока, затем рассматриваются приемы, позволяющие создать именно такую навигацию.
Подразумевается, что написание стилей ведется под семантически корректную структуру меню, которая выглядит примерно так:
Домой
Сделать заказ
Обратная связь
При верстке под doctype, отличный от html5, элемент nav опускаем или заменяем на соответствующий div.
Что ж, начнем!..
Пункты меню, расположенные по правой/левой стороне В данном разделе рассмотрены навигационные блоки, в которых элементы размещены по правой/левой стороне. Для верстки таких блоков, в зависимости от ситуации, можно использовать несколько способов:Данный способ целесообразно применять при верстке меню простого вида, в котором элементы представлены в виде отдельных слов, не имея padding"ов и разделены лишь пробелами между ними:
Как делается
У элементов li в CSS нужно установить свойство display: inline. Кстати, это уберет и ненужные в большинстве меню такого вида маркеры, так как они находятся в дополнительных блоках, которые содержатся у элементов с display: list-item, а у inline"ов отсутствуют.
У ul устанавливаем свойство text-align в значение right или left соответсвенно.
Примечания
- При использовании этого варианта стоит помнить, что у inline элементов вертикальные margin"ы не учитываются, но горизонтальные работают;
- при необходимости верстки pixel perfect, есть вероятность столкновения с проблемой: в разных браузерах ширина пробела между элементами разная. Для решения проблемы расстояние между элементами выставляют margin"ами, а пробелы убирают ;
- если подчеркивание в ссылках элементов меню сделать нижним border"ом, в современных браузерах можно получить красивое анимированное на:hover меню (JSFiddle).
Когда необходимо сделать меню с элементами, имеющими padding"и и/или фиксированную высоту/ширину:
Как делается
Устанавливаем float: left или float:right элементам li. Если нужно убрать маркеры, нужно добавить display: block или list-style: none.
Примечания
- Необходимо «очистить» ul, задав ему класс.clearfix или поместив в его конец элемент с clear: both, иначе у ul высота будет равна нулю; о других способах «очистки» float"ов можно прочитать ;
- пример интересного меню, сверстанного float"ами: html5guy .
Задачи те же, что и при верстке с float. И да, при решении такой задачи inline-block пал в неравном бою. Во-первых, кроссбраузерность такого решения ниже, чем у float"a, а во-вторых, между inline-block"ами, как и между inline-элементами, появляются пробелы, зачастую ненужные. Эти проблемы решаемы, но зачем их создавать?
Как делается
Устанавливаем display: inline-block элементам li. Ну, а для IE7 (если вы его поддерживаете) прописываем *display:inline; *zoom: 1.
Меню расположено по центру:
Как делается
В зависимости от вида пунктов меню, устанавливаем display: inline или display: inline-block (если для пунктов меню предусмотрены padding"и задана ширина и/или высота) элементам li. Родителю (ul) устанавливаем text-align: center.
Примечания
Позволю себе повториться: иногда появляется необходимость в том, чтобы убрать пробелы между inline- и inline-block- элементами; несколько способов решения этой задачи можно найти .
Пункты меню равномерно распределены по всей ширине, между отдельными пунктами имеются промежутки:
Как делается
В зависимости от вида пунктов меню, устанавливаем display: inline или display: inline-block элементам li. Родителю (ul) устанавливаем text-align: justify. Но сразу justify не заработает - нужно переполнить первую строку (если непонятно почему так - запускаем ворд и пытаемся растянуть несколько слов на всю ширину при помощи justify). Поэтому в конец элемента ul добавляем дополнительный элемент с display: inline-block и width: 100%, или, что лучше, псевдо-элемент::after с такими же характеристиками.
Примечания
Помните, в предыдущих типах меню мы убирали пробелы между элементами со свойством display, установленным в inline и inline-block? Так вот, в этом случае так делать категорически нельзя - браузеру нужны промежутки между пунктами меню. Кстати, если убрать пробелы между некоторыми элементами, можно группировать кнопки (JSFiddle):
Между пунктами меню нет промежутков, любое количество пунктов меню занимает всю ширину:
Как делается
При решении данной задачи есть соблазн сверстать меню таблицами; но мы же не собираемся нарушать семантику документа, правда? Поэтому используем display: table-cell для li и display: table для ul; потом задаем ширину для ul
Если нужна поддержка старых браузеров, используем скрипт-полифилл , подменяющий такие блоки на таблицы для IE6 и IE7 или организуем fallback другими способами.
Примечания
При верстке меню данным способом нужно помнить, что нельзя размещать элементы с position: absolute относительно table-cell.
Почему?
Дело в том, что в спецификации w3c действие position: relative на table-cell не определено , поэтому в каждом браузере могут наблюдаться свои особенности.
Посмотрите этот пример в разных браузерах (особо пристально смотрим на поведение Mozilla Firefox!).
Для решения этой проблемы в ячейку нужно помещать div, относительно которого производить позиционирование.