把元素的一个角(通常是右上角或右下角)处理成类似折角的形状,再配上或多或少的拟物样式,已经成为一种非常流行的装饰手法。
45度折角的解决方案
这是原代码即原效果图:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box{
width: 400px;
height: 300px;
background: #58a;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
首先我们从一个右上角具有斜面切角的元素开始,这个切角是由渐变方案实现的,代码及效果如下:
<style>
.box{
width: 400px;
height: 300px;
background:
linear-gradient(-135deg, transparent 3em, #58a 0);
}
</style>
接下来我们增加一个暗色的三角形来实现翻折效果,实现方法是增加另一层渐变来生成这个三角形,并将其定位在右上角。这可以通过background-size来控制角的大小。
.box{
width: 400px;
height: 300px;
background:
linear-gradient(to left bottom,
transparent 50%, rgba(0,0,0,.4) 0)
no-repeat ;
background-position: 100% 0;
background-size: 3em 3em;
border: 1px solid black;
}
把这两个合并后,如下:
background:
linear-gradient(to left bottom,
transparent 50%, rgba(0,0,0,.4) 0)
no-repeat 100% 0/3em 3em,
linear-gradient(-135deg, transparent 3em, #58a 0);
我们发现它们并不贴合,原因是第二层渐变中的3em折角尺寸是写在色标中的,它是沿着渐变轴进行衡量的,是对角线尺寸。另一方面,在background-size中的3em长度是背景贴片的宽度和高度,是在水平和垂直方向上进行度量的。
为了将这两者对齐,我们只要该其中一项就行:
- 如果保留对角线的3em长度,那么就要把background-size乘以根号2
- 如果要保留水平和垂直方向上的3em长度,那么就要要在切角渐变的角标位置除以根号2。
这里我们选用第二种方案,因为绝大多数CSS的度量不是在对角线上进行的,因为我们这里把色标的位置改成3/√2 = 2.121320344,这里取2.2em,效果如下:
background:
linear-gradient(to left bottom,
transparent 50%, rgba(0,0,0,.4) 0)
no-repeat 100% 0/3em 3em,
linear-gradient(-135deg, transparent 2.2em, #58a 0);
这样我们就得到了一个想要的折角效果。
其他角度的解决方案
现实生活中,折角往往不是精确的45度。比如-150deg会产生30度的切角。效果如下:
background:
linear-gradient(to left bottom,
transparent 50%, rgba(0,0,0,.4) 0)
no-repeat 100% 0/3em 3em,
linear-gradient(-150deg, transparent 2.2em, #58a 0);
这时我们就需要通过三角函数来计算得到我们想要的暗色三角形的长度和宽度:
因此计算得到sin30度 = 2.2/x 所以 x = 4.4, cos30度 = 2.2/y 所以y = 2.540341184
所以我们修改得到:
background:
linear-gradient(to left bottom,
transparent 50%, rgba(0,0,0,.4) 0)
no-repeat 100% 0/4.4em 2.55em,
linear-gradient(-150deg, transparent 2.2em, #58a 0);
但是这里虽然对上了,但是看起来不是很真实。如果你拿出一张纸的话,做一下试验,你会发现折页三角形是微微旋转的。因为我们是无法旋转背景的,所以这里我们用到伪元素。
<style>
.box{
width: 400px;
height: 300px;
position: relative;
background:
linear-gradient(-150deg, transparent 2.2em, #58a 0);
}
.box::before{
content: '';
position: absolute;
top: 0;right: 0;
background: linear-gradient(to left bottom,
transparent 50%, rgba(0,0,0,.4) 0)
100% 0 no-repeat;
width: 4.4em;
height: 2.55em;
}
这里你会发现我们只是把上述的效果又实现了一遍。
接下来,我们就把暗色三角的长度和宽度对掉,并且逆时针旋转30度:
width: 2.55em;
height: 4.4em;
transform: rotate(-30deg);
到这里我们已经接近目标了,接下来要做的便是挪动这个三角形让它与斜边重合。
首先:我们把transform-origin设置为bottom right,让三角形的右下角成为旋转的中心,这样就可以让它的右下角保持固定:
transform: rotate(-30deg);
transform-origin: bottom right;
接下来就是再次运用几何学来计算垂直方向上的移动距离了:
如上图所示,我们得到垂直偏移量是x - y = 4.4 - 2.55 = 1.85em,因此我们修改得:
width: 2.55em;
height: 4.4em;
transform: translateY(-1.85em) rotate(-30deg);
transform-origin: bottom right;
这里我们可以再让它美观一点,可以增加一点圆角,渐变和投影等,最终效果如下:
<style>
.box{
width: 400px;
height: 300px;
position: relative;
background:
linear-gradient(-150deg, transparent 2.2em, #58a 0);
border-radius: 1em;
}
.box::before{
content: '';
position: absolute;
top: 0;right: 0;
background: linear-gradient(to left bottom,
transparent 50%, rgba(0,0,0,.2) 0, rgba(0,0,0,.4))
100% 0 no-repeat;
width: 2.55em;
height: 4.4em;
transform: translateY(-1.85em) rotate(-30deg);
transform-origin: bottom right;
border-bottom-left-radius: inherit;
box-shadow: -.2em .2em .3em -.1em rgba(0,0,0,.15);
}
</style>