I'm trying to build a page to display some members of a club. What I'm trying to achieve is very close to what I've managed to get already, but not quite right, and there might be a better way to do it. Attached is an image of what I have already.
A description of what I'm trying to achieve:
-
*A greyscale member image 70px x 70px.
*Name and title without underline.
*On mouse over the image swaps to a colour one and the text becomes underlined.
*All of this is centered.
*The text can span up to 90px wide.
*A gap of about 3px between the text and image.
What I've got - All of the above, the problem is the way I've done it means the when you mouse over the image the text doesn't underline and when over the text the image doesn't swap.
The way it works is the greyscale and colour image is in the same file to save on server requests and so background-position is used in the css. An empty anchor is created, the background image is set for that anchor, and padding is used to get it to expand to the right size. The text is in a separate anchor (couldn't get it working otherwise).
Have I missed a much simpler way to achieve the same thing?
To see it in action: http://www.dur.ac.uk/n.r.brook/bcbc/?p=execmem
HTML
<div id="ex-images"> <ul> <li id="ex-webmaster" class="ex-exmem"><a class="ex-exim" href="#"></a><a class="ex-exname" href="#">Nick Brook<br />Webmaster</a></li> <li id="ex-novice" class="ex-exmem"><a class="ex-exim" href="#"></a><a class="ex-exname" href="#">Katie Brockington<br />Novice Development Officer</a></li> </ul> </div>
CSS
#ex-images { margin: 0 auto; } #ex-images li { display: inline-block; margin: 2px; width: 90px; } .ex-exmem { text-align: center; text-decoration: none; vertical-align: top; font-size: 8pt; line-height: 1.2em; } a.ex-exname { vertical-align: bottom; text-decoration: none; } a.ex-exname:hover { text-decoration: underline; } a.ex-exim { position: relative; margin: 0 10px 3px 10px; float: left; padding-left: 70px; padding-top: 70px; background-repeat: no-repeat; background-position: 0 -70px; } a.ex-exim:hover { background-position: 0 0; } #ex-webmaster a.ex-exim { background-image: url(../execmem/img/webmaster.jpg); } #ex-novice a.ex-exim { background-image: url(../execmem/img/novice.jpg); }
Attachment | Size |
---|---|
Picture 2.png | 12.29 KB |
Yes
Hi,
Yes you have missed a simpler way. Put the text and the image within the same list-item (
) and then use li:hover in your css to make the image swap and the text underline.
i.e
li:hover a { background-position:changed; text-decoration:underline }
To do this you may need to make it so that your unordered list is within an id, rather than giving the list items an id of their own.
i.e
#images ul { list-style:none; margin:0; padding:0; } #images ul li { display:inline; padding:3px; margin:0; text-decoration:none; background-position:center left; } #images ul li:hover { text-decoration:underline; background-position:center right }
That will not work in IE6
That will not work in IE6 but you can use
<!--[if lt IE 7]> <script src="http://ie7-js.googlecode.com/svn/version/2.0(beta3)/IE7.js" type="text/javascript"></script> <![endif]-->
to fix this
Thanks for that, I didn't
Thanks for that, I didn't know you could apply hover to list items.
It's getting there now, see it at http://www.dur.ac.uk/n.r.brook/bcbc/?p=execmem
The problem now is the background image is spanning the whole list item (which is 90px wide), while I only want it to be 70px wide so it hides the other state, and it also needs to be center aligned (but you can't use background-position to do this because it's already used otherwise). Any suggestions? I thought about just applying the background image to a span of the right size but I don't know how that would work with hover. I suppose I could do it pretty easy with two image files...
Here is the new HTML:
<div id="ex-images"> <ul> <li id="ex-webmaster" class="ex-exmem" onclick="alert('hello');">Nick Brook<br />Webmaster</li> <li id="ex-novice" class="ex-exmem">Katie Brockington<br />Novice Development Officer</li> </ul> </div>
And CSS (some things like list-style: none; are applied elsewhere in the css):
#ex-images ul { margin: 0; padding: 0; } #ex-images ul li { display: inline-block; vertical-align: top; margin: 0 2px; padding-top: 73px; width: 90px; background-position: top left; background-repeat: no-repeat; font-size: 8pt; line-height: 1.2em; text-align: center; } #ex-images ul li:hover { text-decoration: underline; background-position: top right; cursor: pointer; } #ex-webmaster { background-image: url(../execmem/img/webmaster.jpg); } #ex-novice { background-image: url(../execmem/img/novice.jpg); }
You need to put your text
You need to put your text inside another element, so that you can have the li set to 70px and the text set to 90px
I suggest using a p tag
I've had a go at that, check
I've had a go at that, check the link above again. I set the li to width:70px; and the p (which is inside the li to preserve the mouse over stuff) to width:90px;
The problem is that the li doesn't expand to the width of the text. However if it did, the background of the li would be expanded too, which we don't want. I've tried putting the background image in a span, which makes it look right but makes the span hover and p hover independent, as I had originally.
What might work is if I managed to align the wider p centrally to the li, and the width of the p determined how far the whole thing is from everything else...or can't that work?
Okay sorry I get you now.
Okay sorry I get you now. You want to make the whole li 90 px wide again, put text-align:center on the li element, and then text-align:left on the p element.[img][/img]
I want the text in the p
I want the text in the p aligned centrally, and li has that set already. As you can see the text is 90px wide but the li is not expanding to that because of its own width property, but this means that the text is not centered to the image and it isn't creating space around it so some overlap could occur (with other lis).
This code ought to do
This code ought to do you.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head> <meta name="generator" content= "HTML Tidy for Linux (vers 7 December 2008), see <a href="http://www.w3.org" rel="nofollow">www.w3.org</a>" /> <title></title> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta name="author" content="Gary Turner" /> <style type="text/css"> /*<![CDATA[*/ ul { margin: 0; padding: 0; list-style: none; } li { margin: 1.25em 0; text-align: center; width: 90px; } a { background: lightblue url(bigbg.gif) no-repeat; color: black; display: block; padding-top: 83px; text-decoration: none; } a:hover { text-decoration: underline; } #webmaster { background-position: center -200px; } #webmaster:hover { background-position: center top; } #postmaster { background-position: center -600px; } #postmaster:hover { background-position: center -400px; } #prexy { background-position: center -1000px; } #prexy:hover { background-position: center -800px; } #veep { background-position: center -1400px; } #veep:hover { background-position: center -1200px; } /*]]>*/ </style> </head> <body> <ul> <li><a href="some-bio.html" id="webmaster" name="webmaster">Our webmaster Bob the builder</a></li> <li><a href="some-bio.html" id="postmaster" name="postmaster">Our postmaster</a></li> <li><a href="some-bio.html" id="prexy" name="prexy">Our president</a></li> <li><a href="some-bio.html" id="veep" name="veep">Our vice president</a></li> </ul> </body> </html>

A primary composite and the final image are attached. You'll need to open the images in GIMP, or 'display' to see the transparent part; but you knew that.
cheers,
gary
Attachment | Size |
---|---|
comp1.gif | 803 bytes |
bigbg.gif | 5.64 KB |
Thanks for your suggestion,
Thanks for your suggestion, the problem is the images are in jpg format being photos, and in gif format are about double the size, negating any speed changes saved by putting them in one file I imagine. Your suggestion does work but I could achieve the same thing with individual jpg files. I was hoping for a purely CSS solution, partly as a learning experience, but also to squeeze some more speed out of it (although there is a lot more squeezing to be done elsewhere on my site!).
You could use jpg images,
You could use jpg images, but then you'd have to use your background color in the in the base image, where I used a transparency. You'd have to change the image to change the bg color. For such small images, a palletized gif ought to be fairly small, and hi-rez enough for the purpose.
The speed thingie is for IE only, as shifting the background image does not incur a reload. IE(8, too?) does not handle background image cache well, at all; often reloading from the server. This causes an uncomfortable delay on the change to hover and back. If your users don't mind the delay, separate images are the simplest solution.
I inferred you wanted a css solution, thus my entry. A javascript solution, using foreground images is a possibility, and while likely complex, should be robust.
cheers,
gary
No matter what export
No matter what export settings I use in photoshop save for web the gif always ends up bigger than the jpg. However I might use the background colour in the jpg method.
Using one image as opposed to individual images also saves on server requests, does it not?
Would you say there is no way to do this just in css otherwise?
Success! I determined the
Success!
I determined the main problem was that the width of the text (90px), as it was wider than its container, was not spacing other things around it. I came up with the following hack.
Each member is an li. Inside the li is a div. Inside the div is the paragraph text. The li is set to width:90px; the div is set to width:70px; and contains the background image. The p is set to width:90px; however even though centrally aligned the left edge aligns with the left edge of the div. To correct this I just set margin: 3px auto 0 -10px; to the p.
This works in firefox 3.5, safari 4, IE8, (almost IE7, but I might not try and fix that) and validates to css 2.1.
See it at http://www.dur.ac.uk/n.r.brook/bcbc/?p=execmem
HTML:
<div id="ex-images"> <ul> <li class="ex-li"><div id="ex-webmaster" class="ex-exmem"><p>Nick Brook<br /><strong>Web Developer</strong></p></div></li> <li class="ex-li"><div id="ex-novice" class="ex-exmem"><p>Katie Brockington<br /><strong>Novice Development Officer</strong></p></div></li> </ul> </div>
CSS:
#ex-images ul { margin: 0; padding: 0; } #ex-images ul li { display: inline-block; vertical-align: top; margin: 0 2px; width: 90px; } #ex-images ul li div { margin: 0 auto; width: 70px; padding-top: 73px; background-position: top right; background-repeat: no-repeat; font-size: 8pt; line-height: 1.2em; text-align: center; } #ex-images ul li div:hover { text-decoration: underline; background-position: top left; cursor: pointer; } #ex-images ul li div p { margin: 3px auto 0 -10px; width: 90px; } #ex-webmaster { background-image: url(../execmem/img/webmaster2.jpg); } #ex-novice { background-image: url(../execmem/img/novice.jpg); }
Thanks for your help guys!