3

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.

Shog9
  • 156,901
  • 35
  • 231
  • 235
geoffs3310
  • 5,599
  • 11
  • 51
  • 104

2 Answers2

9

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);).

jbutler483
  • 24,074
  • 9
  • 92
  • 145
6

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>
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
  • 1
    You don't need a wrapper . Set transform: perspective(1000px) rotateY(50deg); on the figure itself – vals Jan 25 '16 at 16:41