12 replies [Last post]
dignick
Offline
Regular
Last seen: 11 years 47 weeks ago
Timezone: GMT+1
Joined: 2009-08-22
Posts: 13
Points: 8

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); }

AttachmentSize
Picture 2.png12.29 KB
ljbailey
ljbailey's picture
Offline
Enthusiast
Scotland
Last seen: 11 years 38 weeks ago
Scotland
Joined: 2009-01-10
Posts: 224
Points: 59

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
    }

    Liam Bailey is director of Galloway Web Services, a Stranraer web design company, sister of SEO copywriting services company Write About Property.

    ljbailey
    ljbailey's picture
    Offline
    Enthusiast
    Scotland
    Last seen: 11 years 38 weeks ago
    Scotland
    Joined: 2009-01-10
    Posts: 224
    Points: 59

    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

    Liam Bailey is director of Galloway Web Services, a Stranraer web design company, sister of SEO copywriting services company Write About Property.

    dignick
    Offline
    Regular
    Last seen: 11 years 47 weeks ago
    Timezone: GMT+1
    Joined: 2009-08-22
    Posts: 13
    Points: 8

    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); }

    ljbailey
    ljbailey's picture
    Offline
    Enthusiast
    Scotland
    Last seen: 11 years 38 weeks ago
    Scotland
    Joined: 2009-01-10
    Posts: 224
    Points: 59

    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

    Liam Bailey is director of Galloway Web Services, a Stranraer web design company, sister of SEO copywriting services company Write About Property.

    dignick
    Offline
    Regular
    Last seen: 11 years 47 weeks ago
    Timezone: GMT+1
    Joined: 2009-08-22
    Posts: 13
    Points: 8

    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?

    ljbailey
    ljbailey's picture
    Offline
    Enthusiast
    Scotland
    Last seen: 11 years 38 weeks ago
    Scotland
    Joined: 2009-01-10
    Posts: 224
    Points: 59

    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]

    Liam Bailey is director of Galloway Web Services, a Stranraer web design company, sister of SEO copywriting services company Write About Property.

    dignick
    Offline
    Regular
    Last seen: 11 years 47 weeks ago
    Timezone: GMT+1
    Joined: 2009-08-22
    Posts: 13
    Points: 8

    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).

    gary.turner
    gary.turner's picture
    Offline
    Moderator
    Dallas
    Last seen: 1 year 22 weeks ago
    Dallas
    Timezone: GMT-6
    Joined: 2004-06-25
    Posts: 9776
    Points: 3858

    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>
    The background image is a single file composited from the individual bits. First, a 90x200px transparent file was made. Then a 70x70px proxy for the portrait was set on top of it with 10px on either side and the top. A gray-scale copy was made and appended, then the four were appended to each other to make the big bg image. It take longer to describe than it does to make it, using ImageMagick from the command line. I have not a clue how you'd do it in PS or GIMP. Smile

    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

    AttachmentSize
    comp1.gif 803 bytes
    bigbg.gif 5.64 KB

    If your web page is as clever as you can make it, it's probably too clever for you to debug or maintain.

    dignick
    Offline
    Regular
    Last seen: 11 years 47 weeks ago
    Timezone: GMT+1
    Joined: 2009-08-22
    Posts: 13
    Points: 8

    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!).

    gary.turner
    gary.turner's picture
    Offline
    Moderator
    Dallas
    Last seen: 1 year 22 weeks ago
    Dallas
    Timezone: GMT-6
    Joined: 2004-06-25
    Posts: 9776
    Points: 3858

    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

    If your web page is as clever as you can make it, it's probably too clever for you to debug or maintain.

    dignick
    Offline
    Regular
    Last seen: 11 years 47 weeks ago
    Timezone: GMT+1
    Joined: 2009-08-22
    Posts: 13
    Points: 8

    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?

    dignick
    Offline
    Regular
    Last seen: 11 years 47 weeks ago
    Timezone: GMT+1
    Joined: 2009-08-22
    Posts: 13
    Points: 8

    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!