CSS Sprites is a popular way to reduce image requests to the server and hovering lag to load another background image cased by network latency.
Jenny has also devised a technique for foreground image CSS sprinting by Extending CSS Sprites which in essence bears all the merits of the original CSS Sprites method.
Basic concept
You can view the live demo here.
The HTML:
<div class="sprite earth">
<img src="menu.png" alt="" />
</div>
<div class="sprite ocean">
<img src="menu.png" alt="" />
</div>
<div class="sprite sky">
<img src="menu.png" alt="" />
</div>
The CSS:
.sprite {
position: relative;
width: 106px;
height: 39px;
}
.sprite img {
position: absolute;
top: 0;
}
.sprite.earth img {
left: 0;
clip: rect(0px 106px 39px 0px);
}
.sprite.ocean img {
left: -106px;
clip: rect(0px 212px 39px 106px);
}
.sprite.sky img {
left: -212px;
clip: rect(0px 318px 39px 212px);
}
The essential CSS property here is clip which can only affect absolutely positioned elements, resulting in the extra div wrapper relatively positioned.
The only difference my code has from that of Jenny’s is that I have used positioning (left: xx) on the img element rather than on the wrapper div, because I thought it should be the img that has different clipping and positions every time a new sprite image is created.
Clip is possibly the least used CSS property, it’s like a clipping viewport that can be applied to an element to expose only part of it.
A horizontal menu and a vertical menu with hovering
This is a demonstrative usage of the foreground image css sprites technique on menus, with hover effects. There’s also alive demo available.
The HTML:
<ul class="menu horizontal">
<li class="earth"><a href="#"><img src="menu.png" alt="Earth" title="Earth" /></a></li>
<li class="ocean"><a href="#"><img src="menu.png" alt="Ocean" title="Ocean" /></a></li>
<li class="sky"><a href="#"><img src="menu.png" alt="Sky" title="Sky" /></a></li>
</ul>
<ul class="menu">
<li class="earth"><a href="#"><img src="menu.png" alt="Earth" title="Earth" /></a></li>
<li class="ocean"><a href="#"><img src="menu.png" alt="Ocean" title="Ocean" /></a></li>
<li class="sky"><a href="#"><img src="menu.png" alt="Sky" title="Sky" /></a></li>
</ul>
The CSS:
img {
border:none;
}
.menu {
margin:0;
padding:0;
list-style:none;
}
.menu li {
margin:0 0 10px 0;
padding:0;
}
.menu li a {
position: relative;
display:block;
width: 106px;
height: 39px;
}
.menu li a img {
position: absolute;
top: 0;
}
.menu li a:hover img {
left:0;
}
/* normal state */
.menu li.earth a img {
left: 0;
clip: rect(0px 106px 39px 0px);
}
.menu li.ocean a img {
left: -106px;
clip: rect(0px 212px 39px 106px);
}
.menu li.sky a img {
left: -212px;
clip: rect(0px 318px 39px 212px);
}
/* hover state */
.menu li.earth a:hover img {
top:-39px;
clip: rect(39px 106px 78px 0px);
}
.menu li.ocean a:hover img {
top:-39px;
clip: rect(39px 212px 78px 106px);
}
.menu li.sky a:hover img {
top:-39px;
clip: rect(39px 318px 78px 212px);
}
/* specific styles for horizontal menu */
.horizontal {
overflow:hidden;
height:1%;
}
.horizontal li {
float:left;
display:inline;
margin:0 10px 0 0;
}
However as you can see from the demo, the hovering doesn’t work in IE and Opera. Currently I don’t know if there’s a workaround for this. Maybe clip just doesn’t work with :hover?
you can’t use “:hover something” in IE6, its doesn’t understand the selector that comes after the :hover… this is why it doesn’t work on Ie6 dude.
thx for your help.. 😀
np 😉
The advantage of the img tag in this case over a empty DIV container with a background image should be that for your agents which cant load the image for some reason, the “alt” tag kicks in and is displayed.
However, in your demo if you mess up the src attribute to launch the behavior where browsers use the text in the alt attribute, it is not displayed making it equal to the standard sprite technique.
You are a fiend!