是否可以在 CSS 中创建一个斜角?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19248443/
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-30 00:38:48  来源:igfitidea点击:

Is it possible to create an angled corner in CSS?

csscss-shapes

提问by user2307706

I am wondering if there is any way to create this shape with pure CSS. To extend this problem further, this shape needs to clip the image inside (think of it as a mask - but the grey border has to be visible).

我想知道是否有任何方法可以用纯 CSS 创建这个形状。为了进一步扩展这个问题,这个形状需要剪辑内部的图像(把它想象成一个蒙版——但灰色边框必须是可见的)。

enter image description here

在此处输入图片说明

Or am I better off creating this in canvas/svg?

还是我最好在 canvas/svg 中创建它?

采纳答案by Matt.C

It's a little difficult keeping the border, but I managed to achieve a close effect using :before and :after elements with a parent container (:before and :after don't work on an img tag)

保持边框有点困难,但我设法使用 :before 和 :after 元素与父容器实现了接近的效果(:before 和 :after 不适用于 img 标签)

  1. Add a border to the container

  2. Add a before to block out a corner and offset by -1 to cover the border

  3. Add an after that's slightly offset from the before to create the line inside the cut off

  1. 为容器添加边框

  2. 添加一个 before 来挡住一个角落并偏移 -1 以覆盖边界

  3. 添加一个与之前稍微偏移的之后以在切断内部创建线

As you can see, the thickness of the 45deg line is a bit of an issue:

如您所见,45 度线的粗细有点问题:

.cutCorner {
    position:relative; background-color:blue; 
    border:1px solid silver; display: inline-block;
}

.cutCorner img {
    display:block;
}

.cutCorner:before {
    position:absolute; left:-1px; top:-1px; content:'';
    border-top: 70px solid silver;
    border-right: 70px solid transparent;
}

.cutCorner:after {
    position:absolute; left:-2px; top:-2px; content:'';
    border-top: 70px solid white;
    border-right: 70px solid transparent;
}
<div class="cutCorner">
    <img class="" src="https://www.google.co.uk/logos/doodles/2013/william-john-swainsons-224th-birthday-5655612935372800-hp.jpg" />
</div>

JSFiddle

JSFiddle

回答by Vikas Ghodke

SEE THE DEMO

查看演示

You can do this by using pseudo, along with border-widthand border-colorsee the below code to see how it can be done.

您可以通过使用伪代码来完成此操作,border-widthborder-color查看以下代码以了解如何完成。

HTML

HTML

<div class="cut"></div>

CSS

CSS

.cut {
    position:relative;
    width:500px;
    height: 200px;
    padding:20px;
    color:#000;
    background:#ccc;
}

.cut:before {
    content:"";
    position:absolute;
    top:0;
    left:0;
    border-width:30px 30px 0px 0px;
    border-style:solid;
    border-color:#fff transparent transparent #fff ;
}

Another Solution using this jQuery script for cross browser support. -->http://jquery.malsup.com/corner/

使用此 jQuery 脚本进行跨浏览器支持的另一种解决方案。--> http://jquery.malsup.com/corner/

SEE THE DEMO HERE

在此处查看演示

HTML

HTML

<div class="cut"></div>

CSS

CSS

.cut {
    position:relative;
    width:500px;
    height: 200px;
    padding:20px;
    color:#000;
    background:#ccc;
}

JS

JS

$(".cut").corner("bevel tl 50px");

回答by Harry

Using CSS:

使用 CSS:

The exact shape can be achieved using CSS. The idea is to have an element with a border-radiusfor the top-left corner, skew it along the Y axis and then position it just before the rectangle. Doing these would make it look as though the rectangular element has a triangular cut at the top with one curved edge.

使用 CSS 可以实现精确的形状。这个想法是有一个border-radius左上角带有 a 的元素,沿着 Y 轴倾斜它,然后将它定位在矩形之前。这样做会使矩形元素看起来好像在顶部有一个三角形切口,有一个弯曲的边缘。

If the inside part of the shape has only a color (solid or transparent) then it can be achieved using only one element. However, if an image needs to be added inside the shape (like mentioned in question), then we need more than one element because we have to reverse the skeweffect on the image and this cannot be done without a child element.

如果形状的内部只有一种颜色(纯色或透明),则可以仅使用一个元素来实现。但是,如果需要在形状内部添加图像(如问题中提到的),那么我们需要多个元素,因为我们必须反转skew对图像的影响,而没有子元素就无法做到这一点。

