Forum Moderators: not2easy

Message Too Old, No Replies

CSS Multi-Image Rollover without Preload

Please help - I can't find anything useful about this

         

hithere

9:43 pm on Jul 6, 2005 (gmt 0)

10+ Year Member



Hello! I'm still a bit new to using CSS style sheets. I have many images for the nav buttons for our site (both horizontal & vertical). I want to get rid of the flicker involved in CSS only loading the hover & pushed images as they are accessed. I'd rather not do the single image for each button & shift the background trick, as I've read about problems with that as well. I found a tip that sounds like it would be good to use and that sounds like it would be the best thing to avoid adding more html to my pages to preload the images. But I don't know how to incorporate it to work with my existing navigation buttons. Here's an example of some of my nav button CSS code for two of the vertical nav buttons. I know there is probably a lot of unnecessary extra code, but I am not sure of what can safely be omitted, so I just left it in for now:

.gift {
display: block;
width: 82px;
height: 30px;
background-image: url('../images/gift.gif');
background-repeat: no-repeat;
float:left;
vertical-align: top;
}
.gift:hover {
display: block;
width: 82px;
height: 30px;
background-image: url('../images/gift_a.gif');
background-repeat: no-repeat;
float:left;
vertical-align: top;
}
.gift:active {
display: block;
width: 82px;
height: 30px;
background-image: url('../images/gift_p.gif');
background-repeat: no-repeat;
float:left;
vertical-align: top;
}
.audio {
display: block;
width: 82px;
height: 30px;
background-image: url('../images/audio_video.gif');
background-repeat: no-repeat;
float:left;
vertical-align: top;
}
.audio:hover {
display: block;
width: 82px;
height: 30px;
background-image: url('../images/audio_video_a.gif');
background-repeat: no-repeat;
float:left;
vertical-align: top;
}
.audio:active {
display: block;
width: 82px;
height: 30px;
background-image: url('../images/audio_video_p.gif');
background-repeat: no-repeat;
float:left;
vertical-align: top;
}

Here is the tip I found online of a quick fix, no preload required, that I can't figure out how to incorporate into my code:

a,
a:hover,
a:focus { background: url(image_hover.gif); }
a:link { background: url(image_default.gif); }

Any help would be greatly appreciated! Thanks in advance!

Also, as far as omitting unnecessary extra code, can I modify my current code, but still have the same results, if I instead write it like this:

.gift {
display: block;
width: 82px;
height: 30px;
background-image: url('../images/gift.gif');
background-repeat: no-repeat;
float:left;
vertical-align: top;
}
.gift:hover {
background-image: url('../images/gift_a.gif');
}
.gift:active {
background-image: url('../images/gift_p.gif');
}
.audio {
display: block;
width: 82px;
height: 30px;
background-image: url('../images/audio_video.gif');
background-repeat: no-repeat;
float:left;
vertical-align: top;
}
.audio:hover {
background-image: url('../images/audio_video_a.gif');
}
.audio:active {
background-image: url('../images/audio_video_p.gif');
}

Thanks!

alias

3:31 pm on Jul 7, 2005 (gmt 0)

10+ Year Member



If the flickering occurs on IE - here's one of the best solutions.

Add the following lines to the .htaccess file in the root directory of your website.

ExpiresActive On
ExpiresByType image/gif A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/png A2592000

It will modify the image expiration period thus eliminating the flickering (usually on IE).

I hope it helps,
-=ms=-

hithere

6:20 pm on Jul 7, 2005 (gmt 0)

10+ Year Member



The flickering is in IE 6 and also occurs in Netscape 7.1 (and probably other versions as well). Maybe I shouldn't call it "flickering." Basically, instead of seeing my hover image on mouseover, instead the top image (unselected state) disappears and I see nothing for a few seconds until the hover image is loaded.

I'm using FrontPage 2003. I looked for the .htaccess file you were talking about, but I don't see anything like that for FrontPage, which likes to hide files from me. I can see this file online in our ftp, but I can't touch it there or it will mess up our FrontPage Extensions. Please let me know of an alternate way to access this file, and whether or not decreasing the expiration period will have an affect in Netscape as well. Thank you!

hithere

8:01 pm on Jul 7, 2005 (gmt 0)

10+ Year Member



Okay, I found how to modify my .htaccess file. But it didn't seem to help with the flickering for Netscape at all, and while at first it seemed to help with the horizontal naviation buttons in IE, the vertical nav buttons seem unaffected (have the same problem with the disappearing images until they have been loaded). Any other suggestions? Thanks!

SuzyUK

10:43 am on Jul 8, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi hithere and Welcome to WebmasterWorld!

I'd rather not do the single image for each button & shift the background trick, as I've read about problems with that as well.

The only problem I am aware of with using this method is that will sometimes be a flicker ONLY in IE6 and even then not all IE6 users will see it.. it only appears on IE6/Windows with a cache setting of "Every visit to page".

To change this option, Tools» Internet Options.. General Tab: Temporary Internet Files » Settings.

AFAIK, This means that mostly only developers/browser tweakers will see this "flicker" as this is not the default cache setting (It should be "automatically" I think..)

Anyway, As well as the .htaccess tweak above there is another method you can use to avoid seeing the flicker in IE..

