Search code examples
csscss-shapes

Border of rectangle with curved side


I have a shape that looks like this

enter image description here

It is a rectangle with a circle behind it. I need to do a border all around it.

  • I tried to do a border for the rectangle and a curved line for the curved part (based on this). It doesn't seem to be precise enough. The curved line don't align 100% with the circle part. I need precision.
  • Putting the same shape a bit bigger behind it does not work for what I need.

Code - jsfiddle

.template {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.rectangle {
  background: red;
  width: 91mm;
  height: 63mm;
  border-radius: 2mm;
}

.circle {
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  z-index: -999;
  background: red;
  width: 68mm;
  height: 68mm;
  border-radius: 100%;
}
<div class="template">
  <div class="rectangle"></div>
  <div class="circle"></div>
</div>

Any ideas of how I could achieve that sweet border?


Solution

  • Use a pseudo element with radial-gradient:

    .box {
      width:200px;
      height:150px;
      background:red;
      border-radius:10px;
      position:relative;
      margin-top:50px;
    }
    .box:before {
      content:"";
      position:absolute;
      bottom:100%;
      left:0;
      right:0;
      height:50px; /* Same as margin*/
      background:radial-gradient(circle,red 49.5%,transparent 50%) top/150% 400%;
      
    }
    <div class="box">
    
    </div>

    Then you can add border:

    .box {
      width:200px;
      height:150px;
      background:red;
      border-radius:10px;
      position:relative;
      margin-top:50px;
      border:3px solid blue;
    }
    .box:before {
      content:"";
      position:absolute;
      bottom:100%;
      left:0;
      right:0;
      height:50px; /* Same as margin*/
      background:radial-gradient(circle,red 49.5%,blue 50% calc(50% + 3px),transparent calc(50% + 4px)) top/150% 400%;
      
    }
    <div class="box">
    
    </div>

    And also use a transparent color:

    .box {
      width:200px;
      height:150px;
      background:rgba(255,0,0,0.5) padding-box;
      border-radius:10px;
      position:relative;
      margin-top:50px;
      border:3px solid blue;
      border-top-color:transparent;
    }
    .box:before {
      content:"";
      position:absolute;
      bottom:100%;
      left:0;
      right:0;
      height:50px; /* Same as margin*/
      background:radial-gradient(circle,rgba(255,0,0,0.5) 49.5%,blue 50% calc(50% + 3px),transparent calc(50% + 4px)) top/150% 400%; 
    }
    .box:after {
      content:"";
      position:absolute;
      top:-3px;
      height:100%;
      left:-3px;
      right:-3px;
      border-top:3px solid blue;
      border-right:3px solid transparent;
      border-left:3px solid transparent;
      border-radius:inherit;
      clip-path:polygon(0 0,28px 0,28px 50px,calc(100% - 28px) 50px,calc(100% - 28px) 0, 100% 0,100% 100%,0 100%);
    }
    
    body {
     background:url(https://picsum.photos/id/1001/800/800) center/cover;
    }
    <div class="box">
    
    </div>