Данная статья предназначена для новичков в CSS, желающих научиться делать красивые меню без использования JavaScript, сохраняя при этом чистый код HTML-страниц. Я постараюсь объяснить каждое применяемое правило, показывая промежуточные результаты.
Начнем мы с семантической разметки. Наше меню, содержащее сразу три уровня — это простой ненумерованный список, а каждое подменю в нем — это вложенный список. Такой подход имеет ряд преимуществ:
-Код вашего меню занимает мало места -Меню становится доступным для поисковиков и альтернативных клиентов -Вы разделяете содержимое и представление, контролируя оформление только при помощи CSS
Пусть вас не пугает вложенность списков. Главное — следить за правильностью открытия/закрытия тегов. В частности, каждый вложенный тег <ul> должен содержаться внутри тега <li>. Теперь мы добавим несколько кусочков CSS в наш код:
Code
#nav, #nav ul { list-style: none; margin: 0; padding: 0; border: 1px solid #000; background: #515151; float: left; width: 100%; } #nav li { float: left; position: relative; background: #515151; back\ground: none; } #nav li ul { display: none; }
Этими тремя правилами мы сделали следующие вещи:
-Убрали буллеты из нашего списка — list-style:none -Обнулили отступы padding и margin у элементов меню -Украсили меню границей и задним фоном. Свойство back\ground:none служит для задания прозрачного фона во всех браузерах кроме IE 5. Я поясню это позднее -Заставили каждый элемент списка <li>, встать на одну линию при помощи правила float:left -Скрыли подменю 2-го и 3-го уровня, указав display:none
Так как все элементы списка <ul id="nav"> теперь «плавающие», то сам список «схлопывается». Это происходит из-за невозможности вычислить реальную высоту элемента, который содержит другие «плавающие» элементы.
Для борьбы с этой напастью существует несколько методов, однако они могут не работать в новом IE 7. Поэтому здесь я решил использовать метод FNE, заключающийся в присвоении свойства float:left самому контейнеру. Это избавляет нас от «схлопывания» списка, но заставляет нижележащие элементы обтекать меню справа. Именно поэтому мы указываем ширину для всего меню 100% — чтобы справа просто не оставалось места. Добавим немного оформлениянашим ссылкам:
Первым правилом мы оформили ссылки (чтобы они больше походили на кнопки):
-Каждому элементу <a> мы присвоили свойство display:block, что дало нашим ссылкам ширину и высоту -Убрали подчеркивание при помощи text-decoration:none -Задали ширину каждой ссылки 120 пикселей (справедливости ради, надо сказать, что реальная ширина равна 140 (120 + 10 + 10) пикселям, так как в нее включаются и отступы) -Селектор #nav a:hover срабатывает в том случае, когда мы подводим курсор к ссылке, а #nav li:hover — когда подводим его к элементу списка. Второй случай понадобиться нам для того, чтобы в меню оставался «след» наших перемещений (мы это увидим далее).
Мы дописываем к уже существующему правилу:
Code
#nav li ul { display: none; }
следующие инструкции:
Code
#nav li ul { display: none; position: absolute; background: url(fone-tr.png); padding: 8px 0; width: 138px; }
Выражение position:absolute служит для абсолютного позиционирования подменю относительно элемента <li> верхнего уровня.
Code
#nav li li a { width: 118px; background: none; } #nav li:hover ul { display: block; }
Вся магия выпадающего меню заключена в строке display:block для #nav li:hover ul. Именно она заставляет подменю «появиться» при подводе курсора к ссылке, сменяя ранее установленный режим display:none:
Code
#nav li:hover li ul { display: none; width: 138px; top: -9px; left: 133px; } #nav li:hover li:hover ul { display: block; }
Ширина нашего подменю равна 138 пикселям из-за того, что мы вычитаем 2 пикселя от границ с каждой стороны: 140 – 1 – 1 = 138 пикселей.
Селектор #nav li:hover li ul оказывает влияние на подменю 3-го уровня. Мы его сдвигаем влево на ширину 133 пикселя (величина чисто эмпирическая), а также немного вверх (чтобы оно оказалось на одном уровне с активной ссылкой). Теперь, при наведении мышки, наше подменю будет выскакивать справа от ссылки.
Фактор IE Жизнь многих веб-разработчиков стала бы проще если бы не было Internet Explorer. Ситуация начинает улучшаться в связи с выходом седьмой версии, но до повсеместного ее распространения еще очень далеко.
В ранних версиях IE псевдокласс hover поддерживается только для элемента <a>. В нашем же случае это требуется для элемента списка <li>. Поэтому мы будем использовать простую функцию JavaScript для нужной нам реакции на подведение мышки:
Это позволяет «прицепить» класс jshover к любому элементу <li>, над которым проходит курсор. Эта функция работает только в Internet Explorer — для других браузеров она просто не нужна.
Теперь, чтобы меню заработало в IE, добавим к четырем уже существующим правилам по дополнительному селектору li.jshover:
Code
#nav li:hover, #nav li.jshover { ... } #nav li:hover ul, #nav li.jshover ul { ... } #nav li:hover li ul, #nav li.jshover li ul { ... } #nav li:hover li:hover ul, #nav li.jshover li.jshover ul { ... }
--------------------------------------------------- Дополнительная информация
В качестве фона для подменю используется полупрозрачный PNG-файл. IE 6 не поддерживает полупрозрачность, но вы можете это исправить.
Из-за использования полупрозрачной картинки мне пришлось убрать цвет фона. Это привело к тому, что при отключенных картинках буквы подменю становятся не видны. Выход один: задать цвет фона для #nav li, потеряв при этом полупрозрачность.
Я использую хак back\ground:none;, чтобы принудительно задать цвет меню для IE 5. Если этого не сделать, то в этом браузере фон не отображается. Наверное это можно исправить как-то по-другому, но у меня нет желания разбираться со всеми его причудами.
UPD. akella подсказал, что при некоторых настройках системы меню может распираться в Опере. Это происходит из-за использования для всех размеров «абсолютных» единиц px. Пиксели — это зло. Поэтому я сделал второй вариант полностью на em (кроме ширины границы). И именно из-за этой однопиксельной рамки могут появляться небольшие зазоры при увеличении размера шрифта. Выход — не используйте границу =)