CSS Image Reflection
Trying to mimic webkit-box-reflection through moz-element and friends.
HTML
<section>
<h1>Kittens from Flickr</h1>
<div id=container>Please enable JS for the images to load.</div>
<svg height="0">
<mask id="svgGradientMask" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
<linearGradient id="g" gradientUnits="objectBoundingBox" x1="0" y1="100%" x2="0" y2="0">
<stop stop-color="white" offset="0"/>
<stop stop-color="white" stop-opacity="0" offset="50%"/>
</linearGradient>
<rect x="0" y="0" width="1.0" height="1.0" fill="url(#g)"/>
</mask>
</svg>
<aside>
<h1>Note:</h1>
<p>You need a recent WebKit browser or Firefox 4 beta to view this demo. WebKit uses <code>-webkit-box-reflection</code>, Firefox 4 uses: <code>mask</code>, <code>-moz-transform</code> and <code>-moz-element</code>.
<p>This is valid HTML5, but invalid CSS (lots of vendor-prefixed CSS properties used)
<p><small>An HTML5 + CSS + JS + SVG experiment by <a href="http://www.marcoos.com">marcoos</a> (<a href="http://twitter.com/marcoos">@marcoos</a>). Flickr querying <a href="http://developer.yahoo.com/yql/">powered by YQL</a>.</small></p>
</aside>
</section>
CSS
/* some basic styling first */
body {
background:#000;
color: #fff;
font-family: Lucida Grande, Lucida Sans, sans-serif;
}
a {
color: #f00;
text-decoration: none;
}
h1 {
text-align: center;
font-size: 1.2em;
}
aside {
font-size: 0.8em;
width: 50%;
margin: auto;
}
aside h1 {
text-align: left;
}
#container {
text-align: center;
margin-bottom: 160px;
}
#container img {
max-width: 150px;
max-height: 150px;
margin: 5px;
vertical-align: bottom;
}
/* here's where the reflection is rendered by WebKit */
#container a {
display: inline-block;
-webkit-box-reflect:none;
/* below 5px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0.5, transparent), to(white));
some transitions to be used by :hover below
-webkit-transition: 0.5s ease-out;
-moz-transition: 0.5s ease-out;*/
}
#container a:hover {
-webkit-transform: skew(15deg);
-moz-transform: skew(15deg);
-moz-transform-origin: 50% 25%;
}
/* JS sets the nowbr class on body if no webkit-box-reflect support is found */
.nowbr #container {
margin-bottom: 0;
}
/* we'll render the rotated copy of the image in generated content */
.nowbr #container a:after {
display: block;
max-width: 150px;
margin: 5px;
height: 150px;
content: " ";
color: #fff;
/* rotate the image 180 degrees, so that it is a proper reflection */
-moz-transform: rotate(180deg);
/* mask the image with an SVG gradient.
* Shame it's not possible to do something like this: mask: -moz-linear-gradient(...),
* so we have to use SVG.
mask: url(#svgGradientMask);
background-repeat: no-repeat;
background-position: bottom left;*/
}
/* Make the generated-content pseudo-elements mirror what is displayed in the original elements;
* It would be...
JavaScript
function $(id) {
return document.getElementById(id);
}
function isWebkitBoxReflectSupported() {
// if you set WhatEverProperty to a value,
// and that value is returned by getPropertyValue("-what-ever-property"),
// then you can assume the browser supports it.
var d = document.createElement("p");
d.style.WebkitBoxReflect = "none";
return "none" === d.style.getPropertyValue("-webkit-box-reflect");
}
function createImageLink(image, index) {
// this will be called as an argument of the Array.prototype.map method
// create an img element using data from the YQL query
var elem = document.createElement("img");
elem.src = "http://farm" + image.farm + ".static.flickr.com/" +
image.server + "/" + image.id + "_" + image.secret + "_m.jpg";
elem.title = elem.alt = image.title;
elem.id = "img_" + index;
// we need to put the image inside the a element,
// so that generated content in :after works
// (img:after won't)
var a = document.createElement("a");
a.id = "s_img_" + index;
a.href = "http://www.flickr.com/photos/" + image.owner + "/" + image.id;
a.target = "_blank";
a.appendChild(elem);
return a;
}
function yqlCallback(res) {
try {
var container = $("container"),
pics, imageLinks;
pics = res.query.results.photo;
imageLinks = pics.map(createImageLink);
container.innerHTML = "";
imageLinks.forEach(function (elem) {
container.appendChild(elem);
});
} catch (e) {
container.innerHTML = "Error. See console for details.";
if (window.console) {
window.console.log(e);
}
}
}
function yqlGetImages() {
$("container").innerHTML = "Loading...";
var queryUrl = ...