Как сделать на css резиновое адаптивное меню?

Привет. Очень давно не писал постов на тему работы html/css. Недавно как раз начал верстать новый макет и в процессе наткнулся на интересный прием, который позволяет сделать меню резиновым (в него можно будет добавлять новые пункты и размер не увеличиться, а всегда будет 100% родительского блока). Итак, сегодня реализуем на css резиновое меню.

Кому лень читать статью, можно посмотреть это видео. Автор также все очень классно объясняет:

Резиновое меню на CSS — шаг 1

Первый шаг — это всегда html разметка, куда же без нее. Но в нашем случае все будет просто:

  1. блок обертка для меню
  2. само меню, выведенное через маркированный список (тег ul)
  3. ну и пункты меню внутри, а в них, соответственно, уже ссылки

Все понятно, вот такой у меня код разметки:

<div class = "wrap">
<ul class = "r-menu">
<li><a href = "#">Пункт 1</a></li>
<li><a href = "#">Пункт 2</a></li>
<li><a href = "#">Пункт 3</a></li>
<li><a href = "#">Пункт 4</a></li>
<li><a href = "#">Пункт 5</a></li>
</ul>
</div>

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

Шаг 2 — базовые стили

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

*{
	margin: 0;
	padding: 0;
}

Это стандартный код, для верстки реальных сайтов рекомендую использовать более серьезное решение — файлы типа reset.css. Читайте о них здесь.

Далее я добавлю стили блоку-обертке. А именно, установлю максимальную ширину в 600 пикселей (просто чтобы удобно было делать скриншот, чтобы меню влезало), а также отцентрирую блок.

.wrap{
	background: #fff;
	max-width: 600px;
	margin: 0 auto;
}

Шаг 3 — реализуем резиновость

Теперь беремся за само меню. У него (у тега ul) я уберу маркеры, сделаю фоновый линейный градиент, и, самое главное, свойством display: table-row заставлю контейнер для меню вести себя как табличный ряд. Это важно сделать для дальнейших манипуляций.

.r-menu{
	background: linear-gradient(to right, #b0d4e3 0%,#88bacf 100%);
	display: table-row;
	list-style: none;
}

Как видите, приведенный код как раз решил все, о чем я писал. Кстати, градиенты удобно генерировать с помощью инструмента Ultimate CSS Gradient generator. О нем я еще напишу как-то.

Далее нужно задать стили для пунктов меню. Вот:

.r-menu li{
	vertical-align: bottom;
	display: table-cell;
	width: auto;
	text-align: center;
	height: 50px;
	border-right: 1px solid #222;
}

Поясню:

  • vertical-align: bottom — это свойство необходимо для того, чтобы в случае, если текст в пункте меню займет 2 строки, он отображался ровно. Когда мы сделаем меню, можете удалить это свойство, увеличить масштаб чтобы пункты сжались и текст перенесся на две строки и увидите проблему с отображением. Верните свойство и все будет нормально.
  • display: table-cell — поскольку мы задали самому меню отображения табличным рядом, логично будет задать его пунктам отображение как ячейки в таблице. Это обязательно.
  • width: auto — ширина будет вычисляться автоматически, в зависимости от длины текста в пункте
  • text-align: center — это просто для выравнивания текста внутри по центру
  • height: 50px — задаем высоту в 50 пикселей
  • ну и border-right это просто граница справа, такой разделитель для пунктов

Пока меню выглядит неказисто, но ничего, настало время довести его до ума.
2 второй шаг
Последнее, что нужно сделать — задать стили ссылкам внутри пунктов. Тут у меня такой код:

.r-menu li a{
	text-decoration: none;
	width: 1000px;
	height: 50px;
	vertical-align: middle;
	display: table-cell;
	color: #fff;
	font: normal 14px Verdana;
}

И вот так теперь выглядит меню:
меню
Опять же, поясню некоторые строки:

  • свойство text-decoration отменяет подчеркивание у ссылок, которое ставится по умолчанию
  • width: 1000px — пожалуй, самая важная строка. Нужно задать ссылкам примерно такую ширину, можно и меньше, но обязательно больше максимально широкого пункта меню. Ссылки не станут в ширину 1000 пикселей, поскольку ширину ограничит пункт меню li, у которого ширина задана как auto, зато это позволит сделать так, чтобы при любом количестве пунктов в меню оно всегда было на 100 процентов ширины.
  • vertical-align: middle и display: table-cell — первое выровняет текст по вертикали по центру, а второе также делает отображение ссылок в виде ячеек. Оба свойства нужны.
  • font — ну это просто набор установок для шрифта. Читайте про css свойства для шрифтов в этой статье.

Шаг 4 (по желанию) можно добавить интерактивности

Например, чтобы при наведении изменялся цвет пункта меню. Реализуется это совсем просто, с помощью псевдокласса hover:

.r-menu li:hover{
	background-color: #6bba70;
}

при наведении

Тестируем меню на резиновость

Отлично, меню готовы, но мы не проверили самое главное — насколько оно резиновое, как я вам и обещал. Что ж, добавлю в меню еще 2 пункта:
7 пунктов
Меню осталось в ширину на 600 пикселей. Остальные пункты просто немного ужались, чтобы поместились 2 новых.

Добавлю еще 1 длинный пункт:
8 пунктов
Как видите, меню еще немного ужалось и длинный пункт отобразился вполне себе нормально. А если бы не было свойства vertical-align: bottom, о котором я вам говорил, то меню выглядело бы хуже.

Уменьшу меню до трех пунктов.
3 пункта
Пунктам стало гораздо свободнее, но само меню не поменялось в ширине. Вот мы и сделали 100% резиновое меню!

Как его адаптировать?

В принципе, если вы задали блоку-обертке не фиксированную, а максимальную ширину, то его даже не нужно адаптировать. В моем случае у меня стоит свойство max-width: 600px и когда ширина станет меньше 600 пикселей, блок просто будет уменьшаться вслед за экраном, не образуя горизонтальной прокрутки.

Ну а если вы хотите как-то изменить или поправить меню на мобильных устройствах или широких экранах, то медиа запросы вам в помощь! Успехов в сайтостроении!

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

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: