【CSS】CSS特效集锦,视觉魔法的碰撞与融合(一)
正文
前言
在本文中我讲述了 7 种 CSS 的特效,它们也许看起来并不惊艳,但是我认为却足够传达本文的理念:编写一些特殊的 CSS 样式的时候需要不拘于常理,要用特殊的认识角度看待标签和样式属性,从而用「绕个弯」的方式达到效果。
一. 浮光掠影
首先我们看第一个实现效果:在鼠标浮动到图片上方时,让一片白影一闪而过。
实现思路
-
画一个竖直的长方形的白色 div,设置 opcity 将其变为半透明
-
借助 transform:skewX 将长方形变成等高的平行四边形
-
白条 div 绝对定位,外层 div 相对定位,一开始 left 属性默认是 0
-
在:hover 伪元素中修改 left 值,例如 left=600px(超出图片长度),通过 transition 指定 left 和时间,形成过渡
图示
HTML
<div class="flash"> <div class="flash-bar"></div> <img src="{图片地址}" /> </div>
CSS
.flash { position: relative; width: 500px; } .flash img { width: 100%; } .flash-bar { position: absolute; left:-100px; width: 20px; height: 100%; background: #fff; opacity: 0.5; transform: skewX(-30deg); transform-origin: 0 100%; } .flash:hover .flash-bar { left:900px; transition: left ease-in-out 1s; }
二. 发光球体
实现思路
让一个球体散发光芒,一开始好像有点蒙,但是换个角度思考一下,光芒只是另一种颜色的 box-shadow 而已,然后我们通过 animation 让它动起来就好了
HTML
<div class="light"></div>
CSS
@keyframes light { from { box-shadow:0px 0px 4px #f00; } to { box-shadow:0px 0px 16px #f00; } } .light { margin:300px; width: 100px; height: 100px; margin:20px; border-radius: 50%; animation: light 2s ease-in-out infinite alternate; }
三. 圆环进度条
很显然,圆框是通过 border 去实现的,但具体怎么做呢?
这个进度条,表面上看它是由一个 div 圆框组成,实则不然,它是由左右两个半圆的 div 组成的,其中一个 div 转动 180 度,然后另一个 div 再转 180 度。看一下下面的例子你就明白了, 我们把颜色调成蓝色和红色,以对比
我们一步一步来解释,首先我们整个圆的外部是一个正方形,左右由两个 div,div-left 和 div-right 组成,各占一半,分别放左半圆和右半圆。而且两个 div 分别设置 overflow:hidden 实现溢出隐藏,这样的结果是,左边的圆的右半边被隐藏了,右边的圆的左半边被隐藏了。
而且更重要的是,两个因为溢出被隐藏的半圆分别被涂上了蓝色和红色,而没有溢出的两个半圆的圆框则是透明的。所以我们看到的初始的空进度条其实是下面这样的
这两个圆框转动的规则是:
-
左边的蓝色圆框先转完 0 度到 180 度,这段时间里红色圆框是不动的
-
接下来红色圆框转完 180 度到 360 度,这段时间里蓝框则是不动的
(备注:我们约定最上方为 0/360 度)
转到 45 度角的时候进度条是下面这样子
转角超过 180 时也是同理的,不过这个时候就轮到红色框转动了,蓝框保持不动
代码如下:
HTML
<div class="progress"> <div class="wrapper-circle left"> <div class="circle"></div> </div> <div class="wrapper-circle right"> <div class="circle"></div> </div> </div>
CSS
@keyframes left_cirlce_spin { 0%,50% { transform: rotate(-45deg); } 100%{ transform: rotate(135deg); } } @keyframes right_cirlce_spin { 0% { transform: rotate(45deg); } 50%,100%{ transform: rotate(225deg); } } .progress { overflow: hidden; width: 100px; height: 100px; } .progress .wrapper-circle { overflow: hidden; width: 50%; height: 100%; } .left { float: left; } .right { float: right; } .progress { margin: 20px; } .progress .circle { border-radius: 50%; width: 90px; height: 90px; } .progress .left .circle { float: left; border: 5px solid red; border-top-color: transparent; border-left-color: transparent; animation: left_cirlce_spin 4s linear infinite; }.progress .right .circle {
float: right;
border: 5px solid red;
border-top-color: transparent;
border-right-color: transparent;
animation: right_cirlce_spin 4s linear infinite;
}
四. 三角形
这个话题已经是老生常谈了,我第一个了解的比较有趣的 CSS 实现就是它。它是通过一个宽高设置为 0 的 div 的 border 去实现的。
要实现三角形,首先我们要改变心里对 border 形状的刻板认知。border 其实是一个等腰梯形而不是长方形
当 width 和 height 被减小为 0,只有 border 的时候,border 就从等腰梯形变成了等腰三角形:
然后我们需要哪一块三角形,就把剩余的部分 border 都设为 transparent(透明) 就可以了
代码很简单,这里就不加赘述了。
五. 有色到透明的渐变
下面这张图是从知乎的发现栏目上摘来的,很显然它是利用渐变去实现的。思路也很简单,主要是要有两方面的认知:
-
这张图其实可以分成两部分,右边控制图形和渐变,左边就是一张纯色背景,和渐变无关
-
透明 transparent 也是一种颜色,也是渐变可以设置的
代码如下
HTML
<!-- 有色到透明的背景渐变 --> <div class="background-gradient"> <div class="mask"></div> </div>
CSS
.background-gradient { background: rgb(44, 136, 207); position: relative; width: 500px; height: 200px; } .background-gradient .mask { background-image: linear-gradient(to right, rgb(44, 136, 207), transparent), url("https://pic1.zhimg.co m/50/v2-6c5aa2304a93b7fbaf903e3560543d7b_hd.jpg"); background-position:center; background-blend-mode:normal; position: absolute; height: 100%; width: 180px; right: 0; }
六. 模糊效果和毛玻璃效果
知乎上,在发表文章或回答时引入链接就会有下面模糊的效果。它其实是由 CSS3 的 filter 属性去实现的
<img class="blur" src="https://pic1.zhimg.com/50/v2-6c5aa2304a93b7fbaf903e3560543d7b_hd.jpg" />
CSS
.blur { width: 100px; filter: url(blur.svg#blur); /* FireFox, Chrome, Opera */-webkit-filter</span>:<span style="color: rgba(0, 0, 255, 1)"> blur(2px)</span>; <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> Chrome, Opera </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(255, 0, 0, 1)"> -moz-filter</span>:<span style="color: rgba(0, 0, 255, 1)"> blur(2px)</span>;<span style="color: rgba(255, 0, 0, 1)"> -ms-filter</span>:<span style="color: rgba(0, 0, 255, 1)"> blur(2px)</span>;<span style="color: rgba(255, 0, 0, 1)"> filter</span>:<span style="color: rgba(0, 0, 255, 1)"> blur(2px)</span>;<span style="color: rgba(255, 0, 0, 1)"> filter</span>:<span style="color: rgba(0, 0, 255, 1)"> progid:DXImageTransform.Microsoft.Blur(PixelRadius=2, MakeShadow=false)</span>; <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> IE6~IE9 </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
}
效果如下
要注意兼容,兼容各个浏览器的方法如上图所示,顺便一提这份代码由大神张鑫旭提供, 链接如下
模糊效果和 IOS 中的毛玻璃效果还是不一样的。(其实我也感觉毛玻璃效果比起模糊效果会漂亮很多),而 IOS 的毛玻璃效果可以借助 backdrop-filter 去实现,链接如下,大家可以自行尝试
不过注意,目前 backdrop-filter 在较高版本的浏览器才会支持
七. 斜角标签
有的时候,在显示一些时效性的 UI 数据的时候,例如一个商品卡片的打折标签的时候,我们可能会需要在卡片上显示一个等腰梯形,那么我们该怎么实现呢?
实际上,我们可以通过一个横向的 div 通过 transform:rotate 逆时针旋转 45 度角得到它。如下图所示,同时要注意给外层 div 设置 overflow:hidden 实现溢出隐藏。
除此之外,还需要进行简单的计算,因为旋转上去后,形成的是一个等腰直角三角形,所以标签 div 的长度需要是它距离外层 div 顶部距离的√2(根号 2) 倍,如上图所示。
代码如下:
HTML
<div class="label"> <div class="label-bar">打折</div> <img src="https://pic1.zhimg.com/50/v2-6c5aa2304a93b7fbaf903e3560543d7b_hd.jpg" /> </div>
CSS
.label { position: relative; overflow: hidden; } .label-bar { text-align: center; background: red; position: absolute; top:80px; left: 0px; width: 141px; height:20px; transform-origin: 0 100%; transform: rotate(-45deg); }
技术总结
OK, 下面进行 CSS3 的技术(坑点)总结 ~
1. 转换行为 (rotate,skew 等) 的 2D 坐标系是这样的,Y 轴是向下的!原点是 div 的左上角。根据 transform-origin 可以设置转换(例如旋转或者倾斜)的参考点,默认的参考点是(50%,50%),即中心。如下图所示
2. 改变大小的 transform 方法 scale 不接受百分比! 只能是用数字表示倍数,如 transform:scale(2),
transform:scale(0.5) 等等
3.skewX 和 skewY 在 2D 参考系里相当于具有倾斜的效果,倾斜时候变成高度不变的平行四边形。但是 skewX 和 skewY 具有相反的差异,skewX 是 X 轴方向不动,Y 轴方向逆时针倾斜, skewY 是 Y 轴不动,X 轴方向向顺时针倾斜,两者连倾斜的方向都是不一样的,具体可以参考
https://link.zhihu.com/?target=http%3A//www.lvyestudy.com/css3/css3_9.5.aspx
4.transition 和 animation 在使用最明显的区别是什么?
-
transition 的使用是很受限制的,而 animation 非常灵活,在不借助 JS 的前提下,它只能在 CSS 的伪元素中起相应的作用,因为 transition 只能对发生变化的属性起作用,而除了伪元素外,其他元素选择器会出现后面的选择器覆盖前面选择器属性的现象,到最后属性只有一个值,怎么实现过渡呢?当然就不可以了。
-
在不借助 JS 的前提下,transition 只能来一遍,而 animation 可以指定次数:1 次,2 次或无数次(指定 infinite 表示无限次数),还可以指定方向 (altertive,表示播放结束后倒退播放)
-
甚至 animation 还可以通过百分比指定每一阶段的细节变化,这一点 transition 就做不到了
本文完
知乎主页和专栏
知乎主页:https://www.zhihu.com/people/peng-hu-wan-56/activities
知乎专栏: https://zhuanlan.zhihu.com/c_135367198