htmlcsssvgcss-shapescss-mask

How to create a smooth, curved SVG mask for a block's top-right corner?


I'm trying to create a block with a smooth, curved cut-out in the top-right corner, similar to the image below:

enter image description here

Currently, my implementation looks like this:

enter image description here

As you can see, the current curve is not as smooth as I'd like it to be - It's essentially not a curve, but a square with straight angles. Here's my current code:

body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
  background-color: #f0f0f0;
  font-family: Arial, sans-serif;
}

.curved-block {
  width: 300px;
  background-color: white;
  border-radius: 10px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  position: relative;
  overflow: hidden;
  padding: 5px;
}

.curved-block::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 40px;
  height: 40px;
  background-color: #f0f0f0;
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cpath d='M0 0 h25 c5 0, 10 0, 13 3 s2 7, 2 12 v25 h-40 z' fill='%23000000'/%3E%3C/svg%3E");
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cpath d='M0 0 h25 c5 0, 10 0, 13 3 s2 7, 2 12 v25 h-40 z' fill='%23000000'/%3E%3C/svg%3E");
  mask-size: cover;
  -webkit-mask-size: cover;
}

.icon {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 23px;
  height: 23px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 16px;
  font-weight: bold;
  background-color: #0056b3;
  border-radius: 50%;
  color: white;
  z-index: 2;
}
<div class="curved-block">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
  <span class="icon">+</span>
</div>

I'm struggling to achieve a smoother, more natural-looking curve in the SVG mask. How can I modify the SVG path to create a curve that looks more like the one in the desired result image? Thank you in advance for your suggestions.


Solution

  • I did it here: https://css-shape.com/inverted-radius/

    You can easily copy the code and adjust the variables:

    .inverted-radius {
      --r: 15px; /* the radius */
      --s: 30px; /* the size of the corner*/
      
      height: 150px;
      margin: 10px;
      background: #3FB8AF;
      border-radius: var(--r);
      --_m:/calc(2*var(--r)) calc(2*var(--r))
        radial-gradient(#000 70%,#0000 72%) no-repeat;
      mask:
        right calc(var(--s) + var(--r)) top var(--_m),
        right calc(var(--s) + var(--r)) var(--_m),
        radial-gradient(var(--s) at 100% 0,#0000 99%,#000 101%) 
         calc(-1*var(--r)) var(--r) no-repeat,
        conic-gradient(at calc(100% - var(--s) - 2*var(--r)) calc(var(--s) + 2*var(--r)),
         #0000 25%,#000 0);
    }
    <div class="inverted-radius"></div>