Using CSS:
The best that you could achieve with CSS would be something like the below. The shape construction is as follows:
- A pseudo-element whose border-radius is 100% on all sides except border-top-right-radius. This produces a leaf like shape. This is then rotated by -45deg so that the tip is towards the top.
- This pseudo element is then positioned such that only half of it is visible (by setting
overflow as hidden on the parent).
- The parent container's Y axis is then rotated by a high angle to kind of compress the shape. This makes it look more like an arrow.
The shape is responsive but as you can see its creation is very tricky and this is why CSS is not the right tool for this job. SVG is the correct tool and a demo is available below.
div {
position: relative;
height: 200px;
width: 200px;
border-bottom: 2px solid tomato;
overflow: hidden; /* hide the parts that are not required */
transform: rotateY(65deg); /* to compress the shape in Y axis */
}
div:before {
position: absolute;
content: '';
left: 0px;
top: 50%; /* positioning to make only part of it visible */
height: calc(100% - 6px); /* to offset for the border width */
width: calc(100% - 6px); /* to offset for the border width */
border-radius: 100% 0% 100% 100%;
transform: rotate(-45deg);
border: 3px solid tomato; /* made thicker because the transform will make it look thinner than normal */
}
/* just for demo */
div {transition: all 1s ease;}
div:hover {
height: 250px;
width: 250px;
}
<div></div>
Using SVG: recommended
With SVG we can create this shape using a single path element and a couple of Quadratic Curve-to (Q) commands. It is very simple, scalable (responsive), allows us greater control over the curvature etc.
SVG commands used and explanation:
M - moves the imaginary pen to the point specified by the coordinates.
Q - Draws a quadratic curve from the current position of the pen to the point that is indicated by the second set of coordinates that follow the Q command. The first set of coordinates represent the control point. This control point determines the slope of the curve.
z - Closes the shape by drawing a straight line from the current pen position to the starting point.
The SVG shape can also be rotated just like a normal CSS element.
svg {
height: 200px;
width: 200px;
}
path {
fill: none;
stroke: tomato;
stroke-width: 1;
}
/* just for demo */
svg {
transition: all 1s ease;
}
svg:hover {
transform: rotate(-15deg);
}
<svg viewBox="0 0 105 105" preserveAspectRatio="none">
<path d="M15,102 Q25,50 50,0 Q75,50 85,102z" />
</svg>
The above is just a basic implementation. You can play around with the control points of the Quadratic curve to get different slopes. Below are a few possible samples:
<path d="M15,102 Q25,35 50,0 Q75,35 85,102z" />
<path d="M15,102 Q20,35 50,0 Q80,35 85,102z" />
Another advantage of using SVG for such shapes is that you can easily add a gradient or an image as fill or background to the shape. Below is a demo:
svg {
height: 200px;
width: 200px;
}
path {
fill: none;
stroke: tomato;
stroke-width: 1;
}
path#image {
fill: url(#bg-image);
}
path#gradient {
fill: url(#bg-grad);
}
<svg viewBox="0 0 105 105" preserveAspectRatio="none">
<defs>
<pattern id="bg-image" width="1" height="1" patternUnits="objectBoundingBox">
<image xlink:href="https://placeimg.com/200/200/nature" width="105" height="105" />
</pattern>
</defs>
<path d="M15,102 Q20,35 50,0 Q80,35 85,102z" id="image" />
</svg>
<svg viewBox="0 0 105 105" preserveAspectRatio="none">
<defs>
<radialGradient id="bg-grad" width="1" height="1" patternUnits="objectBoundingBox">
<stop offset="0%" stop-color="#3F9CBA" />
<stop offset="100%" stop-color="#153346" />
</radialGradient>
</defs>
<path d="M15,102 Q20,35 50,0 Q80,35 85,102z" id="gradient" />
</svg>