您是否看过 这种巧妙的技术,它使用 <picture>
元素和 <source media="">
根据 prefers-reduced-motion
媒体查询 来提供动画图像(或不提供)?
在我们 时事通讯 中分享了这一点后,我们收到了 Michael Gale 的一封有趣的回复。
那些喜欢动画 GIF 但又不想让 UI 到处缩放的人怎么办?他们现在是否被迫在内容和 UI 之间做出选择?
我认为这是一个非常有趣的问题。
此外,如今每当我看到 <img src="gif.gif">
时,我的大脑就会被触发进入 那么 MP4 呢?! 区域,因为我已经充分相信,在网络上,视频在各个方面都优于 GIF。事实证明,某些浏览器支持在 <img>
元素中直接使用视频,并且,信不信由你,您 可以为此编写回退,并且——请鼓掌——还可以使用 <picture>
元素!
让我们尝试将所有这些东西结合起来。
添加 MP4 源
最简单的方法是添加另一个带有视频的 <source>
。这意味着我们需要三个源媒体文件。
- 当
prefers-reduced-motion
为reduce
时,回退到非动画图形。 - 动画 GIF 作为默认值。
- 如果支持回退,则使用 MP4 视频替换 GIF。
例如
<picture>
<source srcset="static.png" media="(prefers-reduced-motion: reduce)"></source>
<source srcset="animated.mp4" type="video/mp4">
<img srcset="animated.gif" alt="animated image" />
</picture>
在 Chrome 中的默认情况下,只会下载和显示 GIF。

在 Safari 中的默认情况下,只会下载和显示 MP4。

如果您在 Chrome 或 Safari 中激活了 prefers-reduced-motion: reduce
(在我的 Mac 上,我转到 系统偏好设置 → 辅助功能 → 显示 → 降低动画效果),则两个浏览器只会下载静态 PNG 文件。

我测试了 Firefox,它似乎不起作用,而是继续下载 GIF 版本。Firefox 似乎支持 prefers-reduced-motion
,但也许它在 <source>
元素上尚不支持?我不确定那里发生了什么。
提供单个动画源并使用工具从该源生成其他源,这会不会很酷?我敢打赌,您可以使用类似 Cloudinary 的东西将其连接起来。
添加一个切换按钮以显示动画版本
正如 Michael Gale 所提到的,仅仅因为您启用了降低动画效果的切换按钮就完全无法看到动画版本,这似乎很可惜。
使用 <button>
来使用 JavaScript 取消媒体查询并强制浏览器显示动画版本应该很容易。
我相当肯定,无法以声明方式在 HTML 中执行此操作。我们也不能将此按钮放在 <picture>
标记内。即使 <picture>
不是替换元素,浏览器仍然会感到困惑并且不喜欢它。相反,它根本不会呈现它。没什么大不了的,我们可以使用包装器。
<div class="picture-wrap">
<picture>
<!-- sources -->
</picture>
<button class="animate-button">Animate</button>
</div>
我们可以在图像顶部某个位置放置按钮。这只是一个任意选择——您可以将其放在任何位置,或者甚至可以使整个图像都可点击,只要您认为可以向用户解释即可。请记住,仅当相同的媒体查询匹配时才显示按钮。
.picture-wrap .animate-button {
display: none;
}
@media (prefers-reduced-motion: reduce) {
.picture-wrap .animate-button {
display: block;
}
}
单击(或点击)按钮时,我们需要删除媒体查询以通过下载动画源来启动动画。
let button = document.querySelector(".animate-button");
button.addEventListener("click", () => {
const parent = button.closest(".picture-wrap");
const picture = parent.querySelector("picture");
picture.querySelector("source[media]").remove();
});
这是实际操作
查看 CodePen 上 Chris Coyier 的作品
降低动画效果技术 PLUS! (@chriscoyier)
在 CodePen 上。
也许这是一个好的组件?
我们可以使用 Web组件 自动包含按钮、按钮样式和按钮功能。嘿,为什么不呢?
查看 CodePen 上 Chris Coyier 的作品
降低动画效果技术作为 Web 组件 (@chriscoyier)
在 CodePen 上。
在我的博客中使用不太高级的东西来播放/暂停 GIF。我需要重写它以适应
prefers-reduced-motion
(并始终显示按钮?),但已经使用 Netlify 实时生成静态版本。使用 Hugo,我只需要上传一个文件,这使得它非常容易。一种可能性是始终显示切换按钮,但让切换按钮尊重
prefers-reduced-motion
偏好设置。https://twitter.com/cariefisher/status/1142106562745556992
理想情况下,浏览器会提供一个选项,启用该选项后,会自动暂停网页上的所有 GIF、视频和任何其他动画。我的想法是,由于动画是一个可访问性问题,因此浏览器需要加强并提供合适的选项,以确保受影响的用户不会在网站上遇到动画。
知道主要浏览器中不存在此类选项,我个人会使用这种方法。
仅使用视频。(无论出于何种原因,我都无意在我的网站上再次加载动画 GIF。)
如果用户启用了“降低动画效果”,则使用 JavaScript 动态暂停自动播放的视频(并添加手动播放的控件)。暂停的视频应该是足够好的回退图像(尽管 Safari 可能仍然需要海报图像,不确定)。
附注:可能是愚蠢的想法:如果我们可以根据 CSS 媒体查询声明性地设置 HTML 属性(例如
<video autoplay>
),那将是多么酷。然后我就不需要在步骤 2 中使用 JS 了。如果您想使用 Cloudinary 将动画 GIF 转换为视频,最简单的方法可能是使用 Cloudinary 的 Fetch API。
希望这可以帮助您
https://nicolas-hoizey.com/2018/08/using-cloudinary-s-fetch-api-to-convert-an-animated-gif-to-a-video.html
这是原始时事通讯文章的一个很好的扩展!我一直认为 Twitter 通过其选项切换按钮来加载图像和视频(并显示一个覆盖层,告诉您文件有多大)的做法非常棒。
这对于不影响移动体验非常有用。但并非每个网站都能拥有大量选项进行切换等的奢侈。
我也同意 Sime 的观点!我需要养成将所有内容从 GIF 替换为视频的习惯,仅仅是为了更小的文件大小。这里我所能想到的唯一其他考虑因素是,为动画 GIF 提供替代文本的简易性与提供视频脚本的简易性(假设视频中有音频)。