CSS 揭秘(4)--折角效果

Posted by liveipool on February 8, 2017

折角效果

把元素的一个角处理为类似折角的形状,再配上或多或少的拟物样式,这种效果已经成为一种非常流行的装饰手法。

45度折角解决方案

19.3.png
想得到上图这样的折角效果,我们的思路是:

  1. 通过“切角”将一个矩形的右上角切掉。
  2. 增加另一层渐变来生成一个小三角形并定位到右上角。

切角:

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

19.1.png
生成小三角形:

div {
	background: #58a;
	background: linear-gradient(to left bottom, transparent 50%, rgba(0, 0, 0, .4) 0) no-repeat 100% 0 / 2em 2em;
}

19.2.png
最后再把这两层渐变合起来:

div {
	background: #58a;
	background: linear-gradient(to left bottom, transparent 50%, rgba(0, 0, 0, .4) 0) no-repeat 100% 0 / 2em 2em,
				linear-gradient(-135deg, transparent 1.41em, #58a 0);  // 注意这里面是1.41em,而不是2em
}

19.3.png
注意上面的代码中,在进行切角时,长度为1.41em,而小三角形是2em。这是因为折角的尺寸是写在色标中的,是沿着渐变轴进行度量的,是对角线尺寸,而background-size中的2em 2em是指背景贴片的宽度和高度。因此在45度角的情况下,有根号2的关系。
还要注意,background:#58a都是回退方案。

其他角度的解决方案

现实生活中的折角往往不是精确的45度,如果我们希望它看起来更真实一些,可以稍稍改变一下角度,比如-150deg可以产生30度的切角。
但是改变了角度之后,整体效果又会被破坏了,因此我们需要根据三角函数公式来算出现在的各个尺寸了,结果如下:

div {
	background: #58a;
	background: linear-gradient(to left bottom, transparent 50%, rgba(0, 0, 0, .4) 0) no-repeat 100% 0 / 3em 1.73em,
				linear-gradient(-150deg, transparent 1.5em, #58a 0);
}

19.4.png
现在虽然对上号了,但我们拿起真实的纸来就知道现实中是没办法折成上面这样的效果的,因此我们需要将折角进行一点旋转操作,由于无法旋转背景,这里又需要伪元素登场了:

div {
	position: relative;
	background: #58a;
	background: linear-gradient(-150deg, transparent 1.5em, #58a 0);
}

div::before {
	content: '';
	position: absolute;
	top: 0; right: 0;
	background: linear-gradient(to left bottom, transparent 50%, rgba(0, 0, 0, .4) 0) no-repeat 100% 0;
	width: 3em;
	height: 1.73em;
}

19.4.png
下面将小三角的width和height对调,以此来改变它的方向,再逆时针旋转30度使它和斜边平行;

div {
	// ...
}

div::before {
	// ...
	width: 1.73em;
	height: 3em;
	transform: rotate(-30deg);
}

19.5.png
由于随意旋转到现在的情况下,不太好计算距离想要的位置的水平和垂直距离,因此我们可以将三角形的右下角固定为旋转的中心,这样只需要在找到垂直方向上的距离再进行平移就可以达到效果了:

div {
	// ...
}

div::before {
	// ...
	transform-origin: bottom right;
	transform: rotate(-30deg);
}

19.6.png

transform: translateY(-1.3em) rotate(-30deg);

19.7.png
最后再加上圆角,渐变以及阴影让效果更真实一些,最后的完整代码:

// jade
div.w-200.h-200.m-200.p-32.fs-20.text-bold "The only way to get rid of a temptation is to yield to it." --Liveipool

// css
div {
	position: relative;
	background: #58a;
	background: linear-gradient(-150deg, transparent 1.5em, #58a 0);
	color: #fff;
	border-radius: .5em;
}

div::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)) no-repeat 100% 0;
	width: 1.73em;
	height: 3em;
	transform-origin: bottom right;
	transform: translateY(-1.3em) rotate(-30deg);
	border-bottom-left-radius: inherit;
	box-shadow: -.2em .2em .3em -.1em rgba(0, 0, 0, .15);
}

19.8.png

PS.在这个示例中,有地方需要进行三角函数的运算,一种方法是自己计算,另外就是去使用预处理器的mixin等(如果它们能够支持三角函数运算的话)。至于预处理器,以后再深入地看看吧。