Saturday, March 21, 2009

How To Make A Polaroid Photo Style Background For Your Images With CSS Without Using Background Images

I wanted to decorate the photos on my blog with a Polaroid-style look. If you Google for 'polaroid css', you'll get quite a few results. But I didn't quite find what I was looking for, especially without using a background image like in this post or this post. The problems with this method are
  • If the end user turns off images, the effect is lost
  • The client would have to download yet another image (however light)
  • The most importantly, this method will not scale! You'd have to either crop your images to fit the fixed size or have multiple sizes of the polaroid backgrounds for different sized pics.
  • If the background image is a PNG (which let you have gradiant transparency as opposed to GIFs which support transparency for any one colour), then you'll run into IE6's notorious lack of support

So the best way out is to use CSS. Here's what I've come up with. The CSS rules are:
.polaroid-container {
 position: relative;
 /* for being able to use absolute positioning for the 'tape' images, explained below */
 float: left;
 /* with a float we can a)embed the polaroid photo within text and have it wrap around and b) we don't need to specify a width/height */
 margin: 20px;
 /* we want to put some space between the polaroid photo and the surrounding content */
}

.polaroid-shadow {
 background-color: #CCCCCC;
 /* a light gray color, for the pretend shadow */
 text-align: center; /* aligns the text and image to the center */
}

.polaroid {
 background-color: #FDFDFD; /* a light gray background */
 border: 1px solid #999999; /* a thin border in darker gray */
 position: relative;
 /* this allows us to move the the polaroid div without removing it from the flow of the page i.e. we can offset it and show the 'shadow' from below */
 left: -3px; /* we move the polaroid to the left... */
 top: -3px; /* ...and up */
}

.polaroid-content-container {
 margin: 15px 15px 20px 15px;
 /* a little extra margin at the bottom */
}

.polaroid-pic {
 display: block;
 /* this prevents the caption from sliding in next to the image,
since both are inline elements by default */
 border: 1px solid #CCCCCC;
 /* give the image a thin, slightly gray border */
 border-top: 1px solid #999999;
 /* then we override the border for the top and right... */
 border-right: 1px solid #999999;
 /* ...for a very subtle film-embedded-in-the-paper effect */
 margin-bottom: 15px;
 /* we need some gap betwen the image and caption, which also serves to increase the bottom portion of the polaroid, adding to the effect */
}

.polaroid-caption {
 color: #777777; /* dark gray for the caption text... */
 font-size: 0.75em;
 /* ...which will be 75% of the enclosing container's font... */
 font-style: italic; /* ...and will be italicised */
}

The HTML for the image should be:

<div class="polaroid-container">
    <div class="polaroid-shadow">
        <div class="polaroid">
            <div class="polaroid-content-container">
                <img class="polaroid-pic" src="your-image.jpg" />
                <span class="polaroid-caption" />
            </div>
        </div>
    </div>
</div>


You should see something that looks like this:
Sample Screenshot Of Polaroid-style Background

BONUS! - Sticky tape to hold your polaroid in place


This is a pretty common effect on the web now, having sticky tape hold up your images, and it's fairly easy to incorporate into our existing code.

First, you need to make the images of the tape you're going to be sticking the photo with. This tutorial is the simplest and fastest way to get it done. You can also get the images I've made - for the top left corner and the top right corner.

Now, you could easily add the PNGs into the code but there is the problem of lack of support with IE6. So we need some hacks to get the transparency to work. This post links to different ways of getting it done. The (best) way I initially used was using the iepngfix.htc script. But this uses relative URLs and so requires access to your HTML/CSS/images directory in order to place a blank GIF for the transparency. This isn't going to work with Blogger. So I'm using the other method detailed on the post linked above, which works for IE6, Firefox and Chrome and Safari. It fails on Safari but luckily, doesn't break anything; your image will simply be missing the tape. If you have your own webserver hosting your blog or if you do have access to the aforementioned directories, go ahead and use the iepngfix; it'll work more efficiently and also works with Safari.

The changes to the HTML and CSS:
.tape {
 position: absolute;
 /* absolute positioning so that the images can be place at will. This works because the container class specifies relative positioning for the div */
}

