Эффект “rollover” меню
Всем нам нравится эффект, когда при наведении на кнопку-ссылку в меню, фон кнопки меняется, подсвечивается и т.п. Тем самым позволяя нам не запутаться в том, какую ссылку мы выбираем – это то, что касается пользователей. Однако не все вебмастера решаются реализовать этот эффект, т.к. возникает сразу несколько вопросов:
- Это вообще можно реализовать без JS ?
- Как избежать эффект пропадающего фона при наведении на кнопку?
- Сколько картинок мне нужно для 1 кнопки?
- Можно ли сделать кнопку не фиксированной ширины?
- Можно ли обойтись без CSS-фильтров?
Думаю каждый из вас сталкивался с этими вопросами. Давайте раз и навсегда разберемся с ними.
Начнем по-порядку, т.к. 1-й вопрос особенно актуален для новичков. Ответ простой: да, можно. К концу статьи вы поймете, что даже навыков JS вам не нужно знать, чтобы реализовать нашу задачу. Перейдем ко 2-му вопросу.
Как избежать эффект пропадающего фона при наведении на кнопку? Для этого можно воспользоваться 2 методами:
- Использовать свойство background-position для управления положением фона кнопки
- Определять перекрывающую картинку как фон у родительского элемента кнопки (например, у <li>)
Остановимся на каждом из методов по подробнее. Первый способ предполагает, что мы разместим на 1 картинке сразу несколько изображений кнопок, например так:

Таким образом код для кнопки будет выглядеть следующим образом:
a {
background:url(menu_item.gif) top left no-repeat;
/* установили позицию фона обычной кнопки */
height:35px;
display:block;
font-size:12px;
color:#eee;
line-height:35px;
}
a:hover {
background:url(menu_item_hover.gif) bottom left no-repeat;
/* установили позицию фона кнопки при наведении курсором */
color:#fff;
}
Просто, не правда ли? Но радоваться рано :) Дело в том, что несмотря на то, что казалось бы загружается вся картинка, не зависимо от того какую позицую фона мы установим – для IE6 проблема исчезновения фона при наведении курсором не решиться. Поэтому подробно останавливаться на примере я не буду и сразу перейду ко второму способу. Именно он даст нам необходимый результат.
Второй метод предполагает, что определять фон картинки, которая должны быть при наведении, нужно у родительского элемента кнопки. Рассмотрим это сразу на примере.
Напишем небольшой код для нашего меню:
<ul> <li><a href="#">Ссылка 1</a></li> <li><a href="#">Ссылка 2</a></li> </ul>
Стили для элементов будут выглядеть так:
ul {
list-style:none;
height:35px;
padding:0px;
margin:0px;
}
ul li { /* это родительский элемент нашей кнопки */
float:left;
background:url(menu_item_hover.gif) no-repeat top left;
/* устанавливаем фон - картинку при наведении курсором на кнопку*/
}
a {
background:url(menu_item.gif) top left no-repeat;
/* установили фон обычной кнопки */
height:35px;
width:150px;
display:block;
font-size:12px;
color:#eee;
line-height:35px;
}
a:hover {
background:none;
/* убираем фон, тем самым нам становится виден фон
родительского элемента, у которого уже установлен
фон перекрывающей картинки и она !_уже загружена_! */
color:#fff;
}
Ну как вам идея? :) Чувствую, вы уже в предвкушении того, чтобы узнать ответы на остальные вопросы.
Вопрос о количестве картинок решился сам собой – нам необходима только 1 картинка для каждого из состояний кнопки. Теперь не нужно нарезать отдельно фон кнопки и уголки по бокам. Но сразу отмечу, что код, приведенный выше будет работать лишь кнопок фиксированной ширины. Чтобы ответить положительно на вопрос о “резиновости” кнопок, нам потребуется добавить в разметку еще несколько элементов:
<ul> <li><em><a href="#"><b>Ссылка 1</b></a><em></li> <li class="current"><em>Ссылка 2<em></li> <!--Активная кнопка--> <li><em><a href="#"><b>Ссылка 3</b></a><em></li> </ul>
Элемент <em> поможет нам избавиться от фиксированной ширины у <a>. Определим для <em> тот же фон, что и для <li>, но позиционируем его относительной правой части картинки, таким образом сохранив внешний вид кнопки таким, каким он должен быть. Также, нам необходимо будет задать левый отступ у <li>, чтобы дочерний элемент <em>, не перекрывал левый край кнопки и “подвинуть” a на такое же, но отрицательное значение, т.к. <a> должен полностью перекрывать фон родительского элемента.
Сссылка на полный код в конце статьи. Ниже лишь опишу основные моменты:
ul li {
float:left;
background:url(menu_item_hover.gif) no-repeat left top;
padding-left:8px;
}
ul li em {
background:url(menu_item_hover.gif) no-repeat right top;
...
}
ul li a {
display:block;
padding:0 0px 0 8px;
background:url(menu_item.gif) no-repeat left top;
position:relative;
margin-left:-8px;
...
}
ul li a b {
display:block;
display:inherit; /* Litle filter for IE */
padding:0 16px 0 8px;
background:url(menu_item.gif) no-repeat right top;
...
}
ul li.current {
background:url(menu_item_active.gif);
padding-left:16px;
}
ul li.current em {
background:url(button3.gif) no-repeat right top;
padding-right:16px;
}
ul li a:hover, .menu2 li a:hover b {
background:none;
}
А вот как это выглядит.
В примере 1 фон неативной кнопки совпадает с фоном меню, а в примере 2 у неактивных кнопок свое изображение, поэтому коды примеров несколько отличаются и по разметке – во втором примере, кроме <em> я добавила элемент <b> и у него обозначила фон кнопки с позиционированием по правому краю.
Теперь у нас есть полноценное “rollover” меню.
Что касается фильтров (хаков), как видите, таковых нет. Кроссбраузерность была проверена на IE6/7, Opera 9.25, FireFox 2.0.0.11. Одна лишь неувязочка – возможно будут проблемы в браузерах на Mac OS. Если такие найдуться, просьба оставить комментарий.
Код rollover меню можно скачать здесь.




