【问题标题】:How to achieve chamfered CSS Border Corners rather than rounded corners?如何实现倒角 CSS Border Corners 而不是圆角?
【发布时间】:2013-01-24 02:03:19
【问题描述】:

使用 CSS border-radius 属性,我可以在末尾有一个弯曲的圆角边框。

.boxLeft{
    border-right: 1px dashed #333;
    border-bottom: 1px dashed #333;
    border-radius: 0 0 10px 0;
}

.boxRight{
    border-left: 1px dashed #333;
    border-bottom: 1px dashed #333;
    border-radius: 0 0 0 10px;
}

但我想要一个如下图所示的边框。如果我有两个盒子(黄色和粉色)相互交汇,我想在底部交汇点(虚线角)有一个粗糙的角落,我应该怎么做?

这可能使用 CSS 吗?

【问题讨论】:

  • 你应该使用类似(伪代码).boxLeft + .boxRight {border-bottom-left-radius:0} - 记不清了。我有类似的东西,如果我找到它会发布。
  • 有趣的问题!您可能想用 :after 选择器做一些事情,但我不确定这是否可行。看看这个:jtauber.github.com/articles/css-hexagon.html

标签: border css css-shapes


【解决方案1】:

CSS3 渐变可以解决问题:

试试这个,这是Fiddle

div {
  background: #c00;
  /* fallback */
  background: -moz-linear-gradient(45deg, transparent 10px, #c00 10px), -moz-linear-gradient(135deg, transparent 10px, #c00 10px), -moz-linear-gradient(225deg, transparent 10px, #c00 10px), -moz-linear-gradient(315deg, transparent 10px, #c00 10px);
  background: -o-linear-gradient(45deg, transparent 10px, #c00 10px), -o-linear-gradient(135deg, transparent 10px, #c00 10px), -o-linear-gradient(225deg, transparent 10px, #c00 10px), -o-linear-gradient(315deg, transparent 10px, #c00 10px);
  background: -webkit-linear-gradient(45deg, transparent 10px, #c00 10px), -webkit-linear-gradient(135deg, transparent 10px, #c00 10px), -webkit-linear-gradient(225deg, transparent 10px, #c00 10px), -webkit-linear-gradient(315deg, transparent 10px, #c00 10px);
}

div {
  background-position: bottom left, bottom right, top right, top left;
  -moz-background-size: 50% 50%;
  -webkit-background-size: 50% 50%;
  background-size: 50% 50%;
  background-repeat: no-repeat;
}


/* Ignore the CSS from this point, it's just to make the demo more presentable */

div {
  float: left;
  width: 50px;
  margin: 15px auto;
  padding: 15px;
  color: white;
  line-height: 1.5;
}
<div>Div 1</div>
<div>Div 2</div>

【讨论】:

【解决方案2】:

这是一种方法,虽然它确实有一些缺点,比如没有边框并且不透明:

.left,
.right {
  width: 100px;
  height: 100px;
  float: left;
  position: relative;
}

.left {
  background: lightpink;
}

.right {
  background: lightblue;
}

.right::after,
.left::after {
  width: 0px;
  height: 0px;
  background: #fff;
  content: '';
  position: absolute;
  bottom: 0;
}

.right::after {
  left: 0;
  border-top: 10px solid lightblue;
  border-right: 10px solid lightblue;
  border-left: 10px solid white;
  border-bottom: 10px solid white;
}

.left::after {
  right: 0;
  border-top: 10px solid lightpink;
  border-right: 10px solid white;
  border-left: 10px solid lightpink;
  border-bottom: 10px solid white;
}
<div class="left"></div>
<div class="right"></div>

结果:

Here's a fiddle.

【讨论】:

  • this instructional demo page 中所示的一个有价值的更新使用transparent 作为“边框”切口的颜色名称。 CSS 示例:border-bottom:30px solid transparent;。享受吧!
【解决方案3】:

这也可以使用“剪辑路径”。

-webkit-clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);
clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);

div {
  width: 200px;
  height: 200px;
  background: red;
  -webkit-clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);
  clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);
}
&lt;div&gt;&lt;/div&gt;

Source Codepen

可以在这里找到对剪辑路径的支持...http://caniuse.com/#search=clip-path

【讨论】:

  • 这是我最喜欢的方式,请注意目前 IE 不支持它。
  • 是的,但“不受支持”只是意味着它会退回到原始图像形状。相当优雅的后备,以及获得效果的好方法。