.top-left {
 width: 80px; /* specify the width... */
 height: 87px; /* ...and height */
 top: -20px; /* place the image, offset it to top by 20px */
 left: -20px; /* and to the left by 20px */
 /* Only IE will use this filter */
 filter: progid : DXImageTransform.Microsoft.AlphaImageLoader ( enabled =
  true, sizingMethod = scale, src = 'tape-tl.png' );
}

/* similar rules for the other tape */
.top-right {
 width: 87px;
 height: 80px;
 top: -20px;
 right: -20px;
 /* Only IE will use this filter */
 filter: progid : DXImageTransform.Microsoft.AlphaImageLoader ( enabled =
  true, sizingMethod = scale, src = 'tape-tr.png' );
}

/* IE ignores styles with [attributes], so it will skip the following. */
.top-left[class] {
 background-image: url('tape-tl.png');
}

/* IE ignores styles with [attributes], so it will skip the following. */
.top-right[class] {
 background-image: url('tape-tr.png');
}

Add two spans to the HTML
<div class="polaroid-container">
    <div class="polaroid-shadow">
        <div class="polaroid">
            <div class="polaroid-content-container">
                <img class="polaroid-pic" src="your-image.jpg" />
                <span class="polaroid-caption" />
            </div>
        </div>
    </div>
    <span class="tape top-right">&nbsp;</span>
    <span class="tape top-left">&nbsp;</span>
</div>

Here's an image of what you should be seeing with this code:
Sample Screenshot Of Polaroid-style Background With Sticky Tape On Corners

Now, the problems with this method of polaroid-izing your shots:
  • It breaks for really wide images (about as wide as the monitor resolution) because of the 20px margin on the outermost div
  • Lengthy captions will cause the width of the 'polaroid' to increase, giving a lot of whitespace. The text doesn't wrap. The solution is to manually add line-breaks (<br />) to your text at appropriate points

But it still works and as of now, it's the best way I can think of. If you have any suggestions or improvements, do leave a comment!

 [UPDATE] 21 Mar 2009: Turns out that the PNG transparency hack does work with Safari.

Friday, March 6, 2009

Linking PayMate To Your ABN AMRO Bank Account

I'd got a PayMate (not to be confused with Paymate, the Australian equivalent of PayPal) a year or so ago. I don't really use it very frequently except that I'd got a few free coupons so I'd bought stuff with those.

Recently, in my ABN AMRO netbanking account, I noticed a link that read Click here to register for payment service through Mobile 'PAYMATE' [sic]. This sounded interesting since, usually, I'd come across stuff on the online shopping sites that cost just a little bit more than my coupon was worth. Or there'd be extra charges for shipping. I figured that if I could associate my bank account with PayMate (for example, with PayPal, you can add additional sources but the money in your PayPal account gets used up first. So you never run out of funds, but you also don't end up with a trifling balance in your PayPal account), then I'd be able to tap into those funds for the remainder of any purchase requirement, over and above the coupon value.

I needed to confirm this of course, so I called up ABN AMRO's customer care helpline. Not a very good idea. Those people weren't clear on what PayMate was themselves and even when I tried to make them understand that I had been using PayMate for over a year and I knew what it was, they insisted on trying to explain the PayMate service to me. Sigh!

Now don't get me wrong, the representatives are usually pretty helpful and I do like ABN AMRO's service. Except in this case, they had no idea about it and had probably not been trained well enough on the topic. Anyway, I'd read somewhere that instead of venting your ire on some poor phone jockey, who probably wouldn't be able to do anything about it anyway, and spoiling your and his/her day, it's better to say 'thank you', put the phone down, and dial in again, hoping you get someone better equipped to help you.

I tried that but to no avail. The next day, I called up PayMate directly and, finally, someone was able to tell me how this thing would work. So here it is, what you've (hopefully) been reading this post for - how would you use your ABN AMRO account with your PayMate account? How will it work?

 If you don't know how PayMate works, you should read their FAQ first.
 

Your phone number is your PayMate id, of course. For every bank account (or other source of funds) linked to PayMate (they plan to add others later), you will get a new PIN. This is in addition to the PIN you may have for your original PayMate account (if you do have one). When you make an online transaction, the PIN you authorize the transaction with will determine which source of funds is utilized.

So there is no question of using up any one source first and then seamlessly switching over to the next preferred source. The source you pick must have sufficient funds.

Too bad. I was hoping for a PayPal like model, I'd probably have used PayMate more often then. They just might introduce this feature though so it's probably good to wait and watch.