700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 纯CSS实现圆角阴影的折角效果

纯CSS实现圆角阴影的折角效果

时间:2024-04-26 01:28:17

相关推荐

纯CSS实现圆角阴影的折角效果

纯CSS实现圆角阴影的折角效果

-10-04 13:14网页设计标签:css16372

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

目前,我们已经拥有一些使用纯CSS实现的方案,其中某些技巧早在就由伪元素大师Nicolas Gallagher发表了。这些方法的基本原理通常是在右上角增加两个三角形:一个三角形用来体现折页的形状,另外一个白色的三角形遮住元素的一角,用来模拟翻折所产生的缺角。这两个三角形通常都是由经典的边框技巧来生成的。

尽管这些方法在过去光彩夺目,但在今天看来却有一些局限性,而且在以下场景中还会暴露出明显的缺陷:

当折角元素之下的背景不是纯色,而是一幅图案、一层纹理、一张照片、一幅渐变或者其他一种背景图案时;

当我们想要一个45°以外的折角时;

45°折角方案

我们会从一个右上角具有斜面切角的元素开始,在之前的“切角效果”我们已经讲述过方法。通过一个渐变来实现缺角的效果:

background:#58a;/* 回退机制 */background:linear-gradient(-135deg,transparent 2em,#58a 0);

接下来需要的增加一个暗黑色的三角形来实现翻折效果。实现方法也是通过一层渐变来生成这个三角形,并将其定位在右上角,通过background-size来控制折角的大小。

为了生成这个三角形,我们所需要就是一个有角度的线性渐变,而这个渐变的两个色标需要在正中间重合:

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

最后,我们把两层组合起来,应该可以收工了吧?我们来试试看:

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 2em,#58a 0);

奇怪,为什么会这样?

原因在于第二层渐变中的2em折角是写在色标中的,因此它是沿着渐变轴进行度量的,是对角线尺寸。另一面,在background-size中的2em长度是背景贴片的宽度和高度,是在水平和垂直方向上进行度量的。

为了将两者对齐,我们需要选择以下任意项进行调整,选择哪一项取决于我们最终想保留哪一方面的尺寸设置。

如果想保留对角线的2em长度,就要将background-size乘以√2;

如果想保留水平和垂直方向上的2em长度,就要用切角渐变的角标位置除以√2。

由于background-size需要把这个长度重复两次,而且绝大多数的CSS度量都不是在对角线上进行的,因此第二种方案更合适。色标的位置值将变成2/√2=√2≈1.414213562;

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.414213em,#58a 0);

其他角度的解决方案

现实中的折角往往不是精准的45°,如果我们希望它看起来更真实一些,可以稍微改变下角度,比如-150deg可以产生30°的切角。那么显然,第二层肯定不会跟着变化,这会我们又需要请出三角函数了。

本人数学不是很好,大家请自己算吧 = =!都是初中时候教的,勾股定理,正弦和余弦函数之类的。

我们把角度计算改变下,变成了这样:

但细心的人会发现,这样的效果和现实中真实的折纸效果(如下图)是不一样的,它不够真实。

现实中的折角是微微旋转的,它的尺寸和我们从元素角上切下来的那个三角形是一致的。由于我们无法旋转背景,就只能找到伪元素来做了。

.zhejiao{position:relative;background:#58a;/*回退效果*/background:linear-gradient(-150deg,transparent 1.5em,#58a 0);}.zhejiao::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:3em;height:1.73em;}

到这里,我们把原来由背景一次性做完的东西放置到了伪元素层,下一步要把折页的三角形的width和height对调,以此改变它的方向,这样就可以得到跟折角页缺口对称的三角形,而不是一个可以补足折页缺口的三角形。然后,我们再以逆时针旋转30°{(90°-30°)-30°}。这样可以让它的斜边与折线平行:

.zhejiao::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:1.73em;height:3em;transform:rotate(-30deg);}

现在可以看到,我们得到了这个一样形状,但要把它移到准确的位置上,通过计算尺寸是很困难的。因此,我们把transform-origin设置为bottom right,让三角形右下角成为旋转的中心,这样就可以让它的右下角保持固定。然后再计算出垂直方向上的偏移量就可以了。

.zhejiao::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:1.73em;height:3em;transform:translateY(-1.279em) rotate(-30deg);transform-origin:bottom right;}

有个需要注意的是,确保需要把translateY(-1.279em)放置在变形之前,否则三角形就会在30°方向上进行位移了。

修饰并增加圆角和阴影效果

有时候,我们会需要更加真实点的效果,比如增加圆角、渐变以及投影!那么,我们修饰下代码,增加这些内容进去:

.zhejiao{position:relative;background:#58a;background:linear-gradient(-150deg,transparent 1.5em,#58a 0);border-radius: .5em;}.zhejiao::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:1.73em;height:3em;transform:translateY(-1.3em) rotate(-30deg);transform-origin:bottom right;border-bottom-left-radius: inherit;box-shadow:-.2em .2em .3em -.1em rgba(0,0,0,.15);}

处理器@mixin(不完全支持)

最终效果看来很不错,但代码不够DRY,让我们来看一看,如果对样式做些改动或对效果做些微调,会是什么情况?

如果要改变元素的宽度或者其他尺寸(比如内边距等),只需要修改一处。

如果要改变元素的背景色,则需要改变两处;

如果要修改页面的大小,需要修改四处,并做一些复杂的计算;

如果要修改折页的角度,则需要修改五处,并更加复杂了。

看来我们要清楚预处理器mixin了:

@mixin folded-corner($background,$size,$angle:30deg){position:relative;background:$background;background:linear-gradient($angle - 180deg,transparent $size,$background 0);border-radius: .5em;$x:$size / sin($angle);$y:$size / cos($angle);&::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:$y;height:$x;transform:translateY($y-$x) rotate(2*$angle - 90deg);transform-origin:bottom right;border-bottom-left-radius:inherit;box-shadow:-.2em .2em .3em -.1em rgba(0,0,0,.15);}}/*当调用时...*/.note{@include folded-corner(#68d,1.3em,60deg);}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。