www.htmlgoodies.com/beyond/css/article.php/3752046
|
By Stu Nicholls June 10, 2008 IntroductionOne of the main uses for CSS is the styling of unordered lists used to hold menu links. In this article I explain how to remove the unordered list items and replace them with images and, using two images per link, have a hover state that is flicker free. What Flicker?This is a problem that occurs in Internet Explorer when the Temporary Internet Files > Settings > Check for newer versions of stored pages is set as 'Every visit to page.' I have been informed that there is a high percentage of people who browse with this option in place. When this option is chosen, Internet Explorer does not cache background images and has to download them each time they are needed. This creates a short delay in the image display (dependent upon their file size) and accounts for the flicker when you hover over each link. As I've said, this only happens with Internet Explorer, but since this is the most commonly used browser we should attend to this issue and find ways to stop this annoying flicker. To see an example of the problem, open Internet Explorer and as a temporary measure, select Tools > Internet Options > General > Temporary Internet Files > Settings and click 'Every visit to the page' (make a note of your original setting before you make this change). Then click the following link to for a demonstration. Don't forget to switch back to your original Internet Explorer setting afterwards. Flickering ExampleIf you are using any other browser than Internet Explorer then the 'flicker' issue doesn't apply.. MethodThe following method not only replaces your standard unordered list with images but also gets rid of the flicker. The Unordered ListBecause I love art and the 'Old Masters,' I have chosen five names of painters and have a standard list with the (X)HTML as follows:
I have enclosed the list in a div tag with an id. This gives you control over the position of the menu by giving it a position style. i.e. position:absolute or float:left; Each list tag <li> is given a class name as a unique identifier, which could also have been an id. Each link tag <a> is given a unique id and title. The title is used to give a popup description of the link when hovered over. I have not given a link address as this is only a demonstration but you can replace the # with your link pages as required. That completes the (X)HTML for the menu. THIS WILL NOT CHANGE ON ANY OF THE FOLLOWING EXAMPLES. The only changes will be to the styling of this unordered list and will accomplished using CSS. The basic list looks like this: Basic ListStep 1Make sure that you have the correct (X)HTML !DOCTYPE. Without this most browsers will be thrown into 'quirks' mode which will lead to all sorts of incompatibility problems. W3C QA - List of valid DTDs has a list of valid DOCTYPES that can be used. Select from XHTML1.0 or XHTML1.1 as these are more suitable for this styling (I use XHTML1.1 for all my current web pages). Step 2Using your favourite paint package create your images. You will need one image for the normal link (unhovered) and another image for the hovered link. I need 10 images for my menu and have chosen a painting by each artist. The unhovered images have been converted to a sepia tone whilst the hovered images are full color. I have also added the painter's name at the bottom of each image. It is possible to use different size images for each link but to keep things simple for this demonstration I have used images of the same size. The ten images Step 3Removing the bullets and marginWe will start by removing the bullets and moving the unordered list to the left of our containing div. Browsers have different ways of doing this; Internet Explorer and Opera use margin values whereas Mozilla/Netscape/Firefox all use padding values, so to cater to Internet Explorer we need to style the list as follows.
The list will now look like this: Example oneStep 4Making the list horizontalBecause I want a horizontal menu I need to style the list that places all the links on the same line. Some people use display:inline; but on some browsers this puts a gap between each list item. I prefer float:left; as this removes the gap. Add the following to your CSS:
This changes the list as: Example twoStep 5Adding the initial imagesNow it starts to get interesting (and more involved), so make sure you understand this step before continuing. In order to stop the flicker in Internet Explorer we need to ensure that there is an image on screen at all times. This may sound obvious, but the answer is not. My answer is not to hold the initial image in the link tag <a>, but to put it as a background image in the list tag <li>. Here, each list tag <li> is given a unique class which can be used to style the background color and image. To do this, add the following lines to your CSS:
Remember that if you are using an external css file the path to the images is taken from the CSS file not the (X)HTML file. The list now has partial images: Example threeYou will notice that the images are not fully shown and the link text is still visible. Don't worry. The size will be defined later. Just be aware that the background images are in place. Step 6Styling the link tagsEven more interesting things happen when we style the link tags <a>. The first thing is to apply a general style to all the links. The critical styling is the height of zero! This is used with an overflow:hidden; style to stop the link text from being displayed, but if it's got no height then how can we have a background image? Well, with a bit of lateral thinking we can add a top padding equal to the height of the image, which will ensure that the text remains invisible but gives our link an area in which to display the background. The general link styling is as follows:
And the result looks like this: Example fourNotice that I have added a hack for earlier versions of Internet Explorer to correctly define the height of the links. Also notice that the size of the link is taken up by the list tag <li> and the background images are now displayed correctly. The link tags have a transparent background color that allows the list images to be seen and the link text has gone. Step 7Separating the imagesWith the images next to each other it's a little unclear where one finishes and the next begins, so I've added a gap between them. This is easily achieved by adding a right margin to the list tag <li>, so change the <li> style as follows.
And the result looks like this: Example fiveStep 8Adding the :hover imagesWe're almost finished. All we need to do is add the hover state images to each of the link tags <a>. We have given each link a unique id so that we can target each one separately. We could just style the background images to be loaded 'on hover,' but it would be more user friendly to preload the images before the visitor hovered over the links thus creating an instant change. This is possible for those browsers that cache background images that are not initially displayed. My method is to add the background image to the un-hovered link and to move the background image position out of view. This is achieved using the following additional CSS link styling:
You will see that the hover images are not displayed when the mouse is hovered over the links. This is because the :hover state has not yet been defined. The background color needs to be transparent to allow the list images to show through and the image position need to be given at least one negative (or positive) value that is larger than the image size. 'no-repeat' is used to ensure that the image will be displayed only once. The list now looks like this: Example sixStep 9Defining the :hover styleFinally, we get to the bit that does all the work - the :hover style. This is a straightforward link style that moves the background images into place at the top left of each link and is styled by adding the following to your CSS:
The z-index is needed to make sure that the link background is displayed on top of the list background. Without it, older versions of Internet Explorer will not display the hover image. Again, I have added the box model hack for older versions of Internet Explorer. Here's the working list: Example sevenStep 10Lastly - clearing the floatBecause this list uses 'float:left,' you will need to clear this to make sure that the page flow will continue as required. There are many ways of doing this but the easiest is to define the height and width of the containing div #menu. This needs to be larger than the total size of the list images and in my case I have used width=430px and height=130px. To modify the CSS, add the following style values:
And we FINALLY end up with this: Example eightAnd that, as they say, is it. Flickering menus are a thing of the past!About the AuthorStu's website documents his attempts at understanding and exploring the possibilities of CSS. From standard navigation links to his more bizarre experimental techniques. All of his examples are produced with JUST CSS--no javascript, or any other language, has been used in any of the examples. [Editor's note: Prepare to be amazed!] http://www.stunicholls.myby.co.uk/ This article originally appeared on WebReference.com. |