我想知道是否有任何方法可以用纯 CSS 创建这个形状。为了进一步扩展这个问题,这个形状需要裁剪内部的图像(将其视为蒙版 - 但灰色边框必须可见)。
或者我最好在canvas/svg中创建它?
保持边框有点困难,但我设法使用 :before 和 :after 元素与父容器一起实现了闭合效果(:before 和 :after 不适用于 img 标签)
为容器添加边框
在前面添加一个以遮挡角并偏移-1以覆盖边框
添加一条与之前稍有偏移的后线,以在切口内创建线条
如您所见,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>
您可以使用伪代码以及
border-width
和 border-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");
使用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' />
截图:
这是可以做到的,但它是一个 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);
}
输出
参见小提琴
我有一个在线生成器,你可以从那里轻松获得这样的形状。选择您的配置,您将获得
clip-path
值
.box {
display: inline-grid;
position: relative;
/* from the generator */
clip-path: polygon(0 102.00px,102.00px 0,100% 0,100% 100%,0 100%);
}
.box:before {
content: "";
position: absolute;
inset: 0;
background: red; /* your border color */
/* from the generator*/
clip-path: polygon(0 102.00px,102.00px 0,100% 0,100% 100%,0 100%,0 102.00px,10px calc(102.00px + 4.14px),10px calc(100% - 10px),calc(100% - 10px) calc(100% - 10px),calc(100% - 10px) 10px,calc(102.00px + 4.14px) 10px,10px calc(102.00px + 4.14px));
}
<div class="box">
<img src="https://picsum.photos/id/1069/400/250">
</div>
有官方的一个衬垫:clip-path。您可以使用this辅助网页来生成所需的形状。
.container{
display: flex;
}
.shape1{
height: 200px;
width: 200px;
clip-path: polygon(36% 0, 100% 0, 100% 100%, 0 99%, 0 31%);
background-image: url("https://images.pexels.com/photos/12258844/pexels-photo-12258844.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1");
background-size:cover;
}
.shape2{
height: 200px;
width: 200px;
clip-path: polygon(20% 0%, 0% 20%, 30% 50%, 0% 80%, 20% 100%, 50% 70%, 80% 100%, 100% 80%, 70% 50%, 100% 20%, 80% 0%, 50% 30%);
background-image: url("https://images.pexels.com/photos/12258844/pexels-photo-12258844.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1");
background-size:cover;
}
.shape3{
height: 200px;
width: 200px;
clip-path: polygon(31% 5%, 89% 0, 98% 35%, 63% 52%, 100% 71%, 57% 77%, 16% 100%, 24% 66%, 2% 35%, 51% 22%);
background-image: url("https://images.pexels.com/photos/12258844/pexels-photo-12258844.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1");
background-size:cover;
}
<div class="container">
<div class="shape1"></div>
<div class="shape2"></div>
<div class="shape3"></div>
</div>