news 2026/9/30 1:57:51

用 CSS 实现缩放动画(Zoom In Zoom Out):@keyframes 三步动画与 scale 属性的完整实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用 CSS 实现缩放动画(Zoom In Zoom Out):@keyframes 三步动画与 scale 属性的完整实践
  • 教程
  • 文档

【免费下载链接】30-seconds-of-code

Coding articles to level up your development skills

项目地址:https://gitcode.com/gh_mirrors/30/30-seconds-of-code
点击查看免费下载

缩放进出动画(zoom in zoom out)是一种极为常见且优雅的 CSS 动效,常被用于吸引用户注意力的按钮、加载提示、营销 Banner 或品牌 Logo 等场景。本文以 30-seconds-of-code 仓库中的 zoomin-zoomout-animation.md 为骨架,完整讲解如何用@keyframes定义一个三步缩放动画、如何通过animation简写属性控制其时长、缓动与循环次数,并给出scale属性与transform: scale()两种写法的兼容性方案。读完后你将能直接复制一套可运行的缩放动画,并掌握调整缓动、延迟与循环方式的进阶技巧。

三步动画的核心原理:@keyframes 与 scale

一个缩放进出动画本质上是一个三步动画,可以直接用@keyframes定义:

  • 起始点(0%):元素保持原始尺寸,即scale: 100%;
  • 中间点(50%):元素放大到更大尺寸,例如scale: 150%;
  • 结束点(100%):元素回到原始尺寸,即scale: 100%。

动画从原始尺寸放大到 150%,再回落到原始尺寸,视觉上就产生了"先放大、再缩小"的缩放循环。这就是缩放进出动画的全部秘密——没有复杂的位移,也没有多段关键帧堆叠,只需三个关键帧即可。

[!TIP]

这里使用的是相对较新的scale独立属性(注意它直接写scale: 150%,使用的是百分比)。相比传统的transform,scale属性可以独立于transform存在,后续还可以与其他变换组合使用,不会互相覆盖。

应用动画:animation 简写属性与完整代码

定义好@keyframes之后,还需要用animation属性把它应用到元素上。原文档中的完整示例如下:

.zoom-in-out-element { animation: zoom-in-zoom-out 1s ease infinite; } @keyframes zoom-in-zoom-out { 0% { scale: 100%; } 50% { scale: 150%; } 100% { scale: 100%; } }

animation简写属性zoom-in-zoom-out 1s ease infinite依次对应:

简写片段含义说明
zoom-in-zoom-outanimation-name引用下方@keyframes定义的动画名称
1sanimation-duration单次动画持续 1 秒,可按需调整为0.5s、2s等
easeanimation-timing-function缓动函数,控制放大/缩小过程中的速度曲线
infiniteanimation-iteration-count无限循环播放;若只播 2 次可改为2

如果你偏好长写形式,效果完全等价:

.zoom-in-out-element { animation-name: zoom-in-zoom-out; animation-duration: 1s; animation-timing-function: ease; animation-iteration-count: infinite; }

这种长写拆分的方式在仓库的 alternating-text.md 中也有体现——该文章把animation-name、animation-duration、animation-iteration-count、animation-timing-function四个属性逐一写出,便于理解每个属性的独立作用。

[!NOTE]

原文档指出,本示例使用的时长1s、缓动ease与无限循环都只是默认建议,你可以根据自己的设计需求自由调整这几个值。

兼容性方案:scale 属性与 transform: scale() 互换

原文档特别给出了一个兼容性提醒:scale是相对较新的 CSS 属性。如果你担心旧浏览器兼容性,可以无缝替换为传统的transform写法:

.zoom-in-out-element { animation: zoom-in-zoom-out 1s ease infinite; } @keyframes zoom-in-zoom-out { 0% { transform: scale(1, 1); } 50% { transform: scale(1.5, 1.5); } 100% { transform: scale(1, 1); } }

两种写法的对应关系非常直观:

  • scale: 100%↔transform: scale(1, 1)
  • scale: 150%↔transform: scale(1.5, 1.5)

scale(1, 1)表示在 X 轴、Y 轴上均保持 1 倍(原始大小),scale(1.5, 1.5)表示两个轴都放大到 1.5 倍。这种"新属性 ↔ 传统 transform"的互换思路在仓库其他文章中也有体现,例如 button-hover-transitions.md 中就提示可以将悬停放大效果里的transform: scale(1.1)替换为scale: 110%。

进阶:让缩放动画更精致的三个技巧

原文档只给了基础版本,结合仓库中同属 CSS 动画系列的其他片段,还可以快速升级这个效果。

1. 更换缓动函数,让动画更有质感

ease是默认缓动,适用于大多数场景。若希望放大和缩回的过程节奏更统一,可以改用ease-in-out:

.zoom-in-out-element { animation: zoom-in-zoom-out 1s ease-in-out infinite; }

更进阶的做法是使用cubic-bezier()自定义贝塞尔曲线。仓库中的 easing-variables.md 提供了整套缓动变量,例如--ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1)。你可以把缓动抽成变量后应用到缩放动画上:

:root { --ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1); } .zoom-in-out-element { animation: zoom-in-zoom-out 1s var(--ease-in-out-cubic) infinite; }

