如何使我的边框半径向外弯曲?

22

我正在尝试让一个div像下图一样有边框:

enter image description here

这是我尝试的代码:

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

如何有效地完成此任务?


那需要一些额外的标记,而不仅仅是边框半径。 - Colin Schoen
3个回答

30

使用 :before:after

例子

通过 :before 创建顶部边框:

  • 它的高度与边框半径相同

  • top 将其定位在外部,并借助于 left 与左边框对齐

  • calc 计算其宽度,以精确定位曲线的顶部

  • 可以用 transform: skewX(-60deg) 精细调整曲线

通过 :after 创建左边框:

  • calc 给它一个减去 before 的高度和边框厚度的 100% 高度

示例

第一种 - 有点尖

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>

第二个 - 带有偏移的平滑点

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>


谢谢,这很棒,但为什么顶部边框看起来比图片更锐利和尖锐。 - user3741635
@user3741635 - 这是由于CSS中边框绘制的方式。请查看我刚刚添加到答案中的示例2 - 可以使用transform: skewX来平滑处理这个问题。 - misterManSam
只有一个问题,我该如何将绘图的颜色从透明改为红色? - user3741635

8

我可以使用DIV来实现,但我相信有一种更优雅的方式:

    #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>


5
尽管CSS可以实现这一点,但还有另一种方法能够提供更多的灵活性:SVG
这种方法具有以下优点:
  • 形状能够自适应内容的大小。
  • 响应式设计。
  • 可使用任何类型的背景(图像、渐变、半透明颜色等)。
  • 可使用任何类型的填充方式来填充形状(图像、渐变、半透明颜色等)。
  • 更容易控制顶部和底部曲线。

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>


我本来想添加这个功能,直到我看到其他人也需要使用SVG。 - Max Payne
1
因为它没有保持纵横比,所以形状改变了。这很好,但这导致左右笔画的描边宽度也会改变。有没有什么方法可以克服这个问题呢? - Max Payne
@TimKrul 在你的提问之前我不知道,但是有一个 vector-effect="non-scaling-stroke" 属性,可以让描边的宽度固定。但是似乎IE不支持该属性。 - web-tiki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接