USE One background image but put it in two places ~ on both the menu container { e.g. ul or div } AND on the menu item { e.g. usually <a> } that way if there is a temporary hesitation while fetching the hover state of the image, you don't notice it as the image on the background container will remain in view until the new image comes in to cover it ;)

I still prefer this method as the whole menu, either horizontal or vertical can use only one image no matter how many menu choices you have, which can simplify your CSS file too..

-------------------------------------

Also, as far as omitting unnecessary extra code, can I modify my current code, but still have the same results, if I instead write it like this:

Yes..

and you can simplify it even further too by using an ID on the nav container.


/*** presuming all vertical nav put inside div with an ID of "vertnav" ****/

#vertnav a {
display: block;
float:left;
width: 82px;
height: 30px;
vertical-align: top;
background-repeat: no-repeat;
background: position: 0 0;
}

#vertnav a.gift {background-image: url(gift.gif);}
#vertnav a.gift:hover {background-image: url(gift-hover.gif);}
#vertnav a.gift:active {background-image: url(gift-active.gif);}

#vertnav a.audio {background-image: url(audio.gif);}
#vertnav a.audio:hover {background-image: url(audio-hover.gif);}
#vertnav a.audio:active {background-image: url(audio-active.gif);}

Suzy

hithere

4:14 am on Jul 13, 2005 (gmt 0)

10+ Year Member



Hi Suzy! Thanks for replying. I haven't used containers before. I don't understand how I do the part you said about:

"USE One background image but put it in two places ~ on both the menu container { e.g. ul or div } AND on the menu item { e.g. usually <a> } that way if there is a temporary hesitation while fetching the hover state of the image, you don't notice it as the image on the background container will remain in view until the new image comes in to cover it ;)"

I changed my CSS to look like this:

#horiznav a {
display: block;
float:left;
width: 75px;
height: 23px;
vertical-align: top;
background-repeat: no-repeat;
background: position: 0 0;
}

#horiznav a.home {background-image: url('../images/home.gif');}
#horiznav a.home:hover {background-image: url('../images/home_a.gif');}
#horiznav a.home:active {background-image: url('../images/home_p.gif');}

#horiznav a.products {background-image: url('../images/products.gif');}
#horiznav a.products:hover {background-image: url('../images/products_a.gif');}
#horiznav a.products:active {background-image: url('../images/products_p.gif');}

#horiznav a.news {background-image: url('../images/news.gif');}
#horiznav a.news:hover {background-image: url('../images/news_a.gif');}
#horiznav a.news:active {background-image: url('../images/news_p.gif');}

And I changed my html to look like this:

<div id="horiznav"><a class="home" href="../index.html"></a><a class="products" href="../products.htm"></a><a class="news" href="../news.htm"></a></div>

How do I "USE One background image but put it in two places" if I have a different *.gif for each button and also for each button state? I've been trying to figure it out, and this omitted: a tutorial link sort of gives me an idea, but I still don't get it. Any help would be greatly appreciated! Thank you in advance!

[edited by: SuzyUK at 6:09 pm (utc) on July 17, 2005]
[edit reason] No site specifics, thanks. See TOS #13 [WebmasterWorld.com] [/edit]

SuzyUK

6:49 pm on Jul 17, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi hithere..

How do I "USE One background image but put it in two places" if I have a different *.gif for each button and also for each button state?

You would need to join all your images together to form one image, (e.g. :link states stacked vertically then the :hover states stacked vertically in the same order but joined to the :link state at the right hand side, then :active states stacked the same and again further out to the right.) then you would just be shifting the background on the :hover.

When you actually call a different image, on the differing states as you are doing, this is where the "non preload" flicker comes in, and will likely happen in more browsers than just IE. Once you realise that IE's problem is slightly different (cache problems explained above) this "background shifting" should be the easiest answer all around.

Once you've made the one large image ~ all "buttons" joined together ~ you can then use it as the background to your "horiznav" div as well. And when it comes to each of the different buttons ( <a> links ) you just position the image in order to show the required portion of the image as your "button", inside the 75px x 23px "window" moving it using the background co-ordinates as required, on hover and active.

e.g. your buttons are width: 75px; & height: 23px; so in this example the image would be width: 225px; & height: 69px;


.................¦..................¦...................
....HOME:LINK....¦....HOME:HOVER....¦....HOME:ACTIVE....
.................¦..................¦...................
..PRODUCTS:LINK..¦..PRODUCTS:HOVER..¦..PRODUCTS:ACTIVE..
.................¦..................¦...................
....NEWS:LINK....¦....NEWS:HOVER....¦....NEWS:ACTIVE....
.................¦..................¦...................

i.e.
75px wide x 3 states = 225px
23px high x 3 buttons = 69px

You can show any part of that image inside your 75px x 23px button it is only the background co-ordinates that would change on the <a> itself and its various states.

Then when it's used as the background to your horiznav div as well, only the first 75px width, and full height would be shown as a default. You are really never seeing this background as it is hidden behind the links themselves, except when IE's cache problem causes that momentary flicker, so this image is only there to compensate for IE's hesitation on the links.

Haven't explained that very well, but think of your <a> elements as small windows and image a large image moving around behind it, and remember you can use negative co-ordinate postioning to move image up and across too..

Suzy