.shape,
.shape-image {
  position: relative;
  height: 150px;
  width: 400px;
  border-bottom: 2px solid crimson;
  overflow: hidden;
}
.shape:before,
.shape:after,
.shape-image:after {
  position: absolute;
  content: '';
  top: 0px;
  height: 100%;
  z-index: -1;
}
.shape:before,
.shape-image .before {
  left: 0px;
  top: -2px;
  width: 50px;
  border: 2px solid crimson;
  border-width: 3px 0px 0px 2px;
  border-top-left-radius: 8px;
  transform-origin: right bottom;
  transform: skewY(-45deg);
}
.shape:after,
.shape-image:after {
  left: 52px;
  width: calc(100% - 54px);
  border: 2px solid crimson;
  border-left: none;
}
.shape:after,
.shape:before {
  background: aliceblue;
}
.shape.semi-transparent:after,
.shape.semi-transparent:before {
  background: rgba(150, 150, 150, 0.5);
}
.shape-image .before {
  position: absolute;
  top: 0px;
  height: 100%;
  overflow: hidden;
}
.shape-image .before .img {
  height: 100%;
  width: 100%;
  border-top-left-radius: 8px;
  background: url(http://lorempixel.com/400/150);
  transform-origin: right bottom;
  transform: skewY(45deg);
}
.shape-image:after {
  background: url(http://lorempixel.com/400/150);
  background-position: -50px 0px;
}

/* Just for demo */

body{
  background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
.shape{
  margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="shape"></div>
<div class="shape semi-transparent"></div>
<div class="shape-image">
  <div class="before">
    <div class="img"></div>
  </div>
</div>



Using SVG:

使用 SVG:

Alternately the same can be achieved in a more hassle free way with SVG like in the below snippet.

或者,可以使用 SVG 以更轻松的方式实现相同的效果,如下面的代码片段所示。

.vector {
  height: 150px;
  width: 410px;
  padding-left
}
svg {
  height: 100%;
  width: 100%;
}
path {
  stroke: crimson;
  stroke-width: 2;
  fill: none;
}
polygon {
  fill: url(#bg);
}

/* Just for demo */

body {
  background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='vector'>
  <svg viewBox='0 0 400 150' preserveAspectRatio='none'>
    <defs>
      <path d='M50,2 h 342 v144 h-390 v-90 a6,12 0 0,1 3,-9 z' id='p' />
      <clipPath id='clipper'>
        <use xlink:href='#p' />
      </clipPath>
      <pattern id='bg' width='400' height='150' patternUnits='userSpaceOnUse'>
        <image xlink:href='http://lorempixel.com/400/150' height='150' width='400' />
      </pattern>
    </defs>
    <polygon points='2,2 392,2 392,148 2,148' clip-path='url(#clipper)' />
    <use xlink:href='#p' />
  </svg>
</div>
<h3>Original Image</h3>
<img src='http://lorempixel.com/400/150' />

Screenshot:

截屏:

enter image description here

在此处输入图片说明

回答by ediblecode

It is possible to do this, but it is a CSS3 solution so won't work on older browsers I don't think.

可以这样做,但它是一个 CSS3 解决方案,因此我认为不适用于较旧的浏览器。

What I've done is, I've created two divs, one has a border all around, and the other has a border only on the bottom. Using translateI've then rotated that div 45 degrees to mask the corner of the other div, giving the desired effect.

我所做的是,我创建了两个 div,一个四周有边框,另一个只有底部有边框。translate然后使用我将该 div 旋转 45 度以掩盖另一个 div 的角落,从而产生所需的效果。

HTML

HTML

<div class="holder">
    <div class="main"></div>
    <div class="corner"></div>
</div>

CSS

CSS

.holder { 
    position:relative;
    width: 180px;
    margin:30px
}

.main {
    width: 160px;
    height: 40px;
    border: 1px solid grey;
    position:absolute; 
    left:0;
    z-index: 1;
}
.corner { 
    border-bottom: 1px solid grey;
    width:30px; 
    height: 41px; 
    position:absolute;
    top:-25px;
    right:0;
    z-index:2;
    background:#fff;

    /* Safari */
    -webkit-transform: rotate(45deg);    
    /* Firefox */
    -moz-transform: rotate(45deg);    
    /* IE */
    -ms-transform: rotate(45deg);    
    /* Opera */
    -o-transform: rotate(45deg);
}

Output

输出

Clipped corner

剪角

See Fiddle

小提琴