CSS 如何实现倒角CSS边框角而不是圆角?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14770312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 21:36:34  来源:igfitidea点击:

How to achieve chamfered CSS Border Corners rather than rounded corners?

bordercsscss-shapes

提问by Mayeenul Islam

With the CSS border-radiusproperty I can have a curvy, rounded border corner at the end.

使用 CSSborder-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;
}

But I want a border corner like the image below. If I have two boxes (Yellow & Pink) meeting each other and I want a harsh corner at the bottom meeting point (dotted corner), what should I do?

但我想要一个像下图这样的边框角。如果我有两个盒子(黄色和粉红色)相遇,我想在底部相遇点(虚线角)有一个粗糙的角落,我该怎么办?

enter image description here

在此处输入图片说明

Is that possible using CSS?

可以使用 CSS 吗?

采纳答案by thordarson

Here's a way, although it does have some shortcomings, like no borders and it isn't transparent:

这是一种方法,尽管它确实有一些缺点,例如没有边框且不透明:

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

RESULT:

结果:

enter image description here

在此处输入图片说明

Here's a fiddle.

这是一个小提琴。

回答by AlphaMale

CSS3 Gradientscan do the trick:

CSS3 渐变可以做到这一点:

Try this, Here's a Fiddle.

试试这个,这是一个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>

回答by Collins

This is also possible using "clip-path".

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

-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%);
}
<div></div>

Source Codepen

源代码笔

Support for clip-path can be found here... http://caniuse.com/#search=clip-path

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

回答by Bruno

This is what you need, transparency and everything

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

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

回答by gearsdigital

A good The bestway to archive this: border-images. In combination with .svga good solution...

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

回答by Ogglas

I first tested @thordarson solution with position: 'absolute'.

我首先使用position: 'absolute'.

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

This worked fine on most devices as shown in the first picture but when used on iPhones or tablets weird lines started showing up:

这在大多数设备上运行良好,如第一张图所示,但在 iPhone 或平板电脑上使用时,开始出现奇怪的线条:

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

As @Collins answer I then started using clip-path: polygonbut I had quite a hard time getting the correct shapes. I then found a site that really helped me:

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

https://bennettfeely.com/clippy/

https://bennettfeely.com/clippy/

They offer ready shapes that can then be dragged to a desired shape.

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

enter image description here

在此处输入图片说明

For the corner that I needed I could then copy the correct values from the website.

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

enter image description here

在此处输入图片说明

A requirement for us was a 35° angle and to get that right I used the site:

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

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

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

enter image description here

在此处输入图片说明

I have no affiliation with any of the sites, they just really helped me get what I wanted. With clip-path: polygonand -webkit-clip-path: polygonit worked on all devices and browsers that we had as a requirement.

我与任何网站都没有隶属关系,它们只是真正帮助我获得了我想要的东西。随着clip-path: polygon-webkit-clip-path: polygon它的工作在所有设备上,而且我们有一个要求浏览器。

Compatibility check:

兼容性检查:

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

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

回答by Casual Bob

++ Includes Westworld Style UI in CSS ++

++ 在 CSS 中包含西部世界风格的 UI ++

I've updated AlphaMale's awesome answer to hack chamfered borders as originally requested. It basically uses one chamfered div with a slightly smaller on inside it. The outer div's background colour becomes the border colour when the rest of it is covered up by the inner div with matching chamfers.

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

Tested in Edge, Chrome and Firefox.

在 Edge、Chrome 和 Firefox 中测试。

I found this page while looking to duplicate something like the Westworld User Interfacewhich has unequal chamfered corners. See the JS fiddle for how I've cobbled this together along with a colour scheme and example box from the Westworld speech chaining scene.

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

Code on JSFiddle (CSS below): http://jsfiddle.net/S2nqK/345/

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

Westworld UI pic at: https://qph.ec.quoracdn.net/main-qimg-44c9f03b2abfe9f3833763eece1b0cc4?convert_to_webp=true

西部世界 UI 图片: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}

回答by Ramon

Ok, so I made a JS libraryto automate creating chamfered borders. It has two methods for creating the chamfers:

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

Method 1:it creates a chamferedbackground using Canvas API and set it as the CSS background-imageof the element.

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

Method 2:it appends 4 CSS based triangle DOM elements around the target, making the chamfer.

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

You will stick with method 1 when you can let the library set the background-image, and you will need method 2 when your target already has a background, like in <img>'s.

当您可以让库设置 时,您将坚持使用方法 1 background-image,当您的目标已经有背景时,您将需要方法 2,例如在 <img> 中。

The usage is simple, just call ChamferBgfor using method 1, or ChamferEnvelopto use method 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
});

The options and their defaults are:

选项及其默认值是:

{
    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
}

You will need to set resize_observeto true if you use method 1and your element may change its size at runtime, because then it will need to recreate the chamfered background every time it resizes.

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