Forum Moderators: not2easy

Message Too Old, No Replies

Making horizontal navigation look like tabs

Images with clipped or rounded corners

         

coopster

11:57 pm on Mar 6, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



I'm struggling a bit with a concept and figured somebody must have hit this before hopefully and if not, well maybe you can show me the error in my ways.

I want to have a horizontal navigation layout and the links to look like tabs with either nicely rounded corners or a clipped corner ... doesn't matter, it's going to take images with artwork on both sides of the linked item to get it proper, if I understand the possibilities correctly. I'll try to offer a visual with the following code:

<div id="mainnav"> 
<ul>
<li><a href="#">a</a></li>
<li><a href="#">b c d e f g h</a></li>
<li><a class="current">i j k</a></li>
<li><a href="#">l m n o p q r</a></li>
<li><a href="#">s t u</a></li>
<li><a href="#">v w x y z</a></li>
</ul>
</div>

And the layout might look something along these lines ...
____   _______________   _______   _______________   _______   ___________ 
/ A \ / B C D E F G H \ / I J K \ / L M N O P Q R \ / S T U \ / V W X Y Z \
---------------------------------------------------------------------------

The class "current" is going to represent the currently loaded browser page, therefore no
href
attribute and the tab will appear as a different color than the rest of the tabs' backgrounds (same as the hover color will be). There are two images involved --
tab-left.gif = width 12  x height 56 pixels 
tab-right.gif = width 200 x height 56 pixels

Both images are split 50/50 horizontally with a slightly darker-shaded color up top, the lighter color version below, both of them have a linear gradient. The background on the elements are the same color as the top half of the images. When the user hovers over a link the background image for that link will *slide up* making the background change to the lighter color.

css

#mainnav { 
margin: 20px;
}
#mainnav ul {
margin: 0;
padding: 0;
list-style: none;
}
#mainnav li {
float: left;
margin: 0 3px 0 0;
background: #99CCCC url(tab-left.gif) no-repeat left top;
padding: 0 0 0 9px;
white-space: nowrap;
}
#mainnav a {
float: left;
display: block;
width: .1em;
height: 15px;
background: #99CCCC url(tab-right.gif) no-repeat right top;
padding: 8px 10px 4px 1px;
text-decoration: none;
font: 10px "Trebuchet MS", Verdana, Helvetica, sans-serif;
text-transform: uppercase;
letter-spacing: 1px;
color: #066;
}
#mainnav > ul a {width: auto;}
/* Commented Backslash Hack hides rule from IE5-Mac \*/
#mainnav a {float: none;}
/* End IE5-Mac hack */
#mainnav .current {
background-position: 100% -28px;
color: #033;
cursor: default;
}
#mainnav li:hover, #mainnav li:hover a {
background-position: 0% -28px;
color: #033;
}
/* IE fix */
* html #mainnav li a:hover{
background-position: 0% -28px;
color: #033;
}
* html #mainnav li a:hover {
background-position: 100% -28px;
}

Issues:
  1. The left 12 pixels of my "current" tab is the incorrect color
  2. IE only: In addition to the first issue, any hover action leaves the left 12 pixels of the left of the tab being hovered the incorrect color

SuzyUK

11:57 am on Mar 7, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



1. The left 12 pixels of my "current" tab is the incorrect color
2. IE only: In addition to the first issue, any hover action leaves the left 12 pixels of the left of the tab being hovered the incorrect color

coopster, the left part of the tab is being controlled by li:hover ( :hover on non- <a> element) which IE does not support yet, you would need a script to make this work, take a look at whatever:hover [xs4all.nl] for a "plug and play" option

or if you do not want scripts you could nest a span inside the links then use

a:hover {}
and
a:hover span {}
for the two sides of the tab.

The "sticking" on the wrong colour in IE is likely a layout/display error, correcting the first part of the problem might fix the second, if not try adding

a {zoom:1;}
to test this theory

here's a sample of doing it using nested spans and using ALA's sliding door tabs, {left image = 9px wide, right image = 400px wide with 9px curved edge)

HTL:
<div id="mainnav">
<ul>
<li><a href="#"><span>Home</span></a></li>
<li><a class="current"><span>News</span></a></li>
<li><a href="#"><span>Products</span></a></li>
<li><a href="#"><span>About</span></a></li>
<li><a href="#"><span>Contact</span></a></li>
</ul>
</div>

CSS:
#mainnav {
margin: 20px;
}
#mainnav ul {
margin: 0;
padding: 0;
list-style: none;
}

