How to round out corners when using CSS clip-path

夙愿已清 提交于 2019-12-01 03:01:48

I've recently found success experimenting with approaches like this...

SVG

<svg width="0" height="0">
  <defs>
    <clipPath id="clipped">
      <circle cx="var(--myRad)" cy="var(--myRad)" r="var(--myRad)"></circle>
      <circle cx="var(--myRad)" cy="calc(var(--myHeight) - var(--myRad))" r="var(--myRad)"></circle>
      <circle cx="calc(var(--myWidth) - var(--myRad))" cy="calc(var(--myHeight) - var(--myRad))" r="var(--myRad)"></circle>
      <circle cx="calc(var(--myWidth) - var(--myRad))" cy="var(--myRad)" r="var(--myRad)"></circle>
      <rect y="var(--myRad)" width="var(--myWidth)" height="calc(var(--myHeight) - (2 * var(--myRad)))"></rect>
      <rect x="var(--myRad)" width="calc(var(--myWidth) - (2 * var(--myRad)))" height="var(--myHeight)"></rect>
    </clipPath>
  </defs>
</svg>

CSS

.clipped {
  --myWidth: 100vw;
  --myHeight: 10rem;
  --myRad: 2rem;
  clip-path: url(#clipped);
}

I found this useful as compared to using border-radius with overflow set to hidden, because this approach doesn't create a BFC or break things like sticky position and css perspective effects. Also, this allows you to "inset" the position of the svg paths to clip inside the element with a "corner-radius" if you want.

You can also mess around with the circle to get some different effects.

-webkit-clip-path: circle(60.0% at 50% 10%);
clip-path: circle(50.0% at 50% 50%);

Codepen

Too bad you can't combine the polygon and circle... or maybe you can and I haven't played around with it enough to figure it out. HTH

I don't have a comment option yes, so I'm writing it as an answer..

you need to write as many points as possible to round the corner. Nothig else... for, example a few more points to make lower part bit rounder:

-webkit-clip-path: polygon(100% 0%, 100% 100%, 100% 100%, 25% 100%, 5% 70%,1% 60%, 0% 50%, 25% 0%);

oh, yes, or SVG as comment people here.. :)

You could use a child element and do a nested clip-path on that and the child's pseudo element. The parent will do a polygon clip on the shape first, then the pseudo will have an ellipse to round the borders. The clips will have a combined effect.

.parent, .parent div, .parent div:before {
  width: 423px;
  height: 90px;
  position: absolute;
}

.parent {
  right: 0;
  background-image: linear-gradient(to right, transparent 210px, #b0102d 210px);
  margin-top: 15vh;
}

.parent div {
  clip-path: polygon(100% 0%, 100% 100%, 25% 100%, 0 50%, 25% 0);
}

.parent div:before {
  content: "";
  background-color: #b0102d;
  clip-path: ellipse(200px 45px at 210px);
}
<div class="parent">
  <div></div>
</div>

Here is the demo with some adaptations to illustrate what's going on:

.parent, .parent div, .parent div:before {
  width: 423px;
  height: 90px;
  position: absolute;
}

.parent {
  right: 0;
  background-image: linear-gradient(to right, transparent 210px, yellow 210px);
  margin-top: 15vh;
}

.parent div {
  background-color: blue;
  clip-path: polygon(90% 0%, 90% 100%, 25% 100%, 0 50%, 25% 0);
}

.parent div:before {
  content: "";
  background-color: #b0102d;
  clip-path: ellipse(200px 45px at 210px);
}
<div class="parent">
  <div></div>
</div>

The horizontal size and position of the ellipse can be used to get a different effect on the edges. Note that the background starting postion of the parent needs to be adjusted to the same value as the placement of the ellipse (last value in the clip-path) because it fills up whatever gets clipped off on the right side. This can be visualised by removing background-color: blue from .parent div in the second demo.

Here is an additional Codepen to to try it out.

Make a rectangular clip and place a thick rectangle with rounded border over it. Have a good luck!

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!