如何使边界半径曲线向外延伸?

时间:2022-04-01 07:14:14

I am try to make a div have borders like the following drawing:

我试着让一个div有如下的边框:

如何使边界半径曲线向外延伸?

This is what I have tried:

这就是我所尝试的:

div {
    height: 100px;
    width: 100px;
    border-bottom-right-radius:100px 10px;
    border:1px solid #000;
}
<div></div>

What is an effect way to accomplish this?

达到这个目的的有效方法是什么?

3 个解决方案

#1


27  

Using :before and :after

如何使边界半径曲线向外延伸?

The top border is created with the :before:

  • Its height is the same as the border radius

    它的高度等于边界半径

  • It is positioned just outside with top and lines up with the left border thanks to left

    它的位置就在外面,顶部和左边的边界排成一行

  • Its width is calculated with calc to precisely line up the top of the curve

    它的宽度用calc计算,以精确地排列在曲线的顶部

  • The curve can be refined with transform: skewX(-60deg)

    曲线可变换细化:skewX(-60deg)

The left border is created with the :after:

  • It is given a 100% height minus the height of the before and the thickness of the border with calc
  • 它的高度是100%减去之前的高度和边界的厚度

Examples

Number 1 - a bit pointy

div {
  border-bottom-right-radius: 100px 20px;
  border: 1px solid #000;
  border-top: none;
  height: 500px;
  width: 200px;
  position: relative;
  border-left: none;
}
div:before,
div:after {
  content: '';
  display: block;
  position: absolute;
  left: -1px;
}
div:before {
  height: 20px;
  width: 100%;
  width: calc(100% + 1px);
  border-bottom-right-radius: 100px 20px;
  border-bottom: 1px solid #000;
  border-right: solid 1px #000;
  top: -1px;
}
div:after {
  height: calc(100% - 18px);
  border-left: 1px solid #000;
  top: 19px;
}
<div></div>

Number 2 - smoothed out point with skew

div {
  border-bottom-right-radius: 100px 20px;
  border: 1px solid #000;
  border-top: none;
  height: 200px;
  width: 200px;
  position: relative;
  border-left: none;
}
div:before,
div:after {
  content: '';
  display: block;
  position: absolute;
  left: -1px;
}
div:before {
  height: 20px;
  width: 100%;
  width: calc(100% - 36px);
  border-bottom-right-radius: 100px 20px;
  border-bottom: 1px solid #000;
  border-right: solid 2px #000;
  top: 0px;
  left: 17px;
  transform: skewX(-60deg);
}
div:after {
  height: calc(100% - 19px);
  border-left: 1px solid #000;
  top: 20px;
}
<div></div>

#2


7  

I could do it using DIVs, but I am pretty sure that exists a more elegant way to do it:

我可以用DIVs来做,但是我很确定这是一种更优雅的方法:

    #container {
       border:none;   
       height:100px;
       border-right: solid 1px #000;
    }
    
    #square_top {
       border-bottom-right-radius:100px 10px;
       border:none;   
       border-bottom: solid 1px #000;
       height:10px;
    }
    
    #square_bottom {
       border-bottom-right-radius:100px 10px;
       border:none;   
       border-bottom: solid 1px #000;
       border-right:solid 1px #000;
       border-left:solid 1px #000;
       height:10px;
    }
    
    #square {
       height: 90px;
       border-left:solid 1px #000;
    }
    <div id="container">
       <div id="square_top"></div>
       <div id="square">TEXT HERE</div>
    </div>   
    <div id="square_bottom"></div>

#3


4  

Although CSS can do this, there is another approach that allows more flexibility : SVG

虽然CSS可以做到这一点,但是还有另一种方法可以提供更大的灵活性:SVG

This approach allows :

这种方法允许:

  • The shape addapts its size to the size of the content
  • 形状根据内容的大小增加大小
  • Responsive
  • 响应
  • Allows any kind of background (image, gradients, semitransparent color...)
  • 允许任何类型的背景(图像、渐变、半透明颜色…)
  • Allows any kind of filling for the shape (image, gradients, semitransparent color...)
  • 允许任何形状的填充(图像,梯度,半透明的颜色…)
  • easier to control the the top and bottom curves :
  • 容易控制上下曲线:

body {background: url('http://lorempixel.com/output/people-q-g-640-480-9.jpg');background-size: cover;}
div {
  position: relative;
  width: 30%;
  padding: 5%;
  color: #fff;
  text-align: center;
}
svg {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  z-index: -1;
}
<div>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <svg viewbox="0 0 50 100" preserveAspectRatio="none">
    <path d="M1 9 C49 10 49 1 49 1 V90 C49 91 49 99 1 99z"  stroke-width="0.5" stroke="#000" fill-opacity="0.5" />
  </svg>
