
Trouble is, I'd always found it impossible to do without using Javascript or really nasty tricks.
Now of course if you know your image dimensions it's easy, but I never liked the idea of storing that info in the database just to make this layout possible. I also don't like the idea of reading the dimensions in at runtime, because it's a horrible idea.
Here's a list of the constraints I have always had in trying to implement this:
- Don't know the image dimensions
- Images in the "set" are different proportions
- Need labels with each image
- Images should be clickable
- Image should automatically wrap inside of the containing block
- We do know that all images "fit in a box" of a fixed dimension
Today I was implementing yet another site with this layout need, and decided to try to figure it out again. Thanks to this forum thread I was turned on to the idea of doing this by making the image a background image and using background-position: center to get the job done.
So, how'd I do it?
<div id="thumbBox">
<div class="thumbUnit">
<div class="thumbContainer" style="background-image: url(thumb1.jpg);">
<a class="thumbLinkOverlay" href="/thumb1-link"> </a>
</div>
<div class="thumbLabel"><div>Label 1</div></div>
</div>
<div class="thumbUnit">
<div class="thumbContainer" style="background-image: url(thumb2.jpg);">
<a class="thumbLinkOverlay" href="/thumb2-link"> </a>
</div>
<div class="thumbLabel"><div>Label 2</div></div>
</div>
</div>
The "thumbBox" is the containing block for the image set. Each "image" has an area blocked out for it by the "thumbUnit" div, which is given a FIXED width/height that is big enough to hold the largest image.
The "thumbContainer" has the desired image as a background image, since "background-position: center" works, whereas "vertical-align: middle" never does...
Since background images aren't clickable, we use absolute positioning to create a link tag that covers the entire "thumbUnit" area, making our image clickable.
The "thumbLabel" allows us to have a centered caption.
What's also great about this setup is that we can easily make the image set sortable with Scriptaculous, and make the image labels edit-in-place. I'll cover that in future post.
Downsides
There are a couple of downsides to this approach:
- Images won't print in some browsers
- Not all that semantic
However, in my case I am usually using this in an admin area where neither of these things matter. It might be possible to specify a print media css file to override the printing problem, but there isn't much you can do about the semantic problem.
If you really want good semantic markup for this situation, I suppose the best way is to just set up a Javascript function to "center" all of the images once loaded.
Below are the style definitions used with the markup.
<style type="text/css">
#thumbBox {
float: left;
width: 500px;
}
.thumbUnit {
float: left;
position: relative;
margin: 5px;
}
.thumbContainer {
width: 100px;
height: 75px;
background-repeat: no-repeat;
background-position: center;
position: relative;
}
.thumbLinkOverlay {
width: 100px;
height: 75px;
position: absolute;
top: 0;
left: 0;
}
.thumbLabel {
height: 1em;
text-align: center;
}
</style>
5 comments: