How to transform each side of a shape separately?

I don’t think there is any way in CSS to pick and transform each side separately but you can achieve the shape in question by using perspective transforms (pure CSS).

Rotating the element with perspective along both X and Y axes sort of produces the effect of each side having a separate transformation. You can adjust the angles and the perspective setting to create the shape exactly as required.

.shape {
  background: black;
  margin: 100px;
  height: 200px;
  width: 200px;
  transform: perspective(20px) rotateX(-2deg) rotateY(-1deg); /* make perspective roughly 10% of height and width */
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="shape"></div>

Or, you could make use of the clip-path feature. Clip paths can be created either by using CSS alone or by using inline SVG. SVG clip paths have much better browser support than the CSS version.

div {
  height: 200px;
  width: 200px;
  background: black;
}
.css-clip {
  -webkit-clip-path: polygon(0% 10%, 100% 0%, 85% 100%, 15% 95%);
  clip-path: polygon(0% 10%, 100% 0%, 85% 100%, 15% 95%);
}
.svg-clip {
  -webkit-clip-path: url(#clipper);
  clip-path: url(#clipper);
}

/* Just for demo */

div{
  display: inline-block;
  margin: 10px;
  line-height: 200px;
  text-align: center;
  color: beige;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<!-- CSS Clip path -->
<div class="css-clip">CSS Clip Path</div>

<!-- SVG Clip path -->
<svg width="0" height="0">
  <defs>
    <clipPath id='clipper' clipPathUnits="objectBoundingBox">
      <path d='M0 0.1, 1 0, 0.85 1, 0.15 0.95' />
    </clipPath>
    </defs>
</svg>
<div class="svg-clip">SVG Clip path</div>

Note: Though this shape can be achieved using CSS, it is better not to use CSS for such complex shapes.

Leave a Comment