</div>

#1


27  

Using :before and :after

如何使边界半径曲线向外延伸?

The top border is created with the :before:

  • Its height is the same as the border radius

    它的高度等于边界半径

  • It is positioned just outside with top and lines up with the left border thanks to left

    它的位置就在外面,顶部和左边的边界排成一行

  • Its width is calculated with calc to precisely line up the top of the curve

    它的宽度用calc计算,以精确地排列在曲线的顶部

  • The curve can be refined with transform: skewX(-60deg)

    曲线可变换细化:skewX(-60deg)

The left border is created with the :after:

  • It is given a 100% height minus the height of the before and the thickness of the border with calc
  • 它的高度是100%减去之前的高度和边界的厚度

Examples

Number 1 - a bit pointy

div {
  border-bottom-right-radius: 100px 20px;
  border: 1px solid #000;
  border-top: none;
  height: 500px;
  width: 200px;
  position: relative;
  border-left: none;
}
div:before,
div:after {
  content: '';
  display: block;
  position: absolute;
  left: -1px;
}
div:before {
  height: 20px;
  width: 100%;
  width: calc(100% + 1px);
  border-bottom-right-radius: 100px 20px;
  border-bottom: 1px solid #000;
  border-right: solid 1px #000;
  top: -1px;
}
div:after {
  height: calc(100% - 18px);
  border-left: 1px solid #000;
  top: 19px;
}
<div></div>

Number 2 - smoothed out point with skew

div {
  border-bottom-right-radius: 100px 20px;
  border: 1px solid #000;
  border-top: none;
  height: 200px;
  width: 200px;
  position: relative;
  border-left: none;
}
div:before,
div:after {
  content: '';
  display: block;
  position: absolute;
  left: -1px;
}
div:before {
  height: 20px;
  width: 100%;
  width: calc(100% - 36px);
  border-bottom-right-radius: 100px 20px;
  border-bottom: 1px solid #000;
  border-right: solid 2px #000;
  top: 0px;
  left: 17px;
  transform: skewX(-60deg);
}
div:after {
  height: calc(100% - 19px);
  border-left: 1px solid #000;
  top: 20px;
}
<div></div>

#2


7  

I could do it using DIVs, but I am pretty sure that exists a more elegant way to do it:

我可以用DIVs来做,但是我很确定这是一种更优雅的方法:

    #container {
       border:none;   
       height:100px;
       border-right: solid 1px #000;
    }
    
    #square_top {
       border-bottom-right-radius:100px 10px;
       border:none;   
       border-bottom: solid 1px #000;
       height:10px;
    }
    
    #square_bottom {
       border-bottom-right-radius:100px 10px;
       border:none;   
       border-bottom: solid 1px #000;
       border-right:solid 1px #000;
       border-left:solid 1px #000;
       height:10px;
    }
    
    #square {
       height: 90px;
       border-left:solid 1px #000;
    }
    <div id="container">
       <div id="square_top"></div>
       <div id="square">TEXT HERE</div>
    </div>   
    <div id="square_bottom"></div>

#3


4  

Although CSS can do this, there is another approach that allows more flexibility : SVG

虽然CSS可以做到这一点,但是还有另一种方法可以提供更大的灵活性:SVG

This approach allows :

这种方法允许:

  • The shape addapts its size to the size of the content
  • 形状根据内容的大小增加大小
  • Responsive
  • 响应
  • Allows any kind of background (image, gradients, semitransparent color...)
  • 允许任何类型的背景(图像、渐变、半透明颜色…)
  • Allows any kind of filling for the shape (image, gradients, semitransparent color...)
  • 允许任何形状的填充(图像,梯度,半透明的颜色…)
  • easier to control the the top and bottom curves :
  • 容易控制上下曲线:

body {background: url('http://lorempixel.com/output/people-q-g-640-480-9.jpg');background-size: cover;}
div {
  position: relative;
  width: 30%;
  padding: 5%;
  color: #fff;
  text-align: center;
}
svg {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  z-index: -1;
}
<div>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <p>Some text</p>
  <svg viewbox="0 0 50 100" preserveAspectRatio="none">
    <path d="M1 9 C49 10 49 1 49 1 V90 C49 91 49 99 1 99z"  stroke-width="0.5" stroke="#000" fill-opacity="0.5" />
  </svg>
</div>