mask
mask 出场的机会不多,但是却很重要。比如可以实现文字的纯色渐变
<div class="text-mask">一二三四五六七八九十</div> 复制代码
.text-mask{ color: green; font-weight: bold; font-size: 30px; width:320px; -webkit-mask: linear-gradient(-90deg, black, 70%, transparent); } 复制代码
70% 写在两个色值中间的含义是中间色的位置,本例中间色的值为 rgba(0,0,0,.5)。
这看起来好像没什么特别,用前面讲过的 background-clip:text
就能实现。
mask 更常用的是用图片做 mask 实现各种效果,用渐变 mask 还可以把 不透明的图片变成透明图片,这样在素材上就可以用 jpg 也能实现半透明的效果。
用mask 做出折线的效果
<div class="line"></div> 复制代码
.line { width:80px; height: 80px; border:1px solid green; background: linear-gradient(45deg ,green 0 19px,transparent 21px) no-repeat left bottom; background-clip: border-box; -webkit-mask:linear-gradient(45deg ,transparent 0 20px,black 21px 100%) no-repeat left bottom; } 复制代码
-webkit- 是必须的,什么颜色没关系,只与透明度有关。
前面的绿色框就是原图形,后面的就是蒙板。折线部分是用渐变背景加上的。蒙板的的效果与颜色无关,也与透明度有关。用蒙板覆盖原图后,只有蒙板透明度不为 0 的部分才能显示。如果透明度在 [0,1] 之间,就是出现半透明效果。
outline
outline 的好处是不占用位置。下图可以帮助理解。
<div class="outline"></div> <div class="box"></div> 复制代码
.outline { width:80px; height: 80px; background-color: green; outline: 3px solid red; outline-offset: 10px; margin-left: 20px; } .box{ width:120px; height: 40px; background-color: steelblue; } 复制代码
如果设置 outline-offset: -10px;
,还可以有下面的效果
还可以实现加号效果
多行文本省略号
overflow:hidden; text-overflow:ellipsis; display:-webkit-box; -webkit-line-clamp:2; /*(两行文字)*/ -webkit-box-orient:vertical; line-height:1.5; height:3em; 复制代码
页面滚动动画效果
html,body{ scroll-behavior: smooth; } 复制代码
如果没有写上面的css,js 也可以办到
window.scrollTo({ top: 100, left: 100, behavior: 'smooth' }); 复制代码
制作饼图
<div class="pie"></div> 复制代码
.pie { width: 150px; height: 150px; border-radius: 50%; background: conic-gradient(yellowgreen 60%, deepskyblue 0); } 复制代码
纯 css 复选框
默认:<label class="checkbox"></label> 选中:<label class="checkbox checked"></label> 复制代码
.checkbox { display: inline-block; width: 18px; height: 18px; border: 3px solid transparent; box-shadow: inset 0 1px, inset -1px 0, inset 0 -1px, inset 1px 0; color: gray; user-select: none; vertical-align: middle; } .checkbox.checked { color: deepskyblue; background: currentColor; background-clip: padding-box; } .checkbox.checked::before { content: ""; display: block; width: 10px; height: 3px; margin: 5px auto 0; border: solid #fff; border-width: 0 0 2px 2px; transform: rotate(-45deg); } 复制代码
这段代码还是有很多讲究的。
- 用透明 border 来扩大点周区域。
- 因为 border 已经占用,用内阴影来模拟 border。
- 因为 border 只是用来扩大点击区域,所以画背景的时候应该把 border 部分去掉
background-clip: padding-box;
。 - 对号是用最开始讲过的 border 模拟的。
- 内阴影没有指定颜色,颜色用的就是
color:gray
用内阴影来模拟 border 还是很有用的,因为border 点位置 ,内阴影不占位置。比如一个按钮,hover的时候有 border ,正常情况下没有border,这个就可以用内阴影来模拟 border。
新手引导遮罩
.guide { box-shadow: 0 0 0 9999px rgba(0, 0, 0, .75); border-radius: 50%; } 复制代码
用的是阴影的扩散半径。box-shaow 的内阴影在背景之上,又在 img 之下,所以 img 没办法用 box-shaow 的内阴影,可以用 outline 替代。
阴影的扩散半径除了正值还可以是负值,负值可以起到收缩的效果。看上面的图阴影扩散出来了。下面的收缩进来,只有下面有阴影效果。
翻牌效果
<ul class="turn"> <li>1</li> <li>2</li> </ul> 复制代码
.turn{ transform-style: preserve-3d; perspective: 500px; width:100px; height: 100px; font-size: 80px; font-weight: bold; text-align: center; line-height: 100px; position: relative; } .turn li{ list-style: none; transition: all .5s; position: absolute; width: 100%; top: 0; left: 0; backface-visibility: hidden; } .turn li:first-child{ background-color: green; color:rgb(240, 45, 10); transform: rotateY(0); } .turn li:last-child{ background-color: orange; color: orchid; transform: rotateY(180deg); } .turn:hover li:first-child{ transform: rotateY(180deg); } .turn:hover li:last-child{ transform: rotateY(360deg); } 复制代码
翻牌用到了 3D 变换。当鼠标 hover 的时候,进行翻牌。
perspective
的中文意思是透视,perspective
的大小会影响到变换的幅度。试想一下,你离一个物体越近,感觉物体的移动距离就会越大,离的越远,感觉物体的移动距离就越小。3d 变换的 z 轴代表离透视点的远近。可以用这个示例 translateZ()函数与perspective视角关系 体验一下。
backface-visibility: hidden
的意思是只显示正面,背面不可见。也就是说绕 Y 轴旋转 +90deg 或 -90deg 的时候是临界点,这时目标已经垂直,再转就应该显示背面了。这个属性的作用就是不让背面显示。本例中用两个 li 叠加起来,开始的时候一个没有旋转,另一个旋转180deg,所以只能看到 上面没有旋转的。hover 的时候正反面互换,就有了翻牌的效果。为了更好的理解可以看这个示例 backface-visibility属性基本效果示意。
旋转木马
张老师说弄明白 3d 旋转木马这个例子,对于 CSS 3D 变换 的学习就算是合格了,深以为然。
如果想从头学习 3d 变换,看这篇 CSS3 3D transform变换,不过如此!
其实关键就两步
- 为每个图片平均旋转一个角度
rotateY
- 让每个图片向外走几步
translateZ
向外走多少步有公式可以算,也直接在 chrome 里调数值看效果。
边框旋转的按钮
<div class="clip">hello</div> 复制代码
.clip{ position: relative; margin: auto; width: 120px; line-height: 64px; text-align: center; color: #fff; font-size: 20px; border: 2px solid gold; border-radius: 10px; background: gold; transition: all .3s; cursor: pointer; } .clip::before, .clip::after { content: ""; position: absolute; top: -10px; left: -10px; right: -10px; bottom: -10px; border: 2px solid gold; border-radius: 10px; } .clip::before{ animation: clippath 3s infinite linear; } .clip::after { animation: clippath 3s infinite -1.5s linear; } 复制代码
逐帧动画
用 steps 阶跃函数,可以实现纯 css 的逐帧动画,原理就是把 n 张图片一张接着一张的展示,和放电影的原理是一样的。
我们用其它的函数比如 linear,会根据关键帧计算出许许多多的中间状态的帧。steps 和其它函数不同的是,可以指定帧的数量。如果只指定了开始和结束这两帧,相当于是执行了超慢动作的 linear 的效果。
我们用这张图片来演示,直接下载就可以用。图片一共宽 300px ,每个色块 100px。通过每次左移 100px,来显示不同的色块。
<div class="step"></div> 复制代码
.step{ background:url(color.png) no-repeat ; height: 50px; width:100px; animation: step 3s steps(3) infinite; } @keyframes step{ from{ background-position: 0 0; } to { background-position: -300px 0; } } 复制代码
steps(3)
的意思是动画分 3 步完成,因为动画 一共 3秒,所以正好一秒走一步。具体过程是这样的。
- 动画在起始位置停 1秒,效果上是显示红色块 1 秒。
- 背景向左移 100px,停 1,秒 ,效果上是显示绿色块 1 秒。
- 背景向左移 100px,停 1,秒 ,效果上是显示蓝色块 1 秒。
经过 3 步后,动画结束,再从第一步开始。因为我们只指定了 from ,to,所以 3 步平均每步移 100px,每步走多少其实是可以指定的。比如可以第二步走 150 px,效果上到第二步的时候就显示一半红,一半绿。
@keyframes step{ from{ background-position: 0 0; } 50%{ background-position: -150px 0; } to { background-position: -300px 0; } } 复制代码
step 一共有两个参数,本例中是 step(3,end) ,end是默认值。效果上是显示红色块 1秒。
第二个参数可以指定为 start ,效果上是直接显示绿色块,最后显示空白 1 秒。
如果一个图片由 10张 连续的画面橫向拼在一起的,一共 300 px。如果想用 step 连续显示每张图片,就需要分 10 份,一共走 300px,step 用默认的 end 方式。
标签嵌套实现复合动画
两个标签分别实现匀速向右移动和加速向下移动,合起来就是抛物线的效果。
最关键的是这种复合动画的思想,有了这个思想,还可以合成很多效果
env
viewport-fit=cover
必须有这句 env 才能生效。
<meta name="viewport" content="viewport-fit=cover"> 复制代码
env(safe-area-inset-top); /*20px 是兜底的*/ env(safe-area-inset-top,20px); /*兼容 ios <11.2,基本上可以不用写,占比太小*/ constant(safe-area-inset-top); 复制代码
除了top 还有 right,bottom,left 三个值。
取消 300 ms 点击延时
touch-action:manipulation; 复制代码
还可以禁用手势
touch-action:none; 复制代码
穿透点击
pointer-events:none; 复制代码
pointer-events具有继承性,想恢复child的点击
pointer-events:auto; 复制代码
选中
user-select:all; 复制代码
改变被选中文字的颜色
::selection{ color:blue; } 复制代码
光标
caret-color: red;