Forum Moderators: not2easy

Message Too Old, No Replies

Navigation using images

Is there an efficient, cross-browser solution?

         

zendak

3:23 pm on Feb 2, 2004 (gmt 0)

10+ Year Member



I'd be interested in a clean way of building a graphical menu meeting the following requirements:

- Links in an unordered list, so as to be there as plain HTML text
- Text should then be hidden and replaced by an image replacement technique
- Text should be visible if images are turned off in browser and CSS is still on (therefore standard FIR is not an option)

I've found nothing about this subject in any resources. There must be a way of thus creating a menu in which the links can be displayed graphically, while still being accessible. In most resources and discussions, image replacement seems to center around things like headings etc., not links.

I've tried combining techniques but I stumble across a lot of problems when it comes to have the link clickable. Help and opinions greatly appreciated, I don't know what I'm doing wrong, or maybe it IS impossible?

DrDoc

3:58 pm on Feb 2, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Welcome to Webmaster World!
Let me first ask -- are you going to use a special font on the buttons, or is it just a matter of the background being an image? If so, you can always use just a background image, and text on top.

The techniques normally used with headings apply to links as well. Take a look at this thread [webmasterworld.com] which discusses FIR and its alternatives more in depth.

zendak

6:16 pm on Feb 2, 2004 (gmt 0)

10+ Year Member



To be more specific, here's what I've put together so far.

The actual image replacement is based on David Shea's enhancement [mezzoblue.com] of the "Gilder/Levin" method. (See last example on that page)

Pixy's rollover method [pixy.cz] is used, too


<ul>
<li><a id="item1" href="#"><span></span>Nav Item</a></li>
</ul>

#item1 {
width: 80px;
height: 25px;
position: relative;
display: block;
cursor: pointer;
}

#item1 span {
position: absolute;
height: 100%;
width: 100%;
background: url(item1image.png) no-repeat;
}

#item1 span:hover {
background-position: 100% -25px;
}

ul {
margin: 0;
padding: 0;
}

ul li {
list-style: none;
}

This works perfectly in Mozilla, including the rollover effect. The text is replaced by the image but will be visible when images are turned off. The list is styled to make the list-style disc disappear and move the list items to the left by setting margin/padding to zero. So far, so good. Looks like the menu I want.

For IE I had to specifically define the cursor as "pointer" (the "hand" type) in order to see that type of cursor when moving over the link/menu item. A workaround, but it works. But the rollover effect does not work at all in IE. Now as far as I understand that is because IE only applies the :hover pseudo-class to anchors directly. But in order to get my rollover effect I need to address the span element, not the anchor surrounding it. Is there any way to reconstruct this to make it work. Am I missing something?

Oh, nearly forgot your first question: Yes, the reason for this whole approach is because I want to use graphical typography. Plain text versions with images as background are much simpler and perfectly sufficient for most projects, of course. But due to the font restrictions I'm looking for a way to go beyond that for some more graphically-oriented projects.

PS: Thanks for your welcome :)

DrDoc

7:18 pm on Feb 2, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Instead of doing

#item1 span:hover {}

you should do

#item1:hover span {}

It will still work in Mozilla, just start to work in IE as well :)

zendak

7:52 pm on Feb 2, 2004 (gmt 0)

10+ Year Member



Thanks. Ok, now at least IE6 reacts to the hover state. It doesn't return to the original state though when the mouse pointer leaves the area again. In IE 5 and 5.5 nothing happens at all. Oh well in 2006 we'll see the *new and improved* IE7. Sorry bout the sarcasm but stuff like this is really frustrating. You have wonderful technology at your disposal and the market leading browser lags years behind. Back to the actual topic: I also specifically set

#item span {background-position: top left; ... }

but IE still won't return to the "unhovered" state. Also, the overall performance and appearance in IE is a bit shaky, with an hourglass cursor flickering on every mouseover.

Anything else to polish up the CSS or shall we blame it on the browser?

DrDoc

8:10 pm on Feb 2, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



#item1:link span, #item1:visited span, #item1:active span {
background-position: top left;
...
}

?

zendak

9:45 pm on Feb 2, 2004 (gmt 0)

10+ Year Member



Nope, good idea but doesn't help the IE issue.

Wonderful in Mozilla, Safari, Konqueror and Opera.

