How to add border in my clip-path: polygon(); CSS style
Can border be applied to a clipped element along the clip path?
No, adding border
property to the clipped element would not apply the borders along the clipped path because the border
is applied to the original rectangle (or square) container before the clip-path
is applied and so, it also gets clipped out. You can see this in the below snippet:
div {
display: inline-block;
height: 200px;
width: 200px;
border: 3px solid;
background: darkseagreen;
}
div + div {
-webkit-clip-path: polygon(50% 0%, 100% 100%, 100% 0%);
clip-path: polygon(50% 0%, 100% 100%, 100% 0%);
}
<div></div>
<div></div>
Are there any alternate ways to create such a border effect?
We can mimic it by applying the same clip-path
on a container element. The container element's background color will look as though it is the border of the inner element because both are clipped and the container has slightly higher dimensions than the inner element.
.poligon {
display: inline-block;
position: relative;
width: 150px;
height: 150px;
background: red;
box-sizing: border-box;
-webkit-clip-path: polygon(92.32051% 40%, 93.79385% 43.1596%, 94.69616% 46.52704%, 95% 50%, 94.69616% 53.47296%, 93.79385% 56.8404%, 92.32051% 60%, 79.82051% 81.65064%, 77.82089% 84.50639%, 75.35575% 86.97152%, 72.5% 88.97114%, 69.3404% 90.44449%, 65.97296% 91.34679%, 62.5% 91.65064%, 37.5% 91.65064%, 34.02704% 91.34679%, 30.6596% 90.44449%, 27.5% 88.97114%, 24.64425% 86.97152%, 22.17911% 84.50639%, 20.17949% 81.65064%, 7.67949% 60%, 6.20615% 56.8404%, 5.30384% 53.47296%, 5% 50%, 5.30384% 46.52704%, 6.20615% 43.1596%, 7.67949% 40%, 20.17949% 18.34936%, 22.17911% 15.49361%, 24.64425% 13.02848%, 27.5% 11.02886%, 30.6596% 9.55551%, 34.02704% 8.65321%, 37.5% 8.34936%, 62.5% 8.34936%, 65.97296% 8.65321%, 69.3404% 9.55551%, 72.5% 11.02886%, 75.35575% 13.02848%, 77.82089% 15.49361%, 79.82051% 18.34936%);
clip-path: polygon(92.32051% 40%, 93.79385% 43.1596%, 94.69616% 46.52704%, 95% 50%, 94.69616% 53.47296%, 93.79385% 56.8404%, 92.32051% 60%, 79.82051% 81.65064%, 77.82089% 84.50639%, 75.35575% 86.97152%, 72.5% 88.97114%, 69.3404% 90.44449%, 65.97296% 91.34679%, 62.5% 91.65064%, 37.5% 91.65064%, 34.02704% 91.34679%, 30.6596% 90.44449%, 27.5% 88.97114%, 24.64425% 86.97152%, 22.17911% 84.50639%, 20.17949% 81.65064%, 7.67949% 60%, 6.20615% 56.8404%, 5.30384% 53.47296%, 5% 50%, 5.30384% 46.52704%, 6.20615% 43.1596%, 7.67949% 40%, 20.17949% 18.34936%, 22.17911% 15.49361%, 24.64425% 13.02848%, 27.5% 11.02886%, 30.6596% 9.55551%, 34.02704% 8.65321%, 37.5% 8.34936%, 62.5% 8.34936%, 65.97296% 8.65321%, 69.3404% 9.55551%, 72.5% 11.02886%, 75.35575% 13.02848%, 77.82089% 15.49361%, 79.82051% 18.34936%);
}
.poligon img {
position: absolute;
top: 2px; /* equal to border thickness */
left: 2px; /* equal to border thickness */
width: 146px; /* container height - (border thickness * 2) */
height: 146px; /* container height - (border thickness * 2) */
-webkit-clip-path: polygon(92.32051% 40%, 93.79385% 43.1596%, 94.69616% 46.52704%, 95% 50%, 94.69616% 53.47296%, 93.79385% 56.8404%, 92.32051% 60%, 79.82051% 81.65064%, 77.82089% 84.50639%, 75.35575% 86.97152%, 72.5% 88.97114%, 69.3404% 90.44449%, 65.97296% 91.34679%, 62.5% 91.65064%, 37.5% 91.65064%, 34.02704% 91.34679%, 30.6596% 90.44449%, 27.5% 88.97114%, 24.64425% 86.97152%, 22.17911% 84.50639%, 20.17949% 81.65064%, 7.67949% 60%, 6.20615% 56.8404%, 5.30384% 53.47296%, 5% 50%, 5.30384% 46.52704%, 6.20615% 43.1596%, 7.67949% 40%, 20.17949% 18.34936%, 22.17911% 15.49361%, 24.64425% 13.02848%, 27.5% 11.02886%, 30.6596% 9.55551%, 34.02704% 8.65321%, 37.5% 8.34936%, 62.5% 8.34936%, 65.97296% 8.65321%, 69.3404% 9.55551%, 72.5% 11.02886%, 75.35575% 13.02848%, 77.82089% 15.49361%, 79.82051% 18.34936%);
clip-path: polygon(92.32051% 40%, 93.79385% 43.1596%, 94.69616% 46.52704%, 95% 50%, 94.69616% 53.47296%, 93.79385% 56.8404%, 92.32051% 60%, 79.82051% 81.65064%, 77.82089% 84.50639%, 75.35575% 86.97152%, 72.5% 88.97114%, 69.3404% 90.44449%, 65.97296% 91.34679%, 62.5% 91.65064%, 37.5% 91.65064%, 34.02704% 91.34679%, 30.6596% 90.44449%, 27.5% 88.97114%, 24.64425% 86.97152%, 22.17911% 84.50639%, 20.17949% 81.65064%, 7.67949% 60%, 6.20615% 56.8404%, 5.30384% 53.47296%, 5% 50%, 5.30384% 46.52704%, 6.20615% 43.1596%, 7.67949% 40%, 20.17949% 18.34936%, 22.17911% 15.49361%, 24.64425% 13.02848%, 27.5% 11.02886%, 30.6596% 9.55551%, 34.02704% 8.65321%, 37.5% 8.34936%, 62.5% 8.34936%, 65.97296% 8.65321%, 69.3404% 9.55551%, 72.5% 11.02886%, 75.35575% 13.02848%, 77.82089% 15.49361%, 79.82051% 18.34936%);
}
<div class="poligon">
<img src="https://picsum.photos/600/400">
</div>
Pseudo-Element
A nice way to do this would be with a pseudo-element like a ::before
Make exactly the same shape but slightly smaller which holds the main color you want and position it correctly and you get the border you want.
The below example isn't the correct shape but shows how to achieve this effect:
.shape {
width: 400px;
height: 40px;
background-color: black;
position: relative;
}
.shape:before {
content: '';
width: 398px;
height: 38px;
background: #00c000;
display: block;
position: absolute;
top: 1px;
left: 1px;
}
.shape, .shape:before {
-webkit-clip-path: polygon(5% 0, 100% 0, 100% 100%, 0 100%, 0 100%);
clip-path: polygon(5% 0, 100% 0, 100% 100%, 0 100%, 0 100%);
}
<div class="shape"></div>
Adding a Border to a Complex Clip Path With SVG Dilation Filter
Copy-Shrink Method Only Works In Simple Cases -- used in currently accepted answer
The currently accepted answer works by making a copy and shrinking it. This works for the example, but if you have a more complex shape (like text), it will not work. A better approach is to use dilation with a filter.
Shape Dilation Works on ANY Shape
A better approach is to use dilation with the feMorphology filter!!
- SVG feMorphology Filter
Key aspects:
- Create matching
<image>
and<rect>
shapes of equal height and width - Clip both with the desired shape path/polygon
- Use filter to dilate/enlarge the clipped
rect
to make a border
The filter radius=
becomes the stand in for border thickness.
The result:
.clipper{
clip-path: url(#clip_shape);
}
.dilate{
filter: url("#dilate_shape");
}
<svg xmlns="http://www.w3.org/2000/svg" height="400" width="400">
<defs>
<clipPath id="clip_shape" clipPathUnits="objectBoundingBox">
<text x="0" y=".8" lengthAdjust="spacing" font-weight="700" font-style="italic" font-size="1"> M </text>
</clipPath>
<filter id="dilate_shape">
<feMorphology operator="dilate" in="SourceGraphic" radius="5" />
</filter>
</defs>
<g transform="translate(5,5)">
<g class="dilate">
<rect class="clipper" x=0 y=0 height="400px" width="400px" fill="lightgreen"></rect>
</g>
<image class="clipper" xlink:href="http://placekitten.com/400/300" height="400px" width="400px">
</g>
</svg>