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

半世苍凉 提交于 2019-11-27 07:41:23
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:

Here's a fiddle.

AlphaMale

CSS3 Gradients can do the trick:

Try this, Here's a 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>
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

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>

A good The best way to archive this: border-images. In combination with .svg a good solution...

++ Includes Westworld Style UI in CSS ++

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.

Tested in Edge, Chrome and Firefox.

I found this page while looking to duplicate something like the Westworld User Interface which 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.

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

Westworld UI pic at: 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}

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

Method 1: it creates a chamfered background using Canvas API and set it as the CSS background-image of the element.

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

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.

The usage is simple, just call ChamferBg for using method 1, or ChamferEnvelop to use method 2:

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_observe to true if you use method 1 and your element may change its size at runtime, because then it will need to recreate the chamfered background every time it resizes.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!