CSS Day 2

今天主要用了动画 animation。想法来自 Twitter 上 @shuding_ 的分享[1]。实际效果:

See the Pen Fade-in animation that is not so boring by tianheg (@tianheg) on CodePen.

介绍了两种图片动画的变化效果。

#笔记

height: 100vhdisplay: flex;align-items:center; 搭配才能得到垂直居中的效果。

最关键的部分在于怎么写好 keyframes,我写的还不行,对于 filter 的使用还不够熟练。还有对于选择分割点的时机问题。

在手机上查看时,发现动画不起作用。猜测可能是 prefers-reduced-motion ,于是把它改成 prefers-reduced-motion: no-preference 。终于 work 了。

找到 MDN 上关于 prefers-reduced-motion[2] 的页面:

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 里,然后这样设置:

1
<link rel="stylesheet" href="animations.css" media="(prefers-reduced-motion: no-preference)">

一个 Demo: https://prefers-reduced-motion.glitch.me/

如果想强制关闭动画,可以通过 Stylus 这样的插件扩展为所有网站插入以下样式,但 风险自负

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@media (prefers-reduced-motion: reduce) {
  *, ::before, ::after {
    animation-delay: -1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    background-attachment: initial !important;
    scroll-behavior: auto !important;
    transition-duration: 0s !important;
    transition-delay: 0s !important;
  }
}

因为某些网站为了顺利加载会依赖于动画(某一步依赖于触发 animationend 事件),更激进的 animation: none !important; 不起作用。即便是以上设置也不能保证所有网站都能屏蔽掉动画(这段代码无法屏蔽通过 Web Animation API 启动的动作)。

#代码实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!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
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
body {
  background-color: #000;
  color: #fff;
}

h2 {
  text-align: center;
}

.containers {
  display: flex;
  justify-content: center;
  align-items: center;
}

@media (max-width: 600px) {
  .containers {
    flex-direction: column;
  }
}

.container {
  text-align: center;
  margin: 0 1rem;
}

@media (prefers-reduced-motion: no-preference) {
  .container .img-left {
    animation-name: fastFadein;
    animation-duration: 3s;
    animation-iteration-count: infinite;
  }

  .container .img-right {
    animation-name: slowFadein;
    animation-duration: 3s;
    animation-iteration-count: infinite;
  }
}

@media (prefers-reduced-motion: reduce) {

  .container .img-left,
  .container .img-right {
    animation: none;
  }
}

@keyframes fastFadein {
  0% {
    opacity: 1;
    filter: brightness(0) blur(0);
  }

  100% {
    opacity: 1;
    filter: brightness(1) blur(0);
  }
}

@keyframes slowFadein {
  0% {
    opacity: 0;
    filter: brightness(1) blur(20px);
  }

  15% {
    opacity: 1;
    filter: brightness(2) blur(10px);
  }
}

Layout of comment panels