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!
I have not implemented this technique but first response after reading is “Thank you for your time and efforts!”. Now it’s playtime!
Hey, thanks for the blog article.Really looking forward to read more. Much obliged. ebkbbdbaacce
for IE,
you can use a background image (png file with gradient inside) for the overlay instead of the gradient effect
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.
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.
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.
Look and Feel of your website is great. Jaspreet Kaur
Did you know Safari and Chrome implements -webkit-box-reflect
http://developer.apple.com/library/safari/#documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/Reflections/Reflections.html
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.
amazing…this is play with transparent & gradient attribute for to be shadow…
cool trick 😉
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…
Why not use a jave script to turn the image and flip it,, and then overlay it with a javascript so every browser support?
Superb one :))
you could have put a javascript fallback model too
like this
http://davidwalsh.name/javascrip-reflection
CSS will not validate because of browser prefixes and Filter.
great
really helpfull! But it works only if I have a color as website background. Thank you.
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..
woooov . i need that , thank for this usefull post . thanks
it doesn’t work ok on all browsers but the article is great. I’m a webdesigner myself and from time to time I believe we should do awesome designs and projects for a wider public and let the other segment to upgrade their browsers. I still get hits/visits from users who use IE old crappy versions and nope, they are not bots or VM “users” .