Creating a real time reflection effect with CSS and javascript
There are many new CSS properties have surfaced over the last few years (round corners, drop-shadows, multiple background images, border images, reflections to name a few ) some propriety and some contained within the CSS3 working spec. these new properties are a great step forward t make it easier to create current styles in graphic design in HTML. The only thing is these properties are not set in stone and and browser support is varied, which is always the biggest problem in HTML/CSS development.
today I’m going to look at a way to create a reflection effect with CSS/JavaScript that will work cross browsers in the most common desktop browsers. the property were are emulating here is box-reflect which currently is only supported by Safari.
you can see this technique in action at the bottom of my blog as you scroll down the page the content looks like it is reflected onto the floor.
First the HTML we will need 4 containers first is the main content then a div to sit on top of the reflection to create a gradient effect, a reflection div to contain a copy of content which will be inserted via JavaScript and a reflection container to clip the reflection
<div id="Content"></div>
<div id="Reflected-Mask"></div>
<div id="Reflected-Content-Container">
<div id="Reflected-Content"></div>
</div>
Next we have a basic version of the CSS required.
#Content {
width:400px;
position:relative;
z-index:1;
}
#Reflected-Mask {
background:url("../images/reflection.png") no-repeat scroll center top transparent;
height:68px;
bottom:0;
left:0;
overflow:hidden;
position:fixed;
width:401px;
z-index:3;
}
#Refelcted-Content-Container {
height:68px;
bottom:0;
left:0;
overflow:hidden;
position:fixed;
width:401px;
z-index:3;
}
#Reflected-Content-Container {
bottom:0;
overflow:hidden;
height:68px;
position:fixed;
width:400px;
position:relative;
z-index:2;
}
#Reflected-Content {
-moz-transform: matrix(1, 0, 0, -1, 0, 0); /* for firefox */
-webkit-transform: matrix(1, 0, 0, -1, 0, 0); /* for safari / chrome */
-o-transform: matrix(1, 0, 0, -1, 0, 0); /* for opera */
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); /* for ie7 or lower */
-ms-filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); /* for ie8 */
}
The main thing to look at here is the matrix transformation property to get a unified result we need to use 5 different variants to cover the different browsers. most working in the same way except Internet Explorer.
the last step is a small piece of JavaScript to clone the main content into the reflection container so the it can be mirrored and then detect any scroll changes or browser re-size changes to update the reflections position. for this to make things simple I am using jQuery.
$(document).ready(function() {
$(document).pngFix();
// clone element to use as reflection
var clonedContent = $("#Content").clone(true);
// change its id to apply the tranformation matrix
clonedContent.attr("id","Reflected-Content");
// create the reflection container
var container = $("<div id='Reflected-Content-Container'></div>")
container.html(clonedContent)
container.insertAfter("#Content")
// position reflection
setReflection();
$(window).scroll(function() {
setReflection()
});
$(window).resize(function() {
setReflection();
});
})
function setReflection() {
// adjust the reflected content position so it matches the main content.
$("#Reflected-Content").scrollTop($(window).scrollTop()+($(window).height()-(68*2)))
}
So there you have it a reflection effect of HTML content.
Known problems
- I have had some success reflecting flash content but it was not reliable everywhere so you may want to set visibility:hidden; on objects and embeds in the reflection.
- there are some problems using this effect on mobile browsers this is mostly down to their problems for displaying position:fixed at the moment.





