36

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

在此处输入图像描述

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

4

4 回答 4

35

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

  1. 为容器添加边框

  2. 添加一个 before 以遮挡一个角并偏移 -1 以覆盖边框

  3. 添加一个与之前略有偏移的之后,以在切断内创建线条

如您所见,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

于 2013-10-08T13:27:34.620 回答
13

查看演示

您可以通过使用伪来做到这一点,border-widthborder-color查看下面的代码以了解它是如何完成的。

HTML

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

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

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

在这里查看演示

HTML

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

CSS

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

JS

$(".cut").corner("bevel tl 50px");
于 2013-10-08T13:19:53.613 回答
10

使用 CSS:

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

如果形状的内部只有一种颜色(纯色或透明),则可以仅使用一个元素来实现。但是,如果需要在形状内添加图像(如问题中所述),那么我们需要多个元素,因为我们必须反转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>


使用 SVG:

或者,可以使用 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' />

截屏:

在此处输入图像描述

于 2015-06-09T10:27:44.797 回答
3

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

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

HTML

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

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);
}

输出

剪裁角

小提琴

于 2013-10-08T13:19:45.910 回答