Mobile Friendly Website


Doing it with style

CSS MENUS:hover craft tutorial

Date : Pre 2006

For all modern browsers

You have probably noticed that most of my demonstrations and menus make use of the :hover pseudo-class. As well as its normal use to alter the styling of links, it can also be used to show/hide text and images. With this tutorial I hope to take you through the various stages from simple link hovers to a basic flyout menu.

Simple link :hover

In order for your link styling to produce the required results you MUST have the styles in the correct order as follows.

a:link {}
a:visited {}
a:hover {}
a:active {}

Links can also be styled using a couple of other pseudo-classes:

a:focus {}
a:first-child {}

It is also possible to combine pseudo-classes to give more control over your link style, for example:

a:visited:hover {}
a:focus:hover {}

The unvisited link can also be written in three different ways.

a:link {}
 :link {}
a {}

And finally it is also possible to shorten the :hover pseudo-class as follows.

a:hover {}
 :hover {}

But note that this last option must be used with care as most modern browsers allow the use of :hover on all elements and not just links. This method is used on my more advanced dropdown and flyout menus.

So let us start with a basic link and add the various styles.

The example links below have been given an href="#nogo" so that you can test them out without being taken to another page.

<a href="#nogo">THE FIRST LINK</a>

The first step is to add a class to this link so that we can target it with out style:

<a class="link_one" href="#nogo">THE FIRST LINK</a>

We can now add our basis color and background style:

a.link_one {color:#fff; background:#00d; text-decoration:none;}
a.link_one:visited {color:#fff; background:#080;}
a.link_one:hover {color:#fff; background:#c00;}
a.link_one:active {color:#000; background:#cc0;}

Which gives use a link with the following style:


This one start off with white text on a blue background (:link), when hovered this changes to white text on a red background (:hover), click it and it turns to black text on a yellow background (:active), click off the text (IE) or release the mouse button (FF, Opera, Safari etc) and it changes to white text on a green background (:visited).

For most of my demonstrations the :link, :visited and :active all have the same style and the change is only made on :hover.

So we move on to the :hover only change of style.

<a class="link_two" href="#nogo">THE SECOND LINK</a>

To style just a change on :hover we can group the :link, :visited and :active together.

a.link_two, a.link_two:visited, a.link_two:active {
a.link_two:hover {color:#fff; background:#c00;}

Which gives use a link with the following style:


You can see that this one only has a change when :hovered. The :link, :visited and :active all have the same style.

Using :hover to show hidden information

Moving on to something a little more adventurous, we can use the :hover pseudo class to show some previously hidden 'link' text.

For instance, we can place some extra text in a link and hide it from view with just a little extra styling:

<a class="link_three" href="#nogo">THE THIRD LINK <b>WITH SOME
EXTRA TEXT</b></a>

and the styling:

a.link_three:hover {
a.link_three b {display:none;}

Which gives use a link with the following style, that looks exactly the same in all states but has hidden text placed between the <b>...</b> tags:


So on to the method of showing this hidden text when you hover over the link.

You would think that this would be an easy matter of styling the 'a:hover b' style to change it to display:inline; but this has its flaws when dealing with IE5.x and IE6 as I will demonstrate.

<a class="link_four" href="#nogo">THE FOURTH LINK <b>WITH SOME
EXTRA TEXT</b></a>
a.link_four:hover {
a.link_four b {display:none;}
a.link_four:hover b {display:inline; font-weight:normal;}

Which gives use a link with the following style:


In Firefox, IE7, Opera Safari etc this will correctly display the extra text when you hover over the link, but if you try it in IE5.x or IE6 then the extra text will stay hidden. This is a known bug, but fortunately there is also a known answer.

For this to work correctly in IE5.x and IE6 you will first need to either take a :link or :visited style and change it on :hover (an exception is the color style), or take one of the following styles that has not been used previously and declare its default value (there are more but the ones below are probably enough for most circumstances:

  • padding:0;
  • margin:0;
  • display:inline;
  • position:static;
  • border:0;
  • height:auto;
  • text-align:left;
  • text-indent:0;
  • white-space:normal;
  • direction:ltr;
  • float:none;

Because we don't want to change a previously declared style we can use border:0; as our trigger.

<a class="link_five" href="#nogo">THE FIFTH LINK <b>WITH SOME
EXTRA TEXT</b></a>
a.link_five:hover {
a.link_five b {display:none;}
a.link_five:hover {border:0;} /* our trigger for IE5.x and IE6 */
a.link_five:hover b {display:inline; font-weight:normal;}

Which gives use a link with the following style:


We now have a link that will display hidden text on :hover in IE5.x and IE6 as well as IE7, Firefox, Opera, Safari etc.

The text in the above examples was hidden using display:none; which takes it out of the normal flow of the page. We could also have used visibility:hidden; which would leave a gap in the flow of the page.

Moving on to menus

The main use of the :hover pseudo-class is to change the style of navigation menus when your visitor hovers over each link. Most web designers believe that navigation menus should be placed in an unordered list so who am I to argue. So we will move on from the single link styling demonstrated so far to an unordered list of links. Note that all the list items have been closed correctly with </li>.

<ul class="list_one">
<li><a href="#nogo1">List Item 1</a></li>
<li><a href="#nogo2">List Item 2</a></li>
<li><a href="#nogo3">List Item 3</a></li>
<li><a href="#nogo4">List Item 4</a></li>
<li><a href="#nogo5">List Item 5</a></li>

Which, without any styling, looks like this:

The first stage in styling this navigation menu is to get rid of the bullets and the text indent that is automatically applied to unordered lists.

ul.list_one {
  list-style-type:none; /* remove the bullets */
  margin:0; /* remove the automatic margin that some browsers use for the text-indent. */
  padding:0; /* remove the automatic padding that other browsers use for the text-indent. */

Which will make our navigation menu look like this:

Now we will add just a basic style to this menu to have a change of background color on :hover.

ul.list_two {
  list-style-type:none; /* remove the bullets */
  margin:0; /* remove the automatic margin that some browsers use for the text-indent. */
  padding:0; /* remove the automatic padding that other browsers use for the text-indent. */
  width:150px; /* fix the width of the list items which would default to 100% */
ul.list_two a, ul.list_two a:visited, ul.list_two a:active {
  text-decoration:none; /* remove the default underline from the links */
  display:block; /* make each link into a block so that hovering over any area of the link will cause a change of background color */
  width:150px; /*set the width to be the same as the ul width */
  text-indent:5px; /* move the link text 5px to the right */
  background:#c00; /* make the background color red */
  color:#fff; /* make the text color white */
  border-bottom:1px solid #fff; /* separate the links with a 1px wide white line */
ul.list_two a:hover {
  background:#00c; /* change the background to blue on :hover */

Which will make our navigation menu look like this:


How to code and style a single level html/css menu. See the 'Information' section below.

Works in IE6, IE7, IE8, Firefox, Opera, Safari(PC) and Google Chrome.

You may use this method on your personal 'non-profit' web site without seeking my permission.
A link back to CSS PLAY is always appreciated.

Commercial usage is also permitted without seeking approval, but I would ask that a donation is considered to support my work on CSS PLAY.

If you are having problems integrating any of my demonstrations into your website then I now offer a service to fault find and correct any errors that you may have introduced.
Please email me for more information.


Your donations keep CSS PLAY running.
If your donation is for the use of a demo then please email me with the demo url after making your donation.


Facebook Twitter rss feed Facebook Fan Page