CSS3 - 特殊边框半径

CSS3 - special border-radius

我正在尝试用 CSS3 制作独特的形状。 我正在使用 Bootstrap 3 网格系统来制作元素的布局。 我已经构建了这个形状的大部分内容,但我无法让 border-radius 属性 在元素内部转一圈。

形状:

我已经做过的事情:

codepen

CSS:

.test-midbox{
    height: 170px;
    background-color: white ;
    padding-left: 0px;
    padding-right: 0px;
    margin-right: 0;
    margin-left: 0;
    border: solid black 1px;
    top: 20px;

}
.test-inbox{
    margin-right: 0;
    margin-left: 0;
    background-image: url("../images/linux.jpg") !important;
    background-repeat: no-repeat;
    background-position: center;
    background-size: auto 80%;
    height: 170px;
    padding-top:10px;
    padding-left:10px;
    padding-right:10px;
    padding-bottom:40px;
}
.monitor-name:before{
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    z-index: -2;
    display: block;
    height: 100%;
    background: black;
    opacity: 0.7;
    border-bottom-right-radius: 20px;
    border-top-right-radius: 20px;
}
.monitor-name{
    z-index: 100;
    position: absolute;
    height: 40px;
    bottom: 20px;
    text-align: center;
    color: white;
    border:black 1px solid;
    border-left: none;
    border-bottom-right-radius: 20px;
    border-top-right-radius: 20px;
}
.monitor-name-text{
    top:1px;
    text-align: center;
}
.test-puls{
    position: absolute;
    height: 20px;
    padding-left: 0px;
    padding-right: 0px;
    margin-right: 0;
    margin-left: 0;
    border-top: 1px black solid;
    bottom: 15px;
}
.btn-plus{
    border-radius: 0;
}
.btn-cir{
    border: 1px solid black;
    position: absolute;
    height: 40px;
    bottom: 20px;
    padding-left: 0px;
    padding-right: 0px;
}

HTML :

<div class="col-lg-3 test-outerbox">
    <div class="test-midbox col-lg-12">
        <div class="col-lg-12 col-lg-offset-1 test-inbox">
        </div>
        <div class="col-lg-12 col-lg-offset-1 test-puls">
        </div>
        <div class="monitor-name col-lg-10 col-lg-push-2">
            <h4 class="monitor-name-text">tsdsds</h4>
        </div>
        <div class="col-lg-2 btn-cir">k</div>
    </div>
</div>

border-radius永远只会产生向外的曲线,永远不会向内弯曲。因此,它不能单独用于产生您需要的效果。以下是产生所需效果的几种方法。您可以选择最适合您的情况。

我没有使用过基于 Twitter Bootstrap 的标记,但您应该可以直接转换。


使用 z-index:

如果所有项目都有不透明的背景(即没有 alpha 值)并且没有。元素的数量是一个有限的固定数,然后使用 z-index 将元素放置在彼此之上,这样第一个元素在第二个元素之上,而第二个元素又在第三个元素之上,依此类推。负数 margin-right 也设置为所有元素以产生重叠效果。由于背景是不透明的,它们在第一个元素上的边框看起来好像第二个元素有向内弯曲的边框,依此类推。

注意:根据提供的图片,这似乎不适合您的情况,但为完整性添加了内容。

.items {
  position: relative;
  float: left;
  height: 50px;
  width: 200px;
  margin-right: -60px;
  line-height: 50px;
  text-align: center;
  border: 1px solid brown;
}
.elongated-border-curve .items {
  border-radius: 0% 35% 35% 0% / 0% 50% 50% 0%;
}
.shorter-border-curve .items {
  border-radius: 0% 20% 20% 0% / 0% 50% 50% 0%;
}
.items:nth-of-type(n+2) {
  border-left: 0;
  background: wheat;
}
.items:first-of-type {
  background: sandybrown;
  color: white;
  z-index: 3;
}
.items:nth-of-type(2) {
  z-index: 2;  /* lower z-index than first */
}
.items:nth-of-type(3) {
  z-index: 1;  /* lower z-index than second */
}
.items:last-of-type {  /* default z-index 0 */
  border-radius: 0%;
}

/* just for demo */
h3 {
  clear: both;
}
.elongated-border-curve, .shorter-border-curve {
  padding-bottom: 50px;
}
body {
  background: radial-gradient(circle at 50% 50%, aliceblue, mediumslateblue);
  min-height: 500px;
}
<h3>With Elongated Border Curves</h3>
<div class='elongated-border-curve'>
  <div class='items'>Item 1</div>  <!-- give each item a z-index lower than the previous one -->
  <div class='items'>Item 2</div>  <!-- give each item a z-index lower than the previous one -->
  <div class='items'>Item 3</div>  <!-- give each item a z-index lower than the previous one -->
  <div class='items'>Item 4</div>  <!-- give each item a z-index lower than the previous one -->
