CSS (Backgrund Image) Reflection

Published: At Celtra, we use Cover Flow to show recent ads to our clients. It is a set of thumbnail images with their reflections, something similar to what Apple uses in Finder and other applications.
There are a couple of ways to do that in HTML, but all have some flaws and weaknesses. There are strategies to achieve desired effect with JavaScript and Canvas ( David Walsh), but I wanted a pure CSS solution that works cross-browser.

There are some ways to achieve CSS reflection:

Using non-standard CSS reflection in WebKit browsers

Syntax: -webkit-box-reflect: <direction> <offset> <mask-box-image>;

Parameters:

direction
The position of the reflection relative to the border box. Can be: above, below, left, or right.
offset
The distance of the reflection from the edge of the border box, in length units or as a percentage. The default value is 0.
mask-box-image
Used to overlay the reflection. If omitted, the reflection has no mask.

See the Pen Image Reflection in Webkit browsers, using -webkit-box-reflect by Robert Sedovšek (@sedovsek) on CodePen

The result here looks pleasing, but this is not standardized and will probably never be supported by non-Webkit browsers.

Supported by:
  • Chrome Desktop
  • Chrome Android 2.1+
  • Safari
  • Opera 16+
  • iOS 2+

Since this is a unofficial (Webkit only), keep in mind to always use 'prefixed version', -webkit-box-reflect. You can also check for supported browsers on Can I Use, but I suggest to avoid it and rather try using a simple workaround which works cross-browser.


In Firefox (Gecko), using element()

Firefox supports (-moz-)element(), which can be used to achieve image reflection effect. The element() function allows an author to use an element in the document as an image; the spec is currently not ready yet for the implementation, so using element() to achieve reflection is considered an experimental.

Syntax: element(<id selector>)

See the Pen Image Reflection in Webkit browsers, using -webkit-box-reflect by Robert Sedovšek (@sedovsek) on CodePen

Supported by:
  • Firefox 4+
    (-moz prefixed)

See detailed information how Lea Verou used element() and SVG filter to achieve reflection, read more about what can be done by using element() on "Firefox 4: Drawing arbitrary elements as backgrounds with -moz-element" or help contribute to the spec for CSS images (level 4).


Cross-browser workaround, standard-approach

In this case I used pseudo selector ::before and simply replicated the initial background image using standard approach, background-image: inherit value, rotated it, applied box-shadow to create a "fade" to white effect, and lowered the opacity. A slight drawbacks are a) it can only be used on elements that contain background images, and b) "fade" to color should be specified to match the background color (white in our examples).

See the Pen Image Reflection in Webkit browsers, using -webkit-box-reflect by Robert Sedovšek (@sedovsek) on CodePen

Supported by:
  • Internet Explorer 9+
  • Firefox
  • Chrome
  • Safari
  • Opera+

This workaround is actually supported in every browser that support ::before and ::after pseudo selectors, but for better results, also CSS transforms (for rotation) and CSS box-shadow to add "fade" effect to the image are great contributors. But even in browsers that do not support transforms, we still get adequate results.


I am far off to be an expert on this, so there might be better ways to deal with CSS reflections, but so far I haven't seen a proper, W3C standarized way; but clearly there is a need for it, so why not make it a standard… I'm looking at you Apple Inc. and Adobe Systems.

blog comments powered by Disqus