2. 用 animation-delay 制造交错效果

如果页面上有多个元素需要依次缩放(例如多个卡片、多个图标),可以为每个元素设置不同的animation-delay,让动画依次启动而不是同时启动。这一技巧在 loaders.md 的弹跳加载器(bouncing loader)中得到了完整示范——三个小球分别使用animation-delay: 0s、0.2s、0.4s产生依次弹跳的节奏:

.zoom-item:nth-child(1) { animation: zoom-in-zoom-out 1s ease infinite 0s; } .zoom-item:nth-child(2) { animation: zoom-in-zoom-out 1s ease infinite 0.2s; } .zoom-item:nth-child(3) { animation: zoom-in-zoom-out 1s ease infinite 0.4s; }

3. 用 animation-direction 实现两段式缩放

如果不需要"放大再缩小"的完整循环,只想让元素在两个状态之间往复,可以只用两个关键帧,并配合animation-direction: alternate。loaders.md中的弹跳球动画正是用0.6s infinite alternate在两个关键帧之间往返。缩放的简化版本如下:

.zoom-pulse { animation: zoom-pulse 1s ease-in-out infinite alternate; } @keyframes zoom-pulse { from { scale: 100%; } to { scale: 120%; } }

4. 控制循环次数:有限次动画

并不是所有场景都需要无限循环。原文档示例使用了infinite,但在"用户输入错误时抖动提示"这类场景中,动画通常只应播放有限次数。仓库中的 shake-invalid-input.md 展示了animation: shake 0.2s ease-in-out 0s 2的写法——第 4 个位置是animation-delay: 0s,最后一个数字2表示只播放 2 次。缩放动画同样可以这样控制,例如"放大提醒后停止":

.zoom-alert { animation: zoom-in-zoom-out 1s ease 0s 2; }

实战建议与可访问性注意

  • 优先使用scale或transform做缩放:缩放属于合成器(compositor)友好的变换类属性,相比逐帧改变width、height或margin,动画过程通常更流畅。仓库中 loaders.md 在讲解弹跳球时也特别提到使用transform: translate3d()以获得更好的动画性能,思路一致。
  • 尊重用户的减弱动效偏好:无限循环的缩放动画对部分用户(如前庭功能障碍者)可能造成不适。可以考虑用prefers-reduced-motion媒体查询在系统开启"减少动态效果"时关闭动画:
@media (prefers-reduced-motion: reduce) { .zoom-in-out-element { animation: none; } }
  • 控制动画规模与频率:持续的缩放动效适合按钮、加载状态或短暂的品牌展示;若页面中多个元素同时无限缩放,容易分散用户注意力,建议按上文的animation-delay交错或改用有限次数。

在 30-seconds-of-code 中的位置与延伸阅读

本片段位于 content/snippets/css/s/zoomin-zoomout-animation.md,归属于 CSS 动画集合。仓库中 content/collections/css/animation.yaml 通过tagMatcher: animation将本片段归入 "CSS Animations" 集合,你可以在这个集合下继续探索更多动画主题:

  • loaders.md:弹跳球、脉冲涟漪、甜甜圈加载器,覆盖animation-delay、animation-direction与transform的更多组合;
  • alternating-text.md:通过animationiteration事件驱动文字轮换,展示animation长写属性与 JS 配合的用法;
  • shake-invalid-input.md:结合:invalid伪类与有限次数动画的反馈动效;
  • button-hover-transitions.md:scale属性与transform: scale()互换的悬停场景;
  • easing-variables.md:一整套cubic-bezier()缓动变量,可直接用于自定义缩放节奏。

以上就是用 CSS 实现缩放进出动画的完整方案:三步关键帧定义核心动作,animation简写属性控制节奏,scale/transform双写法兼顾新旧浏览器,再配合缓动、延迟与方向控制即可轻松适配各种交互场景。

  • 教程
  • 文档

【免费下载链接】30-seconds-of-code

Coding articles to level up your development skills

项目地址:https://gitcode.com/gh_mirrors/30/30-seconds-of-code
点击查看免费下载
上一篇:PyTorch Grad-CAM终极指南:从论文复现到实际应用的关键差异
下一篇:Emoji Mart终极指南:从初始化到事件处理的完整API解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 1:57:42

ESPHome 接一个电磁阀:从接线到手机可控的 4 步

ESPHome 接一个电磁阀:从接线到手机可控的 4 步 【免费下载链接】esphome ESPHome is a system to control your ESP32, ESP8266, BK72xx, RP2040 by simple yet powerful configuration files and control them remotely through Home Automation systems. 项目地…

作者头像 李华
网站建设 2026/9/30 1:56:05

使用 Git grep 在 30-seconds-of-code 仓库中查找匹配文件

教程文档 【免费下载链接】30-seconds-of-code Coding articles to level up your development skills 项目地址: https://gitcode.com/gh_mirrors/30/30-seconds-of-code 点击查看 免费下载 导读 git grep 是 Git 内置的文本搜索命令,它不只是 grep 的…

作者头像 李华
网站建设 2026/9/30 1:54:34

阿里游戏客户端HRG面核心逻辑:工业化协作能力验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 1:54:24

基于动态参数HMM的水声目标线谱轨迹提取方法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华