Получать рассылку по электронной почте

Введите свой email-адрес:

Delivered by FeedBurner

Навигация

Как сделать резиновое меню? Способы создания горизонтальной навигации на сайте.

навигация

Итак, мы рассмотрим всевозможные варианты того, как создать резиновое CSS меню. Начнем с создания навигации из строчных (inline) элементов.

Горизонтальное резиновое текстовое меню

строчное резиновое меню

Суть сводится к тому, чтобы равномерно распределить текстовые пункты навигации на всю ширину. Слева и справа (у границ меню) отступы отсутствуют, а между отдельными словами расстояния абсолютно одинаковые. В основе этого способа лежит использование свойства text-align:justify,которое, как известно, распределяет текст по всей ширине за счет изменения расстояний между словами, что собственно нам и нужно.

Но если строка одна, как, собственно, и должно быть когда мы создаем меню, текст не распределится по всей ширине. Потребуется небольшая хитрость, для того, чтобы его заставить. Используем для этого псевдоэлемент :before, который сгенерирует нам дополнительное содержимое, размер одной строки будет превышен и текст растянется. Этот дополнительный контент(в примере 1) не будет виден благодаря обрезке overflow:hidden. Можно дополнительно скрыть его с помощью height:0 или visibility:hidden.

Еще нюансы кода: для того, чтобы слова в отдельных пунктах не разрывались применяется inline-block вместо inline  (в правилах для a).

Смотрите код  и действующий пример.

Демонстрационный пример

Горизонтальное меню из блоков одинаковой ширины

резиновое меню с блоками одинаковой ширины

С использованием свойства display:table

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

Поэтому мы поступим другим образом и применим к нашей таблице (или к элементам ведущим себя как таблица – в примере список ul-li) свойство table-layout. Данное свойство позволяет упрощенно вычислять ширину ячеек таблицы на основе первой строки, причем для его корректной работы обязательно должна быть задана общая ширина таблицы. Поскольку ширину отдельных ячеек мы ни явно, ни косвенно указывать не будем, table-layout разделит таблицу на ячейки одинаковой ширины, что  и требуется получить.

Демонстрационный пример

С шириной пунктов в процентах

Демонстрационный пример

Горизонтальное меню из блоков с одинаковыми отступами

резиновое меню из блоков с одинаковыми отступами

С использованием  Flexible Box Model

Долгое время меня интересовал вопрос, как же создать навигацию,  ширина всех пунктов которой складывалась бы  из ширины, зависящей от размеров содержимого и добавочной ширины, имеющей одинаковое значение для каждого пункта. Ее браузер должен вычислять при изменении размеров окна и добавлять к  блокам меню. Для лучшего понимания взгляните на картинку.

одинаковые отступы

Красными стрелками показано расстояние между текстом и правой рамкой блока, это как раз те добавочные отступы, которые должны меняться динамически и быть одинаковыми для всех пунктов. Расстояние между словами пунктов меню также  в таком меню одинаково (так как равно удвоенному отступу).

Сначала мне вообще казалось, что подобное можно создать только лишь используя  JavaScript. Но решение в действительности есть и на чистом CSS – применение технологии CSS 3, которая называется Модель Гибкого Поля (Flexible Box Model). Она позволяет с легкостью осуществлять многие трюки , которые было выполнить с набором стандартных свойств CSS 2.1 весьма непросто. Это и выравнивание по вертикали, и колонки одинаковой высоты, и возможность менять порядок следования столбцов  не редактируя HTML и т.д., в общем  можно написать целую отдельную статью.

Попробуем применить данную методику на практике для наших нужд. Сначала  присвоим списку ul  класс  container и зададим ему свойство  display:box. Данное значение свойства display является новым и  сообщает браузеру, что данный блок следует рассматривать как  особый элемент, называемый “гибким  полем”.  Его дочерние элементы li будут выводиться горизонтально, благодаря свойству box-orient.

Следующее очень важное свойство, которое должно быть присвоено пунктам меню – box-flex. Оно задает степень гибкости  элементов li, т.е. от него зависит как блоки поделят между собой свободное пространство. В примере ниже для  пунктов меню задано значение box-flex:1, следовательно они разделят доступное пространство в равной пропорции. Таким образом поставленная задача решена.

Далее приводится код  HTML и CSS, а также практический пример функционирования меню.

Демонстрационный пример

С  использованием display:table (либо таблицы)

Все было бы хорошо в первом варианте, если бы не существенный минус – поддержка браузеров оставляет желать лучшего, причем для достижения хоть какой-то кроссбраузерности приходится применять собственные свойства браузеров с префиксами. Такие как   -moz (Firefox),  -webkit (Chrome и все браузеры на  основе Chromium, включая последние версии Оперы – как известно разработчики отказались от  использования движка Presto),  c поддержкой старых версий Оперы и Internet Explorer все еще  хуже.

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

таблица с большим и маленьким пунктом

Как это решить? Например, если добавить для ячеек свойство width:1%,то ситуация в корне меняется. Точного объяснения не могу дать, предположу, что когда ширина ячеек одинакова и заведомо меньше содержимого, свободное пространство начинает распределяться между ними поровну. Чем бы это не объяснялось, на выходе  мы получаем результат практически идентичный использованию Flexible Box Model.

Далее приведен код этого варианта навигации.

Демонстрационный пример

Но он также не поддерживается IE и Opera (Presto), видимо у данных браузеров другой алгоритм расчета ширины ячеек. Поэтому пример придется сильно усложнить.

К сожалению, более простого варианта не знаю, но он позволяет добиться наконец одинакового отображения для IE8-IE11.

Блоки содержащие текст имеют минимальную ширину, так как задано правило width:1%, а отступы, меняющиеся в зависимости от ширины формируют  дополнительные ячейки справа и слева (класс space), благодаря правилу

Демонстрационный пример

Если для вас критична поддержка IE 7, используйте таблицу, если не очень – лучше использовать список и применять для него свойство CSS display:table. Во всяком случае использование таблиц мне кажется меньшим злом, чем expression. Но в конечном итоге решать вам.

На этом мой обзор закончен, любые вопросы и замечания пишите в комментариях.

Понравилась статья?
Подпишитесь на RSS по e-mail
Поделитесь в социальных сетях
Вы можете также посмотреть
Комментарии
  1. Прикольный пост, на рсску подписался. Будем читать

  2. Удивили! Удивили и порадовали не то слово…

  3. Офигеть просто! Все, блин, всё знают, кроме меня

  4. Здравствуйте! Подскажите, пожалуйста, как можно сделать, чтобы пункты меню выпадали одинаковой высоты? По типу eBay http://www.ebay.com/

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

  5. А как создать горизонтальное меню с отдельными кнопками и с расстояниями между ними, чтоб тоже все сжималось?

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*