Create reflection effect using CSS3

In a recent project, the client asked me if there is any way to add reflection to images. He wanted this effect because he liked the reflection effect added by designer in the design of his website. But the issue was that he might need to add more images in the future, and he cannot go back to his designer every time. Of course learning photoshop to do it by himself did not excite him either.

This encouraged me to try and create this effect in CSS, and it could prove to be a lifesaver for all. I tried and came up with a solution, which works in all browsers (Yes it works in IE too, not very nicely however).

Before we dive into the code, take a look at the demo page, to get an idea of what we are going to build here.

Following screenshot is taken from Firefox:

Getting started:

To follow along, you need to create an HTML page, a CSS file, and few images. You can also download the source files of my demo page.

I have named my files index.html, style.css, and images are placed in a folder named images.

HTML Code

<div class="image-block">
    <img src="images/book1.jpg" alt="" />
    <div class="reflection">
        <img src="images/book1.jpg" alt="" />
        <div class="overlay"></div>
    </div>
</div>

Each image requires an extra block which contains a copy of the image for reflection and a div with class "overlay" that we will use for adding fading gradient.

I have grouped both image and div into a container div with class "reflection". Let’s call this reflection block for referring it.

Now both original image and reflection block is wrapped into a div with class "image-block". Let’s call this image block. You can have any numbers of image blocks in your code if required, and that’s why I have used classes for CSS instead if IDs.

Ok, this code is simple enough to understand (I guess), so let’s move on to CSS.

CSS Code

.image-block { width:78px; margin:0px 10px; float:left; }
.reflection { position:relative; }
.reflection img {
    -webkit-transform: scaleY(-1);
    -moz-transform: scaleY(-1);
    -ms-transform: scaleY(-1);
    -o-transform: scaleY(-1);
    transform: scaleY(-1);
    filter: flipv; opacity:0.20;
    filter: alpha(opacity='20');
}
.overlay { position:absolute; top:0px; left:0px; width:78px; height:120px;
background-image: -moz-linear-gradient( center bottom, rgb(255,255,255) 60%, rgba(255,255,255,0) 75%);
background-image: -o-linear-gradient( rgba(255,255,255,0) 25%, rgb(255,255,255) 40%);
background-image: -webkit-gradient( linear, left bottom, left top, color-stop(0.60, rgb(255,255,255)), color-stop(0.75, rgba(255,255,255,0)));
filter: progid:DXImageTransform.Microsoft.Gradient( gradientType=0, startColor=0, EndColorStr=#ffffff);
}

Let’s go through the code step by step.

.image-block { width:78px; margin:0px 10px; float:left; }

I have added width to image block equal to the width of image, and by doing so, the reflection div will automatically move down, as it will not have space for second image.

Now we have two images as shown in image below

Next I have added position relative to the reflection block. This will add the positioning coordinates for its child elements with position absolute.

.reflection { position:relative; }

Now we have our stage ready, so let’s begin the magic with CSS3

.reflection img {
    -webkit-transform: scaleY(-1);
    -moz-transform: scaleY(-1);
    -ms-transform: scaleY(-1);
    -o-transform: scaleY(-1);
    transform: scaleY(-1);
    filter: flipv;
    opacity:0.20;
    filter: alpha(opacity='20');
}

This block of CSS code uses CSS3 and IE filters to flip the image vertically and add transparency to the image.

Because transform property is not completely implemented by all browsers, we need to add browser prefixes to make it working in each browser engine.

We have used transform: scaleY(-1); to simply flip the image vertically. Same effect can be achieved in Internet Explorer by adding filter: flipv;

Last 2 lines opacity:0.20; and filter: alpha(opacity='20'); adds transparency to the image.

Following image shows, what we have achieved so far:

Now we only need to add a gradient to add fading effect to the image, we have CSS3 gradients handy for this.

Some facts about CSS3 gradients:

  • CSS3 Gradient property is implemented differently in all browsers.
  • CSS3 Gradient property is not supported by IE including IE9.
  • Gradient in CSS is only supported on background images.
.overlay { 
    position:absolute; top:0px; left:0px; width:78px; height:120px;
    background-image: -moz-linear-gradient( center bottom, rgb(255,255,255) 60%, rgba(255,255,255,0) 75%);
    background-image: -o-linear-gradient( rgba(255,255,255,0) 25%, rgb(255,255,255) 40%);
    background-image: -webkit-gradient( linear, left bottom, left top, color-stop(0.60, rgb(255,255,255)), color-stop(0.75, rgba(255,255,255,0)));
    filter: progid:DXImageTransform.Microsoft.Gradient( gradientType=0, startColor=0, EndColorStr=#ffffff);
}

Because CSS3 gradient property is only supported on background images, we cannot add it directly on our reflection image.

I have added a div with class "overlay" for this purpose. I have positioned this div above reflection image, with position absolute. And added a width and height equaling to image.

At last I have added CSS3 gradient property to this overlay div, which has added a fading effect to the image.

Following is the end result.

This works fine in all browsers, except internet explorer.

Microsoft has provided a gradient filter, but it does not provide the ability to add a start and end point for gradient, like CSS3 gradient property.

Following is the result in Internet Explorer after adding the gradient filter.

As an idea, you can play with heights of reflection div and overlay div to cut the image and improve the effect in Internet Explorer. I am still looking for a better solution for Internet Explorer.

Please let me know if you any suggestions for improvement of this effect, or share the links if you use this effect in your projects.

I’m looking forward to your comments and thank you so much for reading!

17 COMMENTS

  1. Reece October 2, 2012 at 6:14 am

    CSS will never validated correctly unless you specifically design your website for one intended browser. which I’m sure will never be required unless you’re creating an in-house CDN for a company where they all use MAC’s where they all use Safari, Chrome or Firefox.

    -o-
    -webkit-
    -moz-

    these browser specific tags undoubtedly cause any CSS code to not be validated by the glorified piece of sh$# that is w3c..

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>