DrDoc

11:05 pm on Feb 2, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Well, the only thing I can think of then is to do something like this:

.spanout {
background-position: 0 0;
}
.spanover {
background-position: 100% -25px;
}

<span onmouseover="this.className='spanover'" onmouseout="this.className='spanout'"></span>

I tried all sorts of things, but it seems like IE would never go back to the previous state.

zendak

10:37 pm on Feb 4, 2004 (gmt 0)

10+ Year Member



Yes thank you, that works..

Will use it sparingly. It's really frustrating: Using JavaScript kind of defeats the purpose of CSS as an independent styling system. I've even thought of doing a PHP or JavaScript browser sniff and serving whole different markup blocks based on the results.. But that would take us back to 1999 again.

I've tried many variations to solve above problem, guess we'll have to live with IE's limits for a while still to come :(. If anyone has any more ideas/opinions though, I'd be happy to hear them. Thanks again DrDoc

mep00

1:47 am on Feb 5, 2004 (gmt 0)

10+ Year Member



If I understand correctly, the problem is with the Pixy method. What about using js to preload two images and not use Pixy's method?

SuzyUK

10:19 am on Feb 5, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi zendak..

a revised, revised IR .. if this works what'll we call this one ;)

try this:

/* css */
#header {
width: 329px;
height: 25px;
}

#header a {
background: url(sample-rollover.gif) no-repeat 0 0;
display: block;
width: 100%;
height: 100%;
}

#header a:hover{
background: url(sample-rollover.gif) no-repeat 0 -25px;
}

#header a span {
position: absolute;
z-index: -1;
}

</style>
</head>
<body>
<h6 id="header"><a href="/" title="Revised Image Replacement"><span>Revised Image Replacement</span></a></h6>

then put the whole text in the span, you're then accessing the link block and the span text is z-indexed behind the whole lot.. it's still visible when images/css are off.. it'll have the same issue as Dave S's revision.. so title text for tooltip is added and transparent images can't be used .. but you knew that anyway :)

let us know how it does in tests..
I tested IE6, NN7, OP7

Suzy

ooops sorry I tested with the mezzoblue code.. hope it works for lists too.. can't see for sneezing :(

zendak

2:05 pm on Feb 6, 2004 (gmt 0)

10+ Year Member




If I understand correctly, the problem is with the Pixy method. What about using js to preload two images and not use Pixy's method?

Hi, mep00 - I tried that: Using a different bg image for the hover state (preloaded via js) instead of Pixy's background-position shifting method. Unfortunately, still the same issue with IE not returning to normal state.

SuzyUK: Your "revised, revised IR" works really well :) Solves all the previous issues, tested in Win/IE 5 and 6. Strangely, IE5 doesn't show the little hourglass cursor flicker which IE6 does. You used h6 but it also works with lists. I applied the id to the list items instead of the h6. The rollover's based on Pixy's method which does work here, in my example a PNG image of 80 x 50 each per menu item:


<ul>
<li id="home"><a href="home.html" title="Home Page"><span>Home</span></a></li>
<li id="about"><a href="about.html" title="About This Site"><span>About</span></a></li>
</ul>

#home, #about {
width: 80px;
height: 25px;
}

#home a {
display: block;
width: 100%;
height: 100%;
background-image: url(home.png);
background-repeat: no-repeat;
background-position: top left;
}

#about a {
display: block;
width: 100%;
height: 100%;
background-image: url(about.png);
background-repeat: no-repeat;
background-position: top left;
}

#home a:hover, #about a:hover {
background-position: 0 -25px;
}

#home a span, #about a span {
position: absolute;
z-index: -1;
}

Almost perfect except that IE puts a gap of about 2px vertically between the list items. I tried applying margins, padding and even borders of zero to the various style rules but it won't disappear. If that could get resolved somehow it would be perfect.

DrDoc

3:30 pm on Feb 6, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



except that IE puts a gap of about 2px vertically between the list items

Remove the line break between your list items:

...</li><li>...
instead of
...</li>
<li>...

zendak

3:54 pm on Feb 6, 2004 (gmt 0)

10+ Year Member



Nope, doesn't change anything. I'd actually tried that before as I wanted to be sure there are no white-space or line-break issues.

