A recent web design called for the following:
- the client must be able to upload their own banner images
- the banner image was not square and had a transparfent mask around over it (in Photoshop, the banner image was underneath a clipping mask)
- The design must function in a range of legacy browsers
This presented a major headache. Usually uplaoding a totally square image is easy – a client can do this with ease themselves. However, the client in question has no experience using using Photoshop (and why should they to update their website?) and wouldn’t be able to upload a masked image. Additionally, using some of the new CSS3 image masking properties are out, as I need to support IE6 and above.
So, the solution here is to use a transparent image to overlay the square image – meaning a client can upload a square image and have it show masked on the live website – see the final result of what we’ll be making.
The HTML is quite simple:
<div id="banner_outer"> <div id="banner"> <div class="frame_top"></div> <div class="frame_bottom"></div> <img src="images/banners/splat.jpg" alt="splat" /> </div> </div>
Here, we have a simple wrapping divider to center the banner – “banner_outer” and a second divider to hold the banner – “banner”. There are also two dviders that are absolutely positioned, using a css sprites for the background images. The image is a 24 Bit PNG image – as this gives the smoothest effect for the frame and the underlying images could be photographs.
Remove the two frame dividers you’ll get a a simple box with a square image. However, when you add the two frame dividers you’ll see the image is show framed (one frame at the top, one at the bottom), exactly how an image clip would work in Photoshop. The CSS is very simple, but there is one key here to make your life easier and to ensure cross browser compatibility.
Positioning for Child and Parent Elements
Postion the parent divider to the two frames relatively. Why do this? Well a DOM element positioned relatively, gives you full control of the child DOM elements inside it, using absolute positioning – this was definately one of those ‘a-ha!’ moments for me where everything became clear.
In essence, the latter stops child elements positioned absolutely, from positioning themselves in relation to the body. To see the effect in action, view the demo and use Firebug to disable the ‘position: relative’ on the #banner element – the two frames are positioned absolutely according to the body element and not the #banner element as we want. You could ignore the position relative for the parent item, position the frame divs abolsutely and use margins to move them about – -this will work but you’ll run into issues in IE. I’d highly abvise you stick to the position relative method, as described above.
The frame I’ve chosen is a very subtle curve, but you could use any type of shape the mask the image.
A Note on IE6
As I’m sure many of you have already rightly realised – IE6 does not support transparent PNGs. This is really the only downside to this css based image masking technique. There are an absolute plethora of hacks for this, but I’ll be using the belated IE6 PNG Fix – which adds PNG support to IE6 and below. All that is required is the the following is added the head tag:
The CSS for the example in question is extremely simple – there’s no need for me to explain this. Only difference, is that I’ve added a splash of CSS3 for eye candy.
Happy image masking! 🙂