CSS Day 2
今天主要用了动画 animation。想法来自 Twitter 上 @shuding_ 的分享1。实际效果:
<p class="codepen" data-height="537" data-default-tab="result" data-slug-hash="KKoyRaw" data-editable="true" data-user="tianheg" style="height: 537px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
See the Pen Fade-in animation that is not so boring by tianheg (@tianheg) on CodePen.
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
介绍了两种图片动画的变化效果。
笔记
height: 100vh
和 display: flex;align-items:center;
搭配才能得到垂直居中的效果。
最关键的部分在于怎么写好 keyframes,我写的还不行,对于 filter 的使用还不够熟练。还有对于选择分割点的时机问题。
在手机上查看时,发现动画不起作用。猜测可能是 prefers-reduced-motion
,于是把它改成 prefers-reduced-motion: no-preference
。终于 work 了。
找到 MDN 上关于 prefers-reduced-motion2 的页面:
The prefers-reduced-motion CSS media feature is used to detect if the user has requested that the system minimize the amount of non-essential motion it uses.
了解到,将 prefers-reduced-motion 设置为 reduce
或者仅写
prefers-reduced-motion
都会使得浏览器减少/移除动画效果。
从 web.dev 的这篇《prefers-reduced-motion: Sometimes less movement is
more》3可以将和动画有关的样式放到一个 CSS 文件 animations.css
里,然后这样设置:
<link rel="stylesheet" href="animations.css" media="(prefers-reduced-motion: no-preference)">
一个 Demo: https://prefers-reduced-motion.glitch.me/
如果想强制关闭动画,可以通过 Stylus 这样的插件扩展为所有网站插入以下样式,但 风险自负 !
1 @media (prefers-reduced-motion: reduce) {
2 *, ::before, ::after {
3 animation-delay: -1ms !important;
4 animation-duration: 1ms !important;
5 animation-iteration-count: 1 !important;
6 background-attachment: initial !important;
7 scroll-behavior: auto !important;
8 transition-duration: 0s !important;
9 transition-delay: 0s !important;
10 }
11 }
因为某些网站为了顺利加载会依赖于动画(某一步依赖于触发
animationend
事件),更激进的 animation: none !important;
不起作用。即便是以上设置也不能保证所有网站都能屏蔽掉动画(这段代码无法屏蔽通过
Web Animation API 启动的动作)。
代码实现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Day2 in CSS</title> <link rel="stylesheet" href="style.css" /> </head> <body> <h2> Inspired by <a href="https://twitter.com/shuding_/status/1552438750470340610" >@shuding_</a > </h2> <div class="containers"> <div class="container"> <p>Boring Fade-in</p> <img class="img-left" src="benjamin-voros-phIFdC6lA4E-unsplash.jpg" alt="Star" width="400" /> </div> <div class="container"> <p>Not so Boring Fade-in</p> <img class="img-right" src="benjamin-voros-phIFdC6lA4E-unsplash.jpg" alt="Star" width="400" /> </div> </div> </body> </html>
1 body {
2 background-color: #000;
3 color: #fff;
4 }
5
6 h2 {
7 text-align: center;
8 }
9
10 .containers {
11 display: flex;
12 justify-content: center;
13 align-items: center;
14 }
15
16 @media (max-width: 600px) {
17 .containers {
18 flex-direction: column;
19 }
20 }
21
22 .container {
23 text-align: center;
24 margin: 0 1rem;
25 }
26
27 @media (prefers-reduced-motion: no-preference) {
28 .container .img-left {
29 animation-name: fastFadein;
30 animation-duration: 3s;
31 animation-iteration-count: infinite;
32 }
33
34 .container .img-right {
35 animation-name: slowFadein;
36 animation-duration: 3s;
37 animation-iteration-count: infinite;
38 }
39 }
40
41 @media (prefers-reduced-motion: reduce) {
42
43 .container .img-left,
44 .container .img-right {
45 animation: none;
46 }
47 }
48
49 @keyframes fastFadein {
50 0% {
51 opacity: 1;
52 filter: brightness(0) blur(0);
53 }
54
55 100% {
56 opacity: 1;
57 filter: brightness(1) blur(0);
58 }
59 }
60
61 @keyframes slowFadein {
62 0% {
63 opacity: 0;
64 filter: brightness(1) blur(20px);
65 }
66
67 15% {
68 opacity: 1;
69 filter: brightness(2) blur(10px);
70 }
71 }