Any size Image Frame with CSS

Tuesday, November 6th, 2007
An image frame created with custom graphics that can be applied to any size image

Building the Wild Zoofari website we wanted to have some sort of frame around the images on the site. Normally that would mean going into photoshop and adding a frame around each image. This seemed very troublesome and inefficient to me, so I starting thinking about different methods that could be used to achieve the result. In the end I decided to add the image frame using CSS and you can see the result on the image to the left.

CSS Image Frame Advantages

  • The content owners don’t need to know how to add borders to the images.
  • Having to manually add borders onto each individual image increases the time needed for posting new content.
  • The images are used at different sizes on different parts of the site so resizing the larger image with the borders already applied would result in different sized border widths.
  • If the site design changes all the images won’t need to be redone to match the new design.

Making Your Own Image Borders

The Images

The first thing you’ll need are the border images. You’ll need two images one for the top and bottom border and one for the left and right border. Depending on the design your could also use four different images one for each border side, but for this example we’ll stick with two. Here are the two images used for the above picture. These images either need to be taller/wider then the largest image you’ll be displaying or be able to repeat and still fit together.

The HTML

Now that we have the border images we need to setup the html code for the images.

<div class="img-wrap">
<div class="img-container">
<img src="http://static.punteney.com/imgs/Golden_Eagle2_.jpg" width="256" height="331" /><div class="img-top"></div><div class="img-bottom"></div>
</div>
</div>
It’s fairly straight forward html the divs are there to hold the various borders. An important item to notice are the extra divs after the img tag. Those divs have to be on the same line as the image tag or else IE 6 adds an extra space below the image causing an ugly gap before the border. The css for each item is shown below.

The CSS

The first part of the html is the div with the “img-wrap” class the css that is applied:

div.img-wrap { 
    /* Needed to keep the image from being set to float left in ie 7, but doesn't work for ie 6*/
    position: relative;
    /* This triggers the layout feature to contain the floated divs for the top and bottom borders */ 
    overflow: hidden; 
}
You shouldn’t need to change either of those settings, but you can add additional ones for other styling such as setting the image to float left or right or adding margins in.

The next part is the div with the class of “img-container” and it’s css:

div.img-container {
    /* Keep the floated divs/image contained within */
    position: relative;
    float: left;
    overflow: hidden;
    /* this is the left side vertical border
       Set the color to transparent then include the image and have 
       it repeat vertically */
    background: transparent url(/images/pic_frame_vertical.jpg) repeat-y;
}
The background image will need to be changed to reflect the image you want to use for your left vertical border.

Then comes the actual image:

div.img-container img {
     /* Setting the padding equal to the border width for all sides 
        so the borders can be seen */
    padding: 6px;
    /* this is the right side vertical border
       Set the color to transparent then include the image and have 
       it repeat vertically and line up on the right side of the image */
    background: transparent url(/images/pic_frame_vertical.jpg) repeat-y right;
}
The padding should be set to whatever width the borders are going to be. If you have different sized borders on different sides you can specify the padding for each side individually. Then change the background image to be the image you want to use for your right side vertical border.

Finally the top and bottom border divs:

div.img-container div.img-top {
    /* Positioning the top border to start at the top left corner of
       the img-container div */
    position: absolute;
    left: 0;
    top: 0;
    /* Set the height equal to the height of the border */
    height: 6px;
    width: 100%;
     /* this is the top horizontal border
       Set the color to transparent then include the image and have 
       it repeat horizontally */
    background: transparent url(/images/pic_frame_horizontal.jpg) repeat-x;
}
div.img-container div.img-bottom {
    /* Positioning the bottom border to start at the bottom left corner of
       the img-container div */    
    position: absolute;
    left: 0;
    bottom: 0;
    /* Set the height equal to the height of the border */
    height: 6px; 
    width: 100%;
    /* this is the bottom horizontal border
       Set the color to transparent then include the image and have 
       it repeat horizontally positioned at the bottom of the div 
       (bottom position needed for ie 6) */
    background: transparent url(/images/pic_frame_horizontal.jpg) bottom repeat-x; 
}
These divs are just empty divs that provide a spot for their respective backgrounds to show. The styles in each that you would need to change are the “height” setting to what the border height should be and the “background” specifying the image to use for the border.

You can view the complete CSS file here. That’s all there is to it.

Just to prove it does work for any size of image here is a sample page with a couple images using the above code.

Issues and Next Steps

There are a few issues with using this method for doing image boarders though.

  • In ie 6 the image and borders always floats to whichever side the image is set to float to in the css. If you don’t want the images floated in your design and need it to work in ie 6 then this solution won’t work for you. If you know the width of the image you can rework it with absolute positions and specifying the width of the for the img-wrap div.
  • Extra code in the page. Using this method it requires 4 extra div’s on the page for each image you want framed which pollutes the page code. While this isn’t ideal the flexibility it gives is worth it in my opinion
  • Extra time and requests are needed to get the background images. After the first load though they should be cached so the load time should be minimal.
To minimize some of these issues I’ve developed a Javascript version that will add all the needed elements to make the frame automatically for the images. Once I finish cleaning it up and doing the write-up for it I’ll add a post on how to use it.

If you use this technique somewhere or if you encounter any bugs or anything leave a comment below.

This method has been tested in IE 6 and 7, Firefox 2, Opera 9 and Safari.

Update

Here is a link to the Javascript version of the any size image frames.

Read other entries about CSS
Written by James Punteney
blog comments powered by Disqus