So you've put together a fluid, tableless layout, structuring all of your columns using just CSS. You're feeling pretty good about things. Then you add your company's masthead image into one of these "fluid" boxes that grow and shrink as the user's window changes size.
It's then that you notice it.
The image is too wide. As soon as you go below a certain window width, the column the image is in becomes too narrow to fit the image. So your browser grows the containing box to hold that image. Unfortunately, that forces your other (floated) columns to be pushed down in order to make room for the image.
So now what?
Well, you could try to limit how narrow a page gets. As long as your images
stay narrower than the minimum width its containing element will ever be,
you'll never have to worry about this. But how do you do that? CSS
gives us the min-width
property. However IE doesn't recognize
it. Not to fear, we can fake it, using javascript.
Skidoo too
is an example of such an implementation. There's some javascript in there
that will limit the width of the page to 600 pixels. Now I can figure out what
the minimum width an image's containing element will be and alter the image
to fit as needed.
It's a good solution. It works. But what if you don't want to use javascript? Or what if you really want big images anyways? Well there might be another way to go about doing this.
An alternate approach, and quite a handy trick, is to create an DIV
block and use CSS to define its height the same as the image you want to place
in your layout. The width of the DIV
will automatically take up
whatever horizontal space there is.
With your empty DIV
define a background image that won't repeat,
and is positioned in the middle of the block. As the window is sized
and resized, the amount of width that DIV
takes up will change,
all the while displaying as much of your image as can fit inside the available space.
Here's a first example:
That image is 29,999 pixels wide. I don't care how big your monitor is, there's no way your going to fit that entire image onto the screen. But using the method described above, the image is cropped to a size that fits perfectly in the space provided.
The plus side to this is you can use any sized image you want and never worry about your users getting a screwed up interface. And this approach is actually very compatible. I've tested it back to IE 5 and Netscape 6.2 without any problems. (Netscape 4 isn't involved here.)
The downsides are there as well. First, you're creating HTML structure
but not providing any "real" content. We're talking empty DIVs here. It's pure
presentational logic and nothing else. A non-browser parsing your site isn't
going to know there's an image there. The way around this is to include
an IMG
tag inside your (no longer) empty DIV
and
just set the display
property to none.
Another downside is this is all a lot of work for just putting a stupid little image on your website. So I'm trying to bring the difficulty down to a minimum.
So lets look at the HTML
<div style="/*/*/background-image:url(very_wide.gif);" class="rsImage" ><img src="very_wide.gif" width="29999" height="50" alt="" ></div>
Despite how it looks, this is just an IMG
tag wrapped by a DIV
tag. The funny formatting is to keep the HTML readable while not allowing
for any whitespace to appear between any of the tags in this block.
The IMG
tag is there for non-CSS compliant browsers. They will ignore
the inline CSS on the DIV and just display the image as expected. This is why
the width, height and alt attributes are all defined, rather than just ignoring them.
About that inline style. Why am I using an inline style and what is
up with that /*/*/
stuff? Well I'm using an inline style because
if I have more than one of these on my page, and I'm keeping all my CSS in a separate
stylesheet, I'll have to create unique selectors for each image I use this trick on.
That's going to bloat your stylesheet and it means you have to edit both your HTML
and your stylesheet when adding a new image to the page.
The only thing unique about this block from every other HTML block
using this method is the actual image being used. By defining that
as the background image via an inline style, I can keep all the other
CSS needed to implement this in an external stylesheet, in a selector
that can then be reused over and over for every image displayed
in this way. In case you haven't already figured it out, the class
name I'm using to store all this common CSS information is
rsImage
.
Now what about that /*/*/
? That's simply a CSS comment hack
to keep Netscape 4 from parsing the CSS. As of this writing, I cannot
get Netscape 4 to play ball with this approach. But I'm using inline styles
that will be processed by all CSS-knowledgable browsers, including Netscape 4.
But I don't want Netscape 4 to use this CSS. Thus the comment hack.
As an aside here, I want to point out how you could potentially remove
that comment hack and still be friendly to Netscape 4. Keep in mind that
Netscape 4 is going to display the image in that IMG
tag. So if
you have a non-repeating background image aligned the same way the
IMG
element is (left, center, right) you're going to have
one image overlap the other. Since they're the same image, they should overlay
perfectly and the user won't be the wiser to the fact that you've
stacked two images. It could work. But I'm not that bothered by the comment
hack to try this approach. But you're free to give it a shot.
So that's the HTML. What about the CSS?
.rsImage { background-repeat: no-repeat; background-position: 50% 50%; } .rsImage img { width: 0; margin-left: -99999px; padding-left: 1px; }
The first thing you might notice is I don't perform a
display: none
on the image inside the
DIV
. Why is that? I'm after simplifying
this as much as possible when it comes to adding
a new image. One thing I want to eliminate is the need
to specify the width
property within
the inline style. If I keep it to just defining the
background color I can keep things forever simple when it comes
to adding the DIV
/CSS stuff.
By setting the width to 0 and then moving the image
so far off to the left (via negative margins) that it
won't appear on screen I am able to preserve the effect of the
height of the image on its containing DIV
. In other
words, the div.rsImage
block will have whatever
height the image has without me having to specify it via CSS.
0 width should just hide the image completely. However Opera still displays 1px worth of the image. So that's why I had to apply the negative margins. The padding is there because IE will not recognize an element's existence if it has a 0 for one of its two dimensions. So you put all these different ways to hide the image but keep its height together and you've got a very compatible bit of CSS.
The .rsImage
bit itself is very straightforward. It just
sets the background image to appear in the center, middle of the
DIV
element and it says to not repeat that background image.
Both of these values you can go ahead and change it, make copies and rename
them, whatever. For mastheads, I like a centered image. For others, they want
a left or right-aligned image, so go ahead and change the background position.
Including the vertical-centering of the image really isn't necessary since
the DIV
s height and the image height will be the same, but I include
it for completeness.
Here's a couple floated boxes sitting next to each other. You'll see this image approach works just fine.
Try resizing this window a few times just to see this approach in action.
There's some bits to discuss on when to use something like this but I'm not going to cover that here. Instead, give it a try and get a feel for this yourself. You should be able to figure out when you need to use this and when you don't.
Good luck!