Hmm..maybe it's just me. Does it work for you?

mep00

5:29 pm on Feb 7, 2004 (gmt 0)

10+ Year Member



except that IE puts a gap of about 2px

It could be a margin and/or padding, but most likly margin.
Maybe try:

li {
margin : 0;
}

SuzyUK

7:19 pm on Feb 7, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



dang... and I hoped you wouldn't notice! ;)

yes this "whitespace in lists" gap is annoying and there are various ways to "fix" it

  • the broken <li>
  • removing whitespace in the HTML
  • leaving a space before the </a>..
  • add a <br /> before the </a>

    the last option here does work in this case but to aviod extra HTML I think that float: left; on the <li> should fix it..

    but it depends wether it honours any left margin of the <ul> element try it and see... let us know..

    Suzy

  • zendak

    10:59 am on Feb 9, 2004 (gmt 0)

    10+ Year Member



    Thanks..inserting a <br /> before the closing anchor tag works best in IE. Bloats the html a bit but I think that's acceptable as long as CSS3 isn't supported yet.
    li {float: left;} causes the items to line up horizontally. There are no gaps in that version, interesting.

    Another issue: When image display is deactivated in browsers, the text is invisible due to the z-index of -1. Part of my original intention was to let the text links remain when images are switched off as actually quite a few people do this while surfing or use text-only browsers. Is there a way to set the stacking value of the background images higher than that of the text so that the text will have, say 0 or 1 and the bg-images 2 and above?

    SuzyUK

    1:06 pm on Feb 9, 2004 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    li {float: left;} causes the items to line up horizontally. There are no gaps in that version, interesting.

    Yes but then if you set the <a> elements to display: block; with the same width/height as the <li> it will stack again ;)... no gaps

    >>z-index
    I presume it's stacking behind the <body> element .... if you have a background colour set on the body then it'll go behind that... but i haven't sen the rest of you page code...

    I tested just setting the background color on the <html> element and then setting <body> to transparent the text then became visible..

    however yes you could tweak the stacking order higher if you need to..

    just set
    position; relative;
    z-index: 50; (anything high will do)

    on the <ul> itself

    the the -1 setting of the <li> text will take it back to 49 ~ hopefully miles "above" any body or other container elements background coloring..

    Suzy

    zendak

    7:29 pm on Feb 9, 2004 (gmt 0)

    10+ Year Member



    The gaps are no more :) I also found this: [phonophunk.phreakin.com...]

    I'm using a background image so I applied the high z-index and a display: relative on the ul to hide the text. Thanks again Suzy, works nicely. The text now remains visible when images are turned off, as it lies above the background colour and image of the body.

    But it would be too good to be true if IE wouldn't misbehave yet again, wouldn't it? Upon loading the page, IE shows a bit of the link text sticking out from underneath it's background image (the background image that we placed in the foreground - to achieve the graphical menu item effect). When you move the mouse over it, it magically disappears and everything is perfect. I will experiment/investigate and report should I find something out about this...
    For those who'd like to witness this amazing phenomenon :) too, reconstruct your own test case based on the code in this thread and please tell us what you find.

    Yet again, everything's as intended in Mozilla and Opera.

    zendak

    1:52 pm on Feb 11, 2004 (gmt 0)

    10+ Year Member



    I've spent some time now trying to figure out the reasons for IE's behaviour but it remains a mystery to me.

    Quick summary:

    • We have an unordered list, the list items consisting of text links, each with their own background image
    • Using z-index, we rearrange the stacking order so the background images actually appear on top of the text links, thus creating the graphic menu I am trying to achieve
    • The background images can be "rolled over" using Pixy's method of shifting background-position
    • Works fine in Mozilla, Opera and Konqueror

    Problem: IE doesn't align the text behind the images vertically upon loading the page. The various text links sit on top of each other, totally unreadable, in the top left corner of the <ul>. Additionally, they show through underneath the top image. Ugly. IE6 corrects this when the mouse pointer moves over the <li> items - the text items align vertically to their intended position "underneath" their respective images. IE5 does this to a lesser extent: The first text remains.
    This is NOT pretty and makes the page practically overconfusing and unusable to the audience in IE.

    If this sounds unclear let me know and I'll put an example online. Any ideas would be immensely appreciated.