</div>

<h3>With Shorter Border Curves</h3>
<div class='shorter-border-curve'>
  <div class='items'>Item 1</div>  <!-- give each item a z-index lower than the previous one -->
  <div class='items'>Item 2</div>  <!-- give each item a z-index lower than the previous one -->
  <div class='items'>Item 3</div>  <!-- give each item a z-index lower than the previous one -->
  <div class='items'>Item 4</div>  <!-- give each item a z-index lower than the previous one -->
</div>

动态宽度示例:

.items {
  position: relative;
  float: left;
  height: 50px;
  width: 32%;
  margin-right: -10%;
  line-height: 50px;
  text-align: center;
  border: 1px solid brown;
}
.elongated-border-curve .items {
  border-radius: 0% 35% 35% 0% / 0% 50% 50% 0%;
}
.shorter-border-curve .items {
  border-radius: 0% 20% 20% 0% / 0% 50% 50% 0%;
}
.items:nth-of-type(n+2) {
  border-left: 0;
  background: wheat;
}
.items:first-of-type {
  background: sandybrown;
  color: white;
  z-index: 3;
}
.items:nth-of-type(2) {
  z-index: 2;  /* lower z-index than first */
}
.items:nth-of-type(3) {
  z-index: 1;  /* lower z-index than second */
}
.items:last-of-type {  /* default z-index 0 */
  border-radius: 0%;
}

/* just for demo */
h3 {
  clear: both;
}
.elongated-border-curve, .shorter-border-curve {
  padding-bottom: 50px;
}
body {
  background: radial-gradient(circle at 50% 50%, aliceblue, mediumslateblue);
  min-height: 500px;
}
<h3>With Elongated Border Curves</h3>
<div class='elongated-border-curve'>
  <div class='items'>Item 1</div>  <!-- give each item a z-index lower than the previous one -->
  <div class='items'>Item 2</div>  <!-- give each item a z-index lower than the previous one -->
  <div class='items'>Item 3</div>  <!-- give each item a z-index lower than the previous one -->
  <div class='items'>Item 4</div>  <!-- give each item a z-index lower than the previous one -->
</div>

<h3>With Shorter Border Curves</h3>
<div class='shorter-border-curve'>
  <div class='items'>Item 1</div>  <!-- give each item a z-index lower than the previous one -->
  <div class='items'>Item 2</div>  <!-- give each item a z-index lower than the previous one -->
  <div class='items'>Item 3</div>  <!-- give each item a z-index lower than the previous one -->
  <div class='items'>Item 4</div>  <!-- give each item a z-index lower than the previous one -->
</div>


带框阴影:

如果所有项目都有纯色背景(不透明或透明)但没有。元素的数量不是有限的就是很大(因此使以前的方法难以采用),请在伪元素上使用具有较大传播半径的 box-shadow ,如下面的代码片段所示。

当元素具有渐变或图像作为背景时,此方法将不起作用。

.items {
  float: left;
  height: 50px;
  width: 200px;
  margin-right: -60px;
  line-height: 50px;
  text-align: center;
  border: 1px solid brown;
}
.elongated-border-curve .items {
  border-radius: 0% 35% 35% 0% / 0% 50% 50% 0%;
}
.shorter-border-curve .items {
  border-radius: 0% 20% 20% 0% / 0% 50% 50% 0%;
}
.items:first-of-type {
  z-index: 3;
}
.items:nth-of-type(n+2) {
  position: relative;
  border-left: 0;
  overflow: hidden;
}
.items:nth-of-type(n+2):after {
  position: absolute;
  content: '';
  height: 100%;
  width: 100%;
  top: 0px;
  left: -140px;  /* -(parent's margin-right) - width of element */
  z-index: -1;
}
.elongated-border-curve .items:nth-of-type(n+2):after {
  border-radius: 0% 35% 35% 0% / 0% 50% 50% 0%;
}
.shorter-border-curve .items:nth-of-type(n+2):after {
  border-radius: 0% 20% 20% 0% / 0% 50% 50% 0%;
}
.items:last-of-type {
  border-radius: 0%;
}
.opaque-bg .items:first-of-type {
  background: sandybrown;
  color: white;
}
.semi-transparent-bg .items:first-of-type {
  background: rgba(0, 0, 0, 0.5);
  color: white;
}
.opaque-bg .items:nth-of-type(n+2):after {
  box-shadow: 0px 0px 0px 200px wheat;
}
.semi-transparent-bg .items:nth-of-type(n+2):after {
  box-shadow: 0px 0px 0px 200px rgba(127, 127, 127, 0.5);
}

