2

Basically I'm trying to create a reflection of an image using CSS as shown below (and/or jQuery, but not something that will really affect performance). This will need to work responsively too.

The idea is there will be an iMac PNG (with a hole cut out for the site screenshots), and then using a Content Management System I would upload the site screenshot and it would be placed in and behind the screen to show through .... this all works fine, but I then want the screen and site screenshot to be reflected below. I know it's only subtle, but if it's possible I would like to do it.

example of reflection effect

This is the code structure I'm planning to use, feel free to use this in any examples :)

DEMO: http://codepen.io/anon/pen/gKnry

<div class="screen_contain">
    <img src="imac-image.png" class="imac">
    <img src="website_image.png" class="website">
</div>
.screen_contain {
  display:inline-block;
  position: relative;
  width:33%;
}

.imac {
  width: 100%;
  position: relative;
  z-index: 10;
}

.website {
  position: absolute;
  left: 5.0%;
  top: 5%;
  width: 90%;
  z-index: 5;
}

Notes:

  • I would obviously be able to merge the iMac image so that it has the main iMac AND it's reflection in one image ... save on requests and messy code.
  • This is going to be populated by a client so all they will be able to do is upload the screenshot of a website.

Thanks!

Lighty_46
  • 5,010
  • 1
  • 16
  • 17
  • http://css-tricks.com/snippets/css/flip-an-image/ You'd need two images, though. css can't "clone" a dom element. that's not its job. it's just styling rules. if you want an original and a flippped version, you'll have to embed the image twice. – Marc B Aug 27 '14 at 14:32
  • http://www.digitalia.be/software/reflectionjs-for-jquery – j08691 Aug 27 '14 at 14:33
  • 2
    Well, it's WebKit only, but there's this: [CSS Reflections](https://www.webkit.org/blog/182/css-reflections/). Admittedly, this may have been removed from WebKit, or become cross-browser, since last I looked. – David Thomas Aug 27 '14 at 14:36
  • 1
    @DavidThomas: I don’t think it’s been removed from WebKit, but [I don’t think it’s gone cross-browser either](https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-box-reflect). – Paul D. Waite Aug 27 '14 at 14:38
  • @Lighty_46: it might be worth having a look at [this answer](http://stackoverflow.com/a/15144988/20578). It’s a bit fiddly, admittedly. – Paul D. Waite Aug 27 '14 at 14:39
  • No, I assumed not; but I wish it was (it's one of those awkward-to-implement features that would, periodically, be very useful in CSS). – David Thomas Aug 27 '14 at 14:40
  • @DavidThomas: maybe. See, now that design trends have come around to everything being a rectangle with a single background colour (your design is *so* 2007, @Lighty_46), it seems a bit pointless that all those developer hours went into making native CSS drop shadows, gradients, rounded corners and reflections. I guess they’ll come back into fashion one day and we’ll all rejoice. – Paul D. Waite Aug 27 '14 at 14:41
  • You could output the image twice but then use the css3 [in this answer](http://stackoverflow.com/questions/21635990/image-reflection-effect-using-pure-css) to make it appear like a reflection. Or there are many js libraries out there, eg [jqReflect](http://www.jwf.us/projects/jQReflect/) – Pete Aug 27 '14 at 14:42
  • 1
    @Paul: I suspect that the current 'flat' design was a response to the prevalence of shiny/skeumorphic design in the early smartphone era; that being the case (IMHO, etc) I imagine that the glossy UI will return (albeit somewhat different to the last generation) in reaction to the flat designs. – David Thomas Aug 27 '14 at 15:04
  • Any feedback for the answers below? – Brian Dillingham Sep 05 '14 at 04:18

4 Answers4

3

Here is a fiddle showing pure CSS live reflects (if you change the source element, the reflection will change as well): http://jsfiddle.net/scvprc2r/

This only works in Webkit and Gecko browsers (only tested in Chrome and Firefox). If you want better browser support, go with an SVG or JS solution.

The modified structure:

<div class="screen_contain">
    <div class="computer" id="one">
        <img src="http://ferncroft.co.uk/files/2014/08/ethernal-demo-imac.png" class="imac" />
        <img src="http://danzambonini.com/wp-content/uploads/2010/07/stack_overflow_initial.jpg" class="website" id="web1" />
    </div>
    <div class="reflection"></div>
</div>

I added an extra wrapper div around the images, added unique ids to the site image and to the wrapper div. I also added another div to hold the reflection in Firefox and the gradient fade effect in both browsers.

CSS:

.computer {
    -webkit-box-reflect: below 0px linear-gradient(to top, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
}

This creates a reflection of the element below the the element using -webkit-box-reflect. The gradient is added to produce a smoother effect.

.reflection {
    transform: scaleY(-1);
}

Our base reflection style. We flip it around so that the mozilla element() background is in the correct orientation

#one + .reflection {
        background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 1) 32%, rgba(255, 255, 255, 0) 100%) 100% 100%,
                    -moz-element(#web1) no-repeat 50% -5%,
                    -moz-element(#one) no-repeat 100% 100%;
}

This is how the reflection in Firefox is made. This takes advantage of the element() function, which creates a live image of an element. The element backgrounds are set as the second and third backgrounds on the div.

This code is then repeated for each additional repeated div.

In Firefox, the reflected background's size and position depends on the height of the div it is placed in. Here is some jQuery to dynamically change the size of the reflection to the size of the original element:

function resizeReflection() {
    $('.reflection').each(function () {
        $(this).height($(this).prev().height());
    });
}

resizeReflection();

$(window).resize(function () {
    resizeReflection();
});

This would not be needed if your images were fixed size.

What this looks like:

Firefox Firefox Chrome Chrome

If you want an SVG solution instead of a CSS one, take a look at this (much simpler, and has better browser support): http://jsfiddle.net/JeremiePat/bGD3J/

quw
  • 2,844
  • 1
  • 26
  • 35
1

Use CSS transform to flip the image. Then, use CSS mask to create an alpha mask of the image (http://www.html5rocks.com/en/tutorials/masking/adobe/#toc-alpha-mask).

Unfortunately, CSS alpha masks do not seem to be widely supported http://caniuse.com/#search=mask. The alternative, if you have a solid color background, is to place the iMac image in element (likely as a background) and place a PNG-24 gradient image on top that fades to the background color.

Jason
  • 4,079
  • 4
  • 22
  • 32
0

css reflection

jsFiddle Example

CSS

.reflection {
    transform: rotate(180deg); 
    width: 100%;
}

.gradient {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    z-index: 999;
    background: -webkit-gradient(linear, left bottom, left top,
       color-stop(0%,rgba(255,255,255,.5)), 
       color-stop(60%,rgba(255,255,255,1)));
}

To Avoid jquery: Just duplicate the HTML to avoid jquery

<div class="screen_contain">
    <img src="http://ferncroft.co.uk/files/2014/08/ethernal-demo-imac.png" class="imac" />
    <img src="http://danzambonini.com/wp-content/uploads/2010/07/stack_overflow_initial.jpg" class="website" />
    <div class="screen_contain reflection">
        <img src="http://ferncroft.co.uk/files/2014/08/ethernal-demo-imac.png" class="imac" />
        <img src="http://danzambonini.com/wp-content/uploads/2010/07/stack_overflow_initial.jpg" class="website" />
        <div class="gradient"></div>
    </div>
</div>

With Jquery jsFiddle Example

  var screen_captain = $('.screen_contain');

  $.each(screen_captain, function(){
     $(this).append($(this).clone().addClass('reflection').append('<div class="gradient"></div>'));
  })
Brian Dillingham
  • 9,118
  • 3
  • 28
  • 47
0

This is a duplicate question and has been answered in StackOverflow Topic:

CSS property box-reflect compatibility?

Possible with not only webkit (latest chrome or safari) but also in latest firefox.

Here is the example: http://codepen.io/jonathan/pen/pgioE

The tut, thanks to David at:

http://satreth.blogspot.com/2012/05/css3-reflection.html

HTML:

<div id="someid">
   <img src="image url" />
<div/>

CSS (webkit):

#someid {
        /* need some space for the reflection */
        margin-bottom: 120px;
        /* the gradient makes the reflection fade out */
        -webkit-box-reflect: below 0px -webkit-linear-gradient(bottom, rgba(255,255,255,0.3) 0%, transparent 40%, transparent 100%);
}

CSS (Firefox - Gecko):

#someid {
        position: relative;
        /* need some space for the reflection */
        margin-bottom: 120px;
}

#someid:before {
        content:""; /* needed or nothing will be shown */
        background: -moz-linear-gradient(top, white, white 30%, rgba(255,255,255,0.9) 65%, rgba(255,255,255,0.7)) 0px 0px, -moz-element(#someid) 0px -127px no-repeat;
        -moz-transform: scaleY(-1); /* flip the image vertically */
        position:relative;
        height:140px;
        width: 360px; /* should be > image width + margin + shadow */
        top: 247px;
        left:0px;
 }

Firefox uses -moz-element to do the reflections (https://developer.mozilla.org/en-US/docs/CSS/element), whereas webkit uses a proprietary vendor prefix for reflections.

Other example:

http://lea.verou.me/2011/06/css-reflections-for-firefox-with-moz-element-and-svg-masks/

Cheers!

Community
  • 1
  • 1
Jonathan Marzullo
  • 6,879
  • 2
  • 40
  • 46