#mainnav li {
float: left;
margin: 0 3px 0 0;
white-space: nowrap;
font: 10px "Trebuchet MS", Verdana, Helvetica, sans-serif;
text-transform: uppercase;
letter-spacing: 1px;
}

#mainnav a {
float: left;
padding: 0 0 0 9px; /* left padding for left curve width */
background: #fff url(left.gif) no-repeat 0% 0%;
text-decoration: none;
color: #000;
}

/* a hover and current a rules are the same */
#mainnav a:hover, #mainnav a.current {
background-position: 0 -28px;
color: #f00;
}

/* put right side of image in span so it can be moved by the a:hover */
#mainnav a span {
float: left;
background: #fff url(right.gif) no-repeat 100% 0;
padding: 8px 9px 4px 0; /* top/bottom padding as required - right padding width of right "curve" */
}

/* a:hover span and a.current span are the same except change the cursor for the current tab if required */
#mainnav a:hover span, #mainnav a.current span {
background-position: 100% -28px;
cursor: pointer;
}
/* override / change the cursor for current tab */
#mainnav a.current:hover span {cursor: default;}

my colors won't match yours ~ and this code might still cause IE/Mac a problem as I've removed all "fixes". They are not necessary for IE using this method but Floats without widths do cause IE/Mac a problem. AFAIK using display: inline-block; instead of floats for IE Mac should fix it if required.

If you choose to use a script to get IE to support :hover on the li element then you won't need the span but the logic should be fairly similar ~ replace a:hover with li:hover and a:hover span with a:hover and also in this case you might be better to put the "current" class onto the <li> instead of the <a> so you can target

li.current:hover

as long as you have two hoverable elements to work with..

Suzy

Fotiman

3:02 pm on Mar 7, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The website "A List Apart" has 2 articles that discuss how to created these tabbed interfaces. The articles are called "Sliding Doors of CSS" and "Sliding Doors of CSS, Part II". You might take a look at those (I'd post the URL but it's not allowed).

coopster

3:15 pm on Mar 7, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



the left part of the tab is being controlled by li:hover ( :hover on non- <a> element) which IE does not support yet

The root of my problem. Understood and thanks for that. I read the specs [w3.org] and the wording regarding "

CSS doesn't define which elements may be in the above states, or how [...] different devices and UAs may have different ways of pointing to, or activating elements
" had me pondering whether or not I was pushing too far with MSIE.

I thought of the <span> option and realized that may be the route to take if the theory above was confirmed -- I knew I would need an element on both sides because of this rounded-corner-tabbed-image look that was desired.

sliding door tabs

hehe, didn't know there was a pet name for them ;-)

Thanks for the cleanup as well. I was trying all sorts of things to try and get this to work correctly. I found but one issue, and once again it was MSIE-specific. MSIE would not change the cursor correctly over the currently active link, it would on the <a> portion of the display, but move over the <span> and the old "hand" came back. I had to separate the combined ruleset to get the hover working correctly. I don't know why, but MSIE choked on the combo with the override unless I separated the rules:

/* a:hover span and a.current span are the same except change the cursor for the current tab if required */ 
#mainnav a:hover span, #mainnav a.current span {
background-position: 100% -28px;
}
/* override / change the cursor for current tab */
#mainnav a:hover span {
cursor: pointer;
}
#mainnav a.current span {
cursor: default;
}

As always, you are a wealth of knowledge and you explain things so very well. My deepest gratitude to you and the others that contribute to the WebmasterWorld CSS Forum -- coopster

coopster

3:27 pm on Mar 7, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



Yeah, I went and read the tutorials after SuzyUK's post, but thanks Fotiman. I found another tutorial that I was learning from but there were pieces of it that I didn't like. Specifically that the entire <a> element was not giving the cursor change on hover effect that I desired and I also did not want the "current" class on the <li> element (I am doing some server-side magic to automatically change the href attribute on the <a> element to the class="current" instead).

JAB Creations

7:01 pm on Mar 7, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Nice post Suzy!

Coopster, don't forget to use indexed color via GIFs to keep the file size down.

When CSS3 spec becomes official this is what you'll use instead...
[w3.org...]

But until we can use multiple background images per element then we'll all have to rely on well thought out compromises.

Though...is there a way to use vector graphics to render the tabs? I know Firefox 1.5 now supports SVG but not sure if this would be applicable...especially if you're trying to support IE.

John