Dmoz
забираю =)
АнтонЦитировать
в mac os все работает (:
mntekЦитировать
*** ваш пример. Попробуйте в FF увеличить размер шрифта.
>> Не нужно выражаться, пожалуйста.
Причем тут увеличение шрифта? Задача состояла не в том, чтобы добиться эластичности – об этом написано в другой статье.
exoundeeqЦитировать
Респект!
KvazarЦитировать
Просматриваю через макстон 2.0.7.1245… коряво отображается…
как понимаю трабла в em!!!!
а так зачетно, но эта тема уже очень давно известна…!!!
repsakЦитировать
меню отличное!
я вот разбираюсь только с версткой на дивах, и очень пригодилось одно ваше решение) огромное спасибо!
sociosamЦитировать
Просто для кнопки, без меню проще использовать такую конструкцию:
работает абсолютно во всех браузерах, даже в допотопном нетскейпе…
[IGOS]Цитировать
Попробуйте для первого метода сделать следующим образом, тогда проблема в ИЕ6 решается:
a {
background-image:url(menu_item.gif);
background-repeat: no-repeat;
background-position: top left;
/* установили позицию фона обычной кнопки */
height:35px;
display:block;
font-size:12px;
color:#eee;
line-height:35px;
}
a:hover {
background-position: bottom left;
/* установили позицию фона кнопки при наведении курсором */
color:#fff;
}
WebSee.RuЦитировать
Здравствуйте! Огромное спасибо за полезнейший материал.У меня возникла следующая проблема: в IE меню выглядит отлично до тех пор, пока е не переношу его в документ начинающийся с
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
в таком документе тег
перестаёт восприниматься как блочный и его фоновая картинка смещается. При удалении указанных выше строк меню исправляется, но зато перекашивается всё остальное. Буду благодарна за оперативный ответ. СпасибоYevaЦитировать
Решение простое:
в стилях
.menu2 li a bзаменитеdisplay:blockнаdisplay: -moz-inline-stack; /* для FF<3*/
display:inline-block;
АвторЦитировать
спасибо большое, сработало!
YevaЦитировать
а если я, к примеру, хочу чтобы не только фон подсвечивался, но и появлялось выпадающее меню – это сложно будет реализовать?
НеприврунЦитировать
Не сложно, если разобраться ;) Это меню вам не подойдет?
http://www.getincss.ru/2008/04/19/mnogourovnevoe-gorizontalnoe-vypadayushhee-menyu/
АвторЦитировать
А как редактировать надпись на кнопках? Допустим, нужно сместить текст на середину кнопки?
КатяЦитировать
как сделать чтобы меню было не горизонтальное, а вертикальное?
morfyЦитировать
Просматриваю через макстон 2.0.7.1245… коряво отображается…
как понимаю трабла в em!!!!
а так зачетно, но эта тема уже очень давно известна…!!!
реальныйЦитировать