何大小成

CSS · 多边形 · 切角效果

拿到一份设计稿,看到很多数据大屏的元素,比如:图表,数字。其中有个需求是这样的:

切角效果是一种常见的视觉风格设计。但是现在在CSS里,依然无法简单的生成切角效果。
很多人第一时间想到:

  • 针对外面那层边框,切三块,左边和右边一块,中间一块,然后三个
    组成一个元素。

那么有没有更便捷 && 现代的方法?

CSS中linear-gradient能帮到我们。

切角其实就是将某些地方设置背景色为transparent进行隐藏。

切一个角


1
2
3
4
div {
background: #58a;
background: linear-gradient(-135deg, transparent 1.41em, #58a 0);
}

LinearGradient语法:

1
background: linear-gradient(direction/angle, color-stop1, color-stop2, ...)

切两个角

切两个角,那么直接加多一个渐变行不行呢?

1
2
3
4
div {
background: #58a;
background: linear-gradient(-45deg, transparent 15px, #58a 0), linear-gradient(45deg, transparent 15px, red 0);
}

那么怎么办?

background-size 缩小一半

我们需要把它们变小,通过使用background-size来让每个渐变都只应用于元素的一半。

1
2
3
4
5
div {
background: #58a;
background: linear-gradient(-45deg, transparent 15px, #58a 0), linear-gradient(45deg, transparent 15px, red 0);
background-size: 50% 100%;
}


还是不够的,这不是我们要的。那么因为我们还没修改background-repeat

background-repeat 禁止重复

忘了修改background-repeat:no-repeat,所以我们的背景就都重复了两次。

1
2
3
4
5
6
div {
background: #58a;
background: linear-gradient(-45deg, transparent 15px, #58a 0), linear-gradient(45deg, transparent 15px, red 0);
background-size: 50% 100%;
background-repeat: no-repeat;
}


只要改下颜色就完成了。

实战

那么如果要实现文章开头所提出的图形应该怎么办?
有2个思路:

  1. 两个<div>元素,一个是内容里面的,一个是边框外面的。
  2. 一个<div>元素,通过:before和:after伪类元素构造。

那么,我选择了第二种.

通过:before和:after伪类元素构造

(写成了mixins形式)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@mixin polyShpae($bg,$borderBg,$border-width,$transFormWidth) {
$boder:$border-width * 2;
z-index: 0;
position: relative;
display: inline-block;

&:before {
content: '';
position: absolute;
z-index: -1;
width: 100%;
height: 100%;
background: linear-gradient(-45deg, transparent $transFormWidth, $borderBg 0) right, linear-gradient(135deg, transparent $transFormWidth, $borderBg 0) top left;
background-size: 50% 100%;
background-repeat: no-repeat;
border-radius: 2px;
}

&:after {
content: '';
z-index: -1;
position: absolute;
top: $border-width;
left: $border-width;
width: calc(100% - #{$boder});
height: calc(100% - #{$boder});
background: linear-gradient(-45deg, transparent $transFormWidth, $bg 0) right, linear-gradient(135deg, transparent $transFormWidth, $bg 0) top left;
background-size: 50% 100%;
background-repeat: no-repeat;
}
}