CSS transparent curved shape with two rounded sides

前端 未结 1 1901
悲哀的现实
悲哀的现实 2020-11-29 14:14

I\'m trying to create inner curved transparent shape,like this

\"curved

but i have troubl

相关标签:
1条回答
  • 2020-11-29 14:41

    Here is an idea using radial-gradient

    .box {
      margin-top:120px;
      width:200px;
      height:100px;
      background:white;
    }
    .box .top {
      height:100px;
      width:150px;
      transform:translateY(-100%);
      position:relative;
      background:#fff;
    }
    
    .top:before,
    .top:after{
      content:"";
      position:absolute;
      top:0;
      width:50px;
      left:100%;
      bottom:50%;
      background:
        radial-gradient(100% 50% at top left, #fff 98%,transparent 100%) right,
        radial-gradient(100% 50% at bottom right, transparent 98%,#fff 100%) left;
      background-size:50% 100%;
      background-repeat:no-repeat;
    }
    .top:after {
      transform-origin:bottom;
      transform:scaleY(-1);
    }
    body {
      background:pink;
    }
    <div class="box">
    <div class="top"></div>
    </div>

    To better understand the trick here is the curved shape alone with different colors:

    .top {
      height:100px;
      width:100px;
      position:relative;
    }
    
    .top:before,
    .top:after{
      content:"";
      position:absolute;
      top:0;
      width:50px;
      left:100%;
      bottom:50%;
      background:
        radial-gradient(100% 50% at top left, red 98%,blue 100%) right,
        radial-gradient(100% 50% at bottom right, purple 98%,green 100%) left;
      background-size:50% 100%;
      background-repeat:no-repeat;
      outline:2px solid;
    }
    .top:after {
      transform-origin:bottom;
      transform:scaleY(-1);
    }
    body {
      background:pink;
    }
    <div class="top"></div>

    And here is an SVG solution where I will simply replace the gradient with an SVG

    .box {
      margin-top:120px;
      width:200px;
      height:100px;
      background:white;
    }
    .box .top {
      height:100px;
      width:150px;
      transform:translateY(-100%);
      position:relative;
      background:#fff;
    }
    
    .top:before{
      content:"";
      position:absolute;
      top:0;
      width:50px;
      left:100%;
      bottom:0;
      background:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 64 64' width='64' height='64' preserveAspectRatio='none' fill='white'><path d='M0 0 L0 64 L64 64 C64 40 0 56 0 32 C0 8 64 24 64 0 Z' /></svg>");
      background-size:100% 100%;
    }
    body {
      background:pink;
    }
    <div class="box">
    <div class="top"></div>
    </div>


    You can optimize the code and use only one element:

    .box {
      width:200px;
      height:200px;
      background:
        radial-gradient(100% 50% at top     left, #fff 98%,transparent 100%) top 0    right 0   /30px 50px,
        radial-gradient(100% 50% at bottom right, transparent 98%,#fff 100%) top 0    right 30px/30px 50px,
        radial-gradient(100% 50% at bottom  left, #fff 98%,transparent 100%) top 50px right 0   /30px 50px,
        radial-gradient(100% 50% at top    right, transparent 98%,#fff 100%) top 50px right 30px/30px 50px,
        linear-gradient(#fff,#fff) bottom/100% calc(100% - 100px),
        linear-gradient(#fff,#fff) left  /calc(100% - 60px) 100%;
      background-repeat:no-repeat;
    }
    
    body {
      background:pink;
    }
    <div class="box">
    </div>

    And with the SVG:

    .box {
      width:200px;
      height:200px;
      background:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 64 64' width='64' height='64' preserveAspectRatio='none' fill='white'><path d='M0 0 L0 64 L64 64 C64 40 0 56 0 32 C0 8 64 24 64 0 Z' /></svg>") top right/60px 100px,
        linear-gradient(#fff,#fff) bottom/100% calc(100% - 100px),
        linear-gradient(#fff,#fff) left  /calc(100% - 60px) 100%;
      background-repeat:no-repeat;
    }
    
    body {
      background:pink;
    }
    <div class="box">
    </div>


    You can add some CSS variable to control everything easily:

    .box {
      --w:60px;  /*width of the curve */
      --h:100px; /*height of the curve */
      --t:0px;   /*offset from top */
    
      width:150px;
      height:150px;
      display:inline-block;
      background:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 64 64' width='64' height='64' preserveAspectRatio='none' fill='white'><path d='M0 0 L0 64 L64 64 C64 40 0 56 0 32 C0 8 64 24 64 0 Z' /></svg>") top var(--t) right 0/var(--w) var(--h),
        
        linear-gradient(#fff,#fff) top   /100% var(--t),
        linear-gradient(#fff,#fff) bottom/100% calc(100% - var(--h) - var(--t)),
        linear-gradient(#fff,#fff) left  /calc(100% - var(--w)) 100%;
      background-repeat:no-repeat;
    }
    
    body {
      background:pink;
    }
    <div class="box"></div>
    
    <div class="box" style="--t:20px;--w:50px;--h:80px"></div>
    
    <div class="box" style="--t:20px;--w:80px;--h:130px"></div>


    Another idea using mask in case you want to conside a random background. Simply place the background inside the mask definition:

    .box {
      width:200px;
      height:200px;
      -webkit-mask:
        radial-gradient(100% 50% at top     left, #fff 98%,transparent 100%) top 0    right 0   /30px 50px,
        radial-gradient(100% 50% at bottom right, transparent 98%,#fff 100%) top 0    right 30px/30px 50px,
        radial-gradient(100% 50% at bottom  left, #fff 98%,transparent 100%) top 50px right 0   /30px 50px,
        radial-gradient(100% 50% at top    right, transparent 98%,#fff 100%) top 50px right 30px/30px 50px,
        linear-gradient(#fff,#fff) bottom/100% calc(100% - 100px),
        linear-gradient(#fff,#fff) left  /calc(100% - 60px) 100%;
      mask:
        radial-gradient(100% 50% at top     left, #fff 98%,transparent 100%) top 0    right 0   /30px 50px,
        radial-gradient(100% 50% at bottom right, transparent 98%,#fff 100%) top 0    right 30px/30px 50px,
        radial-gradient(100% 50% at bottom  left, #fff 98%,transparent 100%) top 50px right 0   /30px 50px,
        radial-gradient(100% 50% at top    right, transparent 98%,#fff 100%) top 50px right 30px/30px 50px,
        linear-gradient(#fff,#fff) bottom/100% calc(100% - 100px),
        linear-gradient(#fff,#fff) left  /calc(100% - 60px) 100%;
      -webkit-mask-repeat:no-repeat;
      mask-repeat:no-repeat;
      background:linear-gradient(red,blue);
    }
    
    body {
      background:pink;
    }
    <div class="box">
    </div>

    With the SVG syntax

    .box {
      --w:60px;  /*width of the curve */
      --h:100px; /*height of the curve */
      --t:0px;   /*offset from top */
    
      width:150px;
      height:150px;
      display:inline-block;
      -webkit-mask:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 64 64' width='64' height='64' preserveAspectRatio='none' fill='white'><path d='M0 0 L0 64 L64 64 C64 40 0 56 0 32 C0 8 64 24 64 0 Z' /></svg>") top var(--t) right 0/var(--w) var(--h),
        
        linear-gradient(#fff,#fff) top   /100% var(--t),
        linear-gradient(#fff,#fff) bottom/100% calc(100% - var(--h) - var(--t)),
        linear-gradient(#fff,#fff) left  /calc(100% - var(--w)) 100%;
      mask:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 64 64' width='64' height='64' preserveAspectRatio='none' fill='white'><path d='M0 0 L0 64 L64 64 C64 40 0 56 0 32 C0 8 64 24 64 0 Z' /></svg>") top var(--t) right 0/var(--w) var(--h),
        
        linear-gradient(#fff,#fff) top   /100% var(--t),
        linear-gradient(#fff,#fff) bottom/100% calc(100% - var(--h) - var(--t)),
        linear-gradient(#fff,#fff) left  /calc(100% - var(--w)) 100%;
      -webkit-mask-repeat:no-repeat;
      mask-repeat:no-repeat;
      background:linear-gradient(red,blue);
    }
    
    body {
      background:pink;
    }
    <div class="box"></div>
    
    <div class="box" style="--t:20px;--w:50px;--h:80px"></div>
    
    <div class="box" style="--t:20px;--w:80px;--h:130px"></div>

    0 讨论(0)
提交回复
热议问题