Using CSS:
The exact shape can be achieved using CSS. The idea is to have an element with a border-radius for the top-left corner, skew it along the Y axis and then position it just before the rectangle. Doing these would make it look as though the rectangular element has a triangular cut at the top with one curved edge.
If the inside part of the shape has only a color (solid or transparent) then it can be achieved using only one element. However, if an image needs to be added inside the shape (like mentioned in question), then we need more than one element because we have to reverse the skew effect on the image and this cannot be done without a child element.
.shape,
.shape-image {
position: relative;
height: 150px;
width: 400px;
border-bottom: 2px solid crimson;
overflow: hidden;
}
.shape:before,
.shape:after,
.shape-image:after {
position: absolute;
content: '';
top: 0px;
height: 100%;
z-index: -1;
}
.shape:before,
.shape-image .before {
left: 0px;
top: -2px;
width: 50px;
border: 2px solid crimson;
border-width: 3px 0px 0px 2px;
border-top-left-radius: 8px;
transform-origin: right bottom;
transform: skewY(-45deg);
}
.shape:after,
.shape-image:after {
left: 52px;
width: calc(100% - 54px);
border: 2px solid crimson;
border-left: none;
}
.shape:after,
.shape:before {
background: aliceblue;
}
.shape.semi-transparent:after,
.shape.semi-transparent:before {
background: rgba(150, 150, 150, 0.5);
}
.shape-image .before {
position: absolute;
top: 0px;
height: 100%;
overflow: hidden;
}
.shape-image .before .img {
height: 100%;
width: 100%;
border-top-left-radius: 8px;
background: url(http://lorempixel.com/400/150);
transform-origin: right bottom;
transform: skewY(45deg);
}
.shape-image:after {
background: url(http://lorempixel.com/400/150);
background-position: -50px 0px;
}
/* Just for demo */
body{
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
.shape{
margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="shape"></div>
<div class="shape semi-transparent"></div>
<div class="shape-image">
<div class="before">
<div class="img"></div>
</div>
</div>
Using SVG:
Alternately the same can be achieved in a more hassle free way with SVG like in the below snippet.
.vector {
height: 150px;
width: 410px;
padding-left
}
svg {
height: 100%;
width: 100%;
}
path {
stroke: crimson;
stroke-width: 2;
fill: none;
}
polygon {
fill: url(#bg);
}
/* Just for demo */
body {
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='vector'>
<svg viewBox='0 0 400 150' preserveAspectRatio='none'>
<defs>
<path d='M50,2 h 342 v144 h-390 v-90 a6,12 0 0,1 3,-9 z' id='p' />
<clipPath id='clipper'>
<use xlink:href='#p' />
</clipPath>
<pattern id='bg' width='400' height='150' patternUnits='userSpaceOnUse'>
<image xlink:href='http://lorempixel.com/400/150' height='150' width='400' />
</pattern>
</defs>
<polygon points='2,2 392,2 392,148 2,148' clip-path='url(#clipper)' />
<use xlink:href='#p' />
</svg>
</div>
<h3>Original Image</h3>
<img src='http://lorempixel.com/400/150' />
Screenshot:
