Главная » CSS, Статьи и переводы

Эффект “rollover” меню

12 Март 2008 просмотров 13 529 комментариев 16


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

  1. Это вообще можно реализовать без JS ?
  2. Как избежать эффект пропадающего фона при наведении на кнопку?
  3. Сколько картинок мне нужно для 1 кнопки?
  4. Можно ли сделать кнопку не фиксированной ширины?
  5. Можно ли обойтись без CSS-фильтров?

Думаю каждый из вас сталкивался с этими вопросами. Давайте раз и навсегда разберемся с ними.

Начнем по-порядку, т.к. 1-й вопрос особенно актуален для новичков. Ответ простой: да, можно. К концу статьи вы поймете, что даже навыков JS вам не нужно знать, чтобы реализовать нашу задачу. Перейдем ко 2-му вопросу.

Как избежать эффект пропадающего фона при наведении на кнопку? Для этого можно воспользоваться 2 методами:

  1. Использовать свойство background-position для управления положением фона кнопки
  2. Определять перекрывающую картинку как фон у родительского элемента кнопки (например, у <li>)

Остановимся на каждом из методов по подробнее. Первый способ предполагает, что мы разместим на 1 картинке сразу несколько изображений кнопок, например так:

rollover_m1.gif

Таким образом код для кнопки будет выглядеть следующим образом:

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 меню можно скачать здесь.

Комментариев 16 »

  • ]]>Антон пишет: ]]>

    забираю =)

      Цитировать

  • ]]>mntek пишет: ]]>

    в mac os все работает (:

      Цитировать

  • ]]>exoundeeq пишет: ]]>

    *** ваш пример. Попробуйте в FF увеличить размер шрифта.

    >> Не нужно выражаться, пожалуйста.
    Причем тут увеличение шрифта? Задача состояла не в том, чтобы добиться эластичности – об этом написано в другой статье.

      Цитировать

  • ]]>Kvazar пишет: ]]>

    Респект!

      Цитировать

  • ]]>repsak пишет: ]]>

    Просматриваю через макстон 2.0.7.1245… коряво отображается…

    как понимаю трабла в em!!!!
    а так зачетно, но эта тема уже очень давно известна…!!!

      Цитировать

  • ]]>sociosam пишет: ]]>

    меню отличное!

    я вот разбираюсь только с версткой на дивах, и очень пригодилось одно ваше решение) огромное спасибо!

      Цитировать

  • ]]>[IGOS] пишет: ]]>

    Просто для кнопки, без меню проще использовать такую конструкцию:

    работает абсолютно во всех браузерах, даже в допотопном нетскейпе…

      Цитировать

  • ]]>WebSee.Ru пишет: ]]>

    Попробуйте для первого метода сделать следующим образом, тогда проблема в ИЕ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;
    }

      Цитировать

  • ]]>Yeva пишет: ]]>

    Здравствуйте! Огромное спасибо за полезнейший материал.У меня возникла следующая проблема: в IE меню выглядит отлично до тех пор, пока е не переношу его в документ начинающийся с
    < !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    в таком документе тег перестаёт восприниматься как блочный и его фоновая картинка смещается. При удалении указанных выше строк меню исправляется, но зато перекашивается всё остальное. Буду благодарна за оперативный ответ. Спасибо

      Цитировать

  • ]]>Автор пишет: ]]>

    Решение простое:
    в стилях .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!!!!
    а так зачетно, но эта тема уже очень давно известна…!!!

      Цитировать

Комментарии

Добавьте ваш комментарий, или трекбэк с сайта. Вы также можете подписаться на комментарии к этой статье через RSS.

Вы можете использовать теги:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Чтобы получить аватарку, зарегистрируйтесь на Gravatar.