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. Malone R777 July 15, 2011 at 2:17 pm

    I have not implemented this technique but first response after reading is “Thank you for your time and efforts!”.  Now it’s playtime!

    Notice: Undefined variable: add_below in /home/ajain/www/www.xhtml-lab.com/htdocs/wp-content/themes/xhtml-lab/functions.php on line 55 Reply to Malone
    • Johnc970 July 15, 2014 at 8:08 am

      Hey, thanks for the blog article.Really looking forward to read more. Much obliged. ebkbbdbaacce

      Notice: Undefined variable: add_below in /home/ajain/www/www.xhtml-lab.com/htdocs/wp-content/themes/xhtml-lab/functions.php on line 55 Reply to Johnc970
  2. Lyjuboy July 18, 2011 at 9:55 am

    for IE, 
      you can use a background image (png file with gradient inside)  for  the overlay instead of the gradient effect 

    Notice: Undefined variable: add_below in /home/ajain/www/www.xhtml-lab.com/htdocs/wp-content/themes/xhtml-lab/functions.php on line 55 Reply to Lyjuboy
    • Jaspreet Kaur July 18, 2011 at 10:08 am

      Using images for IE is a nice idea, however there are few concerns:
      1. you will need to use IE Hack for this
      2. it will be difficult to match if you have a complex background
      3. If these images are added dynamically by client, he will need to add 2 images, and it’s quite possible that client is not technical enough to create the reflection effect for images.

      Notice: Undefined variable: add_below in /home/ajain/www/www.xhtml-lab.com/htdocs/wp-content/themes/xhtml-lab/functions.php on line 55 Reply to Jaspreet
      • xJp1989 January 30, 2014 at 9:32 am

        Using a solid color to transparent background image is no big deal and can be applied to all browser, that’s what I did. Thanks great tut.

        Notice: Undefined variable: add_below in /home/ajain/www/www.xhtml-lab.com/htdocs/wp-content/themes/xhtml-lab/functions.php on line 55 Reply to xJp1989
      • xJp1989 January 30, 2014 at 9:32 am

        Using a solid color to transparent background image is no big deal and can be applied to all browser, that’s what I did. Thanks great tut.

        Notice: Undefined variable: add_below in /home/ajain/www/www.xhtml-lab.com/htdocs/wp-content/themes/xhtml-lab/functions.php on line 55 Reply to xJp1989
      • Surendra June 19, 2014 at 4:05 am

        Look and Feel of your website is great. Jaspreet Kaur

        Notice: Undefined variable: add_below in /home/ajain/www/www.xhtml-lab.com/htdocs/wp-content/themes/xhtml-lab/functions.php on line 55 Reply to Surendra
    • Jaspreet Kaur July 24, 2011 at 1:22 pm

      Yes i know, This property is supported by Safari, Chrome and Firefox with following commands:
      -webkit-box-reflect
      -moz-box-reflect

      However it’s not yet supported by Opera and IE.
      Thanks for your comments.

      Notice: Undefined variable: add_below in /home/ajain/www/www.xhtml-lab.com/htdocs/wp-content/themes/xhtml-lab/functions.php on line 55 Reply to Jaspreet
  3. Beben Koben July 24, 2011 at 8:22 pm

    amazing…this is play with transparent & gradient attribute for to be shadow…
    cool trick ;)

    Notice: Undefined variable: add_below in /home/ajain/www/www.xhtml-lab.com/htdocs/wp-content/themes/xhtml-lab/functions.php on line 55 Reply to Beben
  4. CyberStream.us July 26, 2011 at 1:24 am

    Thanks for this tip! Wouldn’t it be cool if you could add a reflection to the image with pseudo-elements:

    img:after {content: url(attr(src));transform: rotate(180deg);
    opacity: 0.35; }

    Then you could add a CSS3 mask to fade it out! Wishful thinking…

    Notice: Undefined variable: add_below in /home/ajain/www/www.xhtml-lab.com/htdocs/wp-content/themes/xhtml-lab/functions.php on line 55 Reply to CyberStream.us
  5. Wouter Mesker July 26, 2011 at 10:29 am

    Why not use a jave script to turn the image and flip it,, and then overlay it with a javascript so every browser support?

    Notice: Undefined variable: add_below in /home/ajain/www/www.xhtml-lab.com/htdocs/wp-content/themes/xhtml-lab/functions.php on line 55 Reply to Wouter
  6. Matteo September 17, 2012 at 1:49 pm

    really helpfull! But it works only if I have a color as website background. Thank you.

    Notice: Undefined variable: add_below in /home/ajain/www/www.xhtml-lab.com/htdocs/wp-content/themes/xhtml-lab/functions.php on line 55 Reply to Matteo
  7. 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..

    Notice: Undefined variable: add_below in /home/ajain/www/www.xhtml-lab.com/htdocs/wp-content/themes/xhtml-lab/functions.php on line 55 Reply to Reece

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>