/* just for demo */
h3 {
  clear: both;
}
.opaque-bg, .semi-transparent-bg {
  padding-bottom: 50px;
}
body {
  background: radial-gradient(circle at 50% 50%, aliceblue, mediumslateblue);
  min-height: 500px;
}
<h3>Items have a solid opaque background + Elongated Border Curves</h3>
<div class='opaque-bg elongated-border-curve'>
  <div class='items'>Item 1</div>
  <div class='items'>Item 2</div>
  <div class='items'>Item 3</div>
  <div class='items'>Item 4</div>
</div>

<h3>Items have a solid semi-transparent background + Elongated Border Curves</h3>
<div class='semi-transparent-bg elongated-border-curve'>
  <div class='items'>Item 1</div>
  <div class='items'>Item 2</div>
  <div class='items'>Item 3</div>
  <div class='items'>Item 4</div>
</div>

<h3>Items have a solid opaque background + Shorter Border Curves</h3>
<div class='opaque-bg  shorter-border-curve'>
  <div class='items'>Item 1</div>
  <div class='items'>Item 2</div>
  <div class='items'>Item 3</div>
  <div class='items'>Item 4</div>
</div>

<h3>Items have a solid semi-transparent background + Shorter Border Curves</h3>
<div class='semi-transparent-bg  shorter-border-curve'>
  <div class='items'>Item 1</div>
  <div class='items'>Item 2</div>
  <div class='items'>Item 3</div>
  <div class='items'>Item 4</div>
</div>

动态宽度示例:

.items {
  float: left;
  height: 50px;
  width: 32%;
  margin-right: -10%;
  line-height: 50px;
  text-align: center;
  border: 1px solid brown;
}
.elongated-border-curve .items {
  border-radius: 0% 35% 35% 0% / 0% 50% 50% 0%;
}
.shorter-border-curve .items {
  border-radius: 0% 20% 20% 0% / 0% 50% 50% 0%;
}
.items:first-of-type {
  z-index: 3;
}
.items:nth-of-type(n+2) {
  position: relative;
  border-left: 0;
  overflow: hidden;
}
.items:nth-of-type(n+2):after {
  position: absolute;
  content: '';
  height: 100%;
  width: 100%;
  top: 0px;
  left: -69%;  /* -(parent's margin-right) - width of element */
  z-index: -1;
}
.elongated-border-curve .items:nth-of-type(n+2):after {
  border-radius: 0% 35% 35% 0% / 0% 50% 50% 0%;
}
.shorter-border-curve .items:nth-of-type(n+2):after {
  border-radius: 0% 20% 20% 0% / 0% 50% 50% 0%;
}
.items:last-of-type {
  border-radius: 0%;
}
.opaque-bg .items:first-of-type {
  background: sandybrown;
  color: white;
}
.semi-transparent-bg .items:first-of-type {
  background: rgba(0, 0, 0, 0.5);
  color: white;
}
.opaque-bg .items:nth-of-type(n+2):after {
  box-shadow: 0px 0px 0px 999px wheat;
}
.semi-transparent-bg .items:nth-of-type(n+2):after {
  box-shadow: 0px 0px 0px 999px rgba(127, 127, 127, 0.5);
}

/* just for demo */
h3 {
  clear: both;
}
.opaque-bg, .semi-transparent-bg {
  padding-bottom: 50px;
}
body {
  background: radial-gradient(circle at 50% 50%, aliceblue, mediumslateblue);
  min-height: 500px;
}
<h3>Items have a solid opaque background + Elongated Border Curves</h3>
<div class='opaque-bg elongated-border-curve'>
  <div class='items'>Item 1</div>
  <div class='items'>Item 2</div>
  <div class='items'>Item 3</div>
  <div class='items'>Item 4</div>
</div>

<h3>Items have a solid semi-transparent background + Elongated Border Curves</h3>
<div class='semi-transparent-bg elongated-border-curve'>
  <div class='items'>Item 1</div>
  <div class='items'>Item 2</div>
  <div class='items'>Item 3</div>
  <div class='items'>Item 4</div>
</div>

<h3>Items have a solid opaque background + Shorter Border Curves</h3>
<div class='opaque-bg  shorter-border-curve'>
  <div class='items'>Item 1</div>
  <div class='items'>Item 2</div>
  <div class='items'>Item 3</div>
  <div class='items'>Item 4</div>
</div>

<h3>Items have a solid semi-transparent background + Shorter Border Curves</h3>
<div class='semi-transparent-bg  shorter-border-curve'>
  <div class='items'>Item 1</div>
  <div class='items'>Item 2</div>
  <div class='items'>Item 3</div>
  <div class='items'>Item 4</div>
</div>

我认为 box-shadow 方法应该适用于您的情况。 如果没有,那么唯一的其他选择就是使用 SVGclip-path 可以在不使用 SVG 的情况下帮助实现这一点,但目前浏览器支持非常差。