【解决方案4】:

这就是你所需要的,透明度和一切

.left,
.right {
  width: 100px;
  height: 100px;
  float: left;
  position: relative;
  overflow: hidden;
}

.right::after,
.left::after {
  content: '';
  width: 200px;
  height: 200px;
  position: absolute;
  -moz-transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
}

.right::after {
  background: lightblue;
  left: -40px;
  top: -100px;
}

.left::after {
  background: lightpink;
  left: -60px;
  top: -100px;
}
<div class="left"></div>
<div class="right"></div>

【讨论】:

【解决方案5】:

一个很好的最好的存档方式:border-images。结合.svg 一个很好的解决方案...

【讨论】:

    【解决方案6】:

    我首先使用position: 'absolute' 测试了@thordarson 解决方案。

    position: 'absolute',
    top: '2.9rem',
    left: '2.6rem',
    borderLeft: '1rem solid #6CAEC6',
    borderBottom: '0.7rem solid white',
    

    这在大多数设备上都可以正常工作,如第一张图片所示,但在 iPhone 或平板电脑上使用时开始出现奇怪的线条:

    作为@Collins 的回答,我随后开始使用clip-path: polygon,但我很难获得正确的形状。然后我找到了一个对我很有帮助的网站:

    https://bennettfeely.com/clippy/

    它们提供现成的形状,然后可以拖动到所需的形状。

    对于我需要的角落,我可以从网站上复制正确的值。

    我们的要求是 35° 角,为了做到这一点,我使用了该网站:

    https://www.ginifab.com/feeds/angle_measurement/

    我与任何网站都没有从属关系,它们只是真的帮助我得到了我想要的东西。使用clip-path: polygon-webkit-clip-path: polygon,它可以在我们要求的所有设备和浏览器上运行。

    兼容性检查:

    https://caniuse.com/#feat=css-clip-path

    【讨论】:

      【解决方案7】:

      ++ 在 CSS ++ 中包含 Westworld 样式 UI

      我已按照最初的要求更新了 AlphaMale 破解倒角边框的绝妙答案。它基本上使用一个倒角的 div,里面有一个稍微小一点的 div。当外部 div 的其余部分被具有匹配倒角的内部 div 覆盖时,外部 div 的背景颜色成为边框颜色。

      在 Edge、Chrome 和 Firefox 中测试。

      我在想要复制类似 Westworld 用户界面 之类的东西时发现了这个页面,该界面具有不相等的倒角。请参阅 JS fiddle,了解我如何将其与来自 Westworld 语音链接场景的配色方案和示例框拼凑在一起。

      JSFiddle 上的代码(以下 CSS):http://jsfiddle.net/S2nqK/345/

      西部世界用户界面图片:https://qph.ec.quoracdn.net/main-qimg-44c9f03b2abfe9f3833763eece1b0cc4?convert_to_webp=true

      body {background-color: #353535;
      font-family: 'Open Sans';}
      .div-outer {
      
       /* Chrome / Safari */
          background:
              -webkit-linear-gradient(45deg,  transparent 0px, #6ea1a1 0px), /* bottom left */
              -webkit-linear-gradient(135deg, transparent 14px, #6ea1a1 14px), /* bottom right */
              -webkit-linear-gradient(225deg, transparent 0px, #6ea1a1 0px), /* top right */
              -webkit-linear-gradient(315deg, transparent 5px, #6ea1a1 5px); /* top left */
      
          /* Firefox */
              background:
              -moz-linear-gradient(45deg,  transparent 0px, #6ea1a1 0px), /* bottom left */
              -moz-linear-gradient(135deg, transparent 14px, #6ea1a1 14px), /* bottom right */
              -moz-linear-gradient(225deg, transparent 0px, #6ea1a1 0px), /* top right */
              -moz-linear-gradient(315deg, transparent 5px, #6ea1a1 5px); /* top left */
      
           /* Opera */
              background:
              -o-linear-gradient(45deg,  transparent 0px, #6ea1a1 0px), /* bottom left */
              -o-linear-gradient(135deg, transparent 14px, #6ea1a1 14px), /* bottom right */
              -o-linear-gradient(225deg, transparent 0px, #6ea1a1 0px), /* top right */
              -o-linear-gradient(315deg, transparent 5px, #6ea1a1 5px); /* top left */
      
      
         padding: 2px;
         color: #fff;
      
      }
      
      .div-inner {
      
      
          background:
              -webkit-linear-gradient(45deg,  transparent 0px, #000 0px),
              -webkit-linear-gradient(135deg, transparent 14px, #000 14px),
              -webkit-linear-gradient(225deg, transparent 0px, #000 0px),
              -webkit-linear-gradient(315deg, transparent 5px, #000 5px);
      
               background:
              -moz-linear-gradient(45deg,  transparent 0px, #000 0px),
              -moz-linear-gradient(135deg, transparent 14px, #000 14px),
              -moz-linear-gradient(225deg, transparent 0px, #000 0px),
              -moz-linear-gradient(315deg, transparent 5px, #000 5px);
      
               background:
              -o-linear-gradient(45deg,  transparent 0px, #000 0px),
              -o-linear-gradient(135deg, transparent 14px, #000 14px),
             -o-linear-gradient(225deg, transparent 0px, #000 0px),
              -o-linear-gradient(315deg, transparent 5px, #000 5px);
      
      
         padding: 10px;
      
         height: 92px;
         text-align: center;
      }
      
      
      .div-outer, .div-inner {
          background-position: bottom left, bottom right, top right, top left;
          -moz-background-size: 50% 50%;
          -webkit-background-size: 50% 50%;
          background-size: 50% 50%;
          background-repeat: no-repeat;
      }
      
      .contain {
         width: 180px;
      }
      .title {background-color: #76ffff; 
        padding: 6px;
        color: #000;
        border-radius: 2px;
        font-weight: bold;
       text-align-last: justify;
       text-align: justify;
        }
      .font-large {font-size: 34pt;}
      .font-tiny {font-size: 10pt;}
      .cyan {color: #76ffff;}
      /* Ignore the CSS from this point, it's just to make the demo more presentable */
      
      .arrow-right {
        width: 0; 
        height: 0; 
        border-top: 8px solid transparent;
        border-bottom: 8px solid transparent;
        border-left: 8px solid #fff;
        display: inline-block;
        vertical-align: middle;
      }
      
      
      p:first-of-type { margin-top: 0 }
      p:last-of-type { margin-bottom: 0}
      

      【讨论】:

      • 仅供参考,至少在 Chrome 中,奇数像素的高度和宽度会在 div 的中间形成一条带有倒角的线。比我聪明的人必须看看他们是否能解决这个问题!
      【解决方案8】:

      好的,所以我创建了一个JS library 来自动创建倒角边框。 它有两种创建倒角的方法:

      方法一:它使用Canvas API创建一个倒角背景,并将其设置为元素的CSS background-image

      方法2:它在目标周围附加4个基于CSS的三角形DOM元素,制作倒角。

      当你可以让库设置background-image时,你会坚持使用方法1,当你的目标已经有背景时,你将需要方法2,就像在中一样。

      用法很简单,调用ChamferBg使用方法一,或者ChamferEnvelop使用方法二:

      var el = document.getElementById('box');
      ChamferBg(el, {
          size: 20,
          sw: 6,
          sc: '#447aec',
          fc: '#21ceff',
          tl: false,
          br: false,
          resize_observe: true
      });
      

      选项及其默认值是:

      {
          size: 5,    // chamfer size
          sw: 1,      // stroke width
          sc: 'black',    // stroke color,
          fc: undefined,  // fill color
          fp: undefined,  // URL of an image to use as fill pattern
      
          tl: true,   // chamfer top-left corner?
          tr: true,   // chamfer top-right corner?
          bl: true,   // chamfer bottom-left corner?
          br: true,   // chamfer bottom-right corner?
      
          resize_observe: false
          // turn on resize_observe observer?
          // this will observer whenever the element
          // resizes and will refresh the background
      }
      

      如果您使用方法1,您需要将resize_observe 设置为true,并且您的元素可能会在运行时更改其大小,因为这样每次调整大小时都需要重新创建倒角背景。

      【讨论】:

      • 仅仅链接到您自己的库或教程并不是一个好的答案。链接到它,解释它解决问题的原因,提供如何解决问题的代码,并否认你编写了它,以获得更好的答案。见:What signifies “Good” self promotion?
      • @Ramon 在 SO 推广时至少说明您与 MISoftware 和 Chamfer.js 库/脚本的连接......
      • 伙计们,希望它现在是一个有用的答案。如果有什么办法可以改进,请告诉我...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-09
      • 2011-10-11
      • 2019-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多