Daniel
Daniel

Reputation: 176

How to simply create an image reflection effect in JavaScript/CSS?

I have spent some time to look up how to best create a dynamic image reflection effect.

Options I found were:

The drawbacks of the above lie at hand. Unfortunately I do not have a web blog where to post what I came up with, yet I think it would be worth sharing (see self-answer below).

Upvotes: 0

Views: 796

Answers (2)

Daniel
Daniel

Reputation: 176

  1. Add an image to your HTML:
<img class="reflect" src="some/image.png" />
  1. Add the following CSS rules:
img.reflect {
  width: calc(100% - 20px); /* not sure how else to allow for margin */
  margin-left: 10px;
}

img.reflection {
  position: absolute;
  opacity: 0.4;
  margin-top: 4px;
  width: calc(100% - 20px);
  -webkit-mask-image: -webkit-linear-gradient(transparent 75%, black 100%);
  mask-image: linear-gradient(transparent 75%, black 100%);
  -webkit-transform: translateX(calc(-100% - 10px)) translateY(100%) scaleY(-1) ;
  transform: translateX(calc(-100% - 10px)) translateY(100%) scaleY(-1);
}

If you don't want to rely on any JavaScript you could now simply add the reflection by inserting the reflection tag right after the image tag from (1):

<img class="reflection" src="some/image.png" />

Otherwise

  1. For example, extend JQuery with the following function:
$.fn.reflect = function() {
    var reflection = this.clone();
    this.after(reflection);
    reflection.addClass("reflection");
};
  1. Then reflect the image:
$(".reflect").reflect();

Upvotes: 2

Temani Afif
Temani Afif

Reputation: 273021

Here is a pure CSS solution without the need of jQuery or JS:

.reflect {
  display:inline-block;
  vertical-align:top;
  width:150px;
  height:300px;
  background:
    linear-gradient(#000,#000) center/100% 1px no-repeat, /*a separation*/
    var(--img) top/100% 50% no-repeat;
  position:relative;
}
.reflect::before {
  content:"";
  position:absolute;
  bottom:0;
  left:0;
  right:0;
  top:0;
  background:inherit;
  transform:scale(1,-1);
  -webkit-mask-image: -webkit-linear-gradient(transparent 25%, #ccc 50%);
  mask-image: linear-gradient(transparent 25%, #ccc 50%)
}
.right {
  width:300px;
  height:150px;
  background-position:center,left;
  background-size:1px 100%,50% 100%;
}
.right:before {
  transform:scale(-1,1);
  -webkit-mask-image: -webkit-linear-gradient(left,transparent 25%, #ccc 50%);
  mask-image: linear-gradient(to left,transparent 25%, #ccc 50%)
}
<div class="reflect" style="--img:url(https://picsum.photos/200/200?image=0)"></div>

<div class="reflect right" style="--img:url(https://picsum.photos/200/200?image=1069)"></div>

Upvotes: 0

Related Questions