Expanding a DIV to Size of 'background-image'

I struggled with this for a bit yesterday and found naught but forums telling me 'it can't be done,' or 'why are you doing that, it's stupid,' so I thought I'd share the solution I developed.

The Problem


Here's the scenario: You have a DIV that will contain some text. You have different background-images that you want displayed under the text depending on which page is showing. But the background images are of varying sizes.

What you want, therefore, is a way to expand your DIV to the dimensions of whatever background-image you happen to stick inside it, without having to explicitly declare width and height values, either at your style sheet or in-line.

...and now you're off the rails.

One could surely pose a number of "why not" scenarios, such as: 'Why not just declare the width and height in-line?' or 'Why not just make the text part of the images?' Or one could pontificate upon the myriad of client and server-side solutions for querying the image size and declaring the DIV dimensions equal by script. But instead, let's just assume that we are coders and geeks, and that if there is a simpler solution requiring less explicit declaration and more uniform code distribution, then that elegance of design is our tacit desire and reward.

Solving


First off we must accept and acknowledge the limitations before us. The 'background-image' declaration does not care for width and height. It will fill a DIV with the image you choose, but it cannot under any circumstances be used to alter the boundaries of the DIV. Give that up right now!

Besides which, a 'background-image' declaration here would have to be placed in-line to meet our need of changing it across different pages, and I think it a best-practice to avoid in-line styles wherever possible, favoring HTML tags for dynamic content.

The solution, therefore, must be implemented from within the DIV. Anything placed inside a DIV of undeclared width and height will expand that DIV to fit. So in place of a 'background-image' declaration, we will set an <img> tag inside the DIV. The IMG's dimensions will be determined upon page load and the DIV will expand to match.

<div id="my_div">
<img src="images/bg1.gif">
</div>


Now comes the text we want displayed atop our IMG. Just shoehorn it in there with a <p> tag. We'll make it work in a minute.

<div id="my_div">
<p>Contact Us!</p>
<img src="images/bg1.gif">
</div>


So now we have a DIV containing two blocks: P and IMG. What we want is for the P tag to overlay the IMG tag, creating the effect of IMG as a background. We accomplish this by use of negative margins and 'z-index.'

First off, the P tag has its own vertical margins which we'll want to zero so we can have a simple text-block with no extraneous white-space to work with. As for making our IMG into a background, we can force the P tag to overlap IMG's boundaries by giving IMG a negative 'margin-top.'

#my_div p { margin: 0 }
#my_div img { margin-top: -80px }


If you looked now, you would find that the text of the P tag has more or less disappeared behind your IMG. Here the IMG tag has a higher natural z-index than the text, meaning it is being drawn after, or overtop of P. We can change that by giving the IMG a negative z-index, which places it dimensionally beneath P. Note here that when you set a 'z-index' you must also make the 'position' of the element explicit, or it will not take effect.

#my_div p { margin: 0 }
#my_div img {
margin-top: -80px;
position: relative;
z-index: -1;
}


Finally your P tag should be sitting proudly atop your IMG which has effectively become a background-image. Huzzah! Full code follows...

The Solution



<head>
<style type="text/css">
#my_div p { margin: 0 }
#my_div img {
margin-top: -80px;
position: relative;
z-index: -1;
}
</style>
</head>

<body>
<div id="my_div">
<p>Contact Us!</p>
<img src="images/bg1.gif">
</div>
</body>


Beautiful isn't it? Just four lines of CSS and you can now switch out one background for another of an entirely different width - and even a different height if the design is right - without so much as a whisper regarding those properties. All you declare explicitly is how far down to drop your text over the image. "Can't be done," my eye!

There are some pitfalls to watch out for when implementing this method. For instance, it might seem just as easy to make the 'margin-bottom' of P a negative instead of the 'margin-top' of IMG, but if you do it this way Internet Explorer, in particular, just might chop off the vertical edges of your IMG if P's block fails to fill the DIV out to the full height of IMG. This can be countered by augmenting line-height, but then you're fighting battles you don't have to. Yeah, I may have learned that one the hard way.

There you go: Dynamically expanding a DIV to the size of a background image. Tada!

0 comments:

Post a Comment