How can I clip and transform an image, adding rounded corners and perspective?

1.5k Views Asked by At

How can I use HTML and CSS to make a div with an image inside it that is clipped and masked so that it looks like the following:

perspective-skewed div containing similarly-transformed image

I've been trying to find a way to do this for about 2 hours now and got nowhere so I was just hoping someone could point me in the right direction. To be specific here, I wish to clip the image such that the top two corners are rounded, and embed it in a div element with four rounded corners and a 1/4 bottom padding, with both elements transformed such that it appears the right edge is further away from the viewer than the left.

2

There are 2 best solutions below

0
On BEST ANSWER

In order to create such an effect, where the image remains the same, but the outer shape has this perspective look, you could use something similar to the demo below.

div.inner {/*gives top section effect, also crops the image*/
  position: absolute;
  top: 0;
  left: 0;
  border-radius: 20px 20px 0 0;
  height: 200px;
  width: 300px;
  overflow: hidden;
  border: 10px solid red;
  transform: skewY(5deg);
}

.inner img {/*removes transform skew from image*/
  transform: skewY(-5deg);
  transform-origin: top left;
  height:100%;width:100%;
}

.wrap {
  display: inline-block;
  height: 200px;
  width: 300px;
  position: relative;
  
  /*for demo only*/
  margin: 100px 100px;
}

.wrap:after { /*give bottom section the effect*/
  content: "";
  position: absolute;
  bottom: -50%;
  left: 0;
  height: 100%;
  width: calc(100% + 20px);
  transform: skewY(-10deg);
  transform-origin: bottom right;
  background: red;
  z-index: -1;
  border-radius: 20px;
}
<div class="wrap">
  <div class="inner">
    <img src="http://lorempixel.com/500/500" />
  </div>
</div>

In order to create the effect, I have had to incorporate this wrapper div. This allows the use of a pseudo element (the :after css) to generate the lower part of the shape:

 +----------------------------+
 |                            |
 |                    _______/  <-- curved corner
 |             ------/
 |      ------/
 \-----/
   /\
    \_____ also curved corner

The inner div is then hence used to generate the upper part of the shape. Using the skew declaration, the shape allows the opposite of the :after element, bringing the right hand side of the red shape down wards.

The overflow:hidden ensures any part of the image that does not fit within this inner div will be cropped (the border-radius:20px 20px 0 0; ensures only the upper corners are affected).

The last point to note is the .inner img css. Since I have skewed the .inner div, it is important to then 'unskew' the image so it remains the rectangular shape. This is why there is a 'counter-skew' here (transform: skewY(-5deg);).

1
On

Here's my attempt using perspective.

Thanks to @vals for the pointing out that perspective can be used as part of the transform.

* {
  box-sizing: border-box;
}
figure {
  perspective: 1000px;
  width: 420px;
  margin: 5em auto;
  height: 350px;
  background: red;
  text-align: center;
  padding: 10px;
  border-radius: 25px;
  transform: perspective(1200px) rotateY(50deg);
}
img {
  border-radius: 20px 20px 0 0;
}
<figure>
  <img src="http://lorempixel.com/400/200/sports/1/" alt="" />
</figure>