导读:本期聚焦于森沢创作的《CSS3动画@keyframes怎么实现图片变大变小和颜色变化?》,敬请观看详情。网页里的图片如何才能自动放大缩小,同时颜色还跟着一起渐变?答案就藏在CSS3的@keyframes动画里。本文从动画的基本原理讲起,先介绍@keyframes规则和animation属性的写法,再用transform的scale控制图片缩放,借助filter的hue-rotate和背景色过渡实现颜色变化,最后给出一个把缩放与变色组合起来的完整案例,并补充动画性能优化的几个小技巧,帮你做出流畅又不卡顿的动效。

做网页动效时,图片的缩放和颜色变化是最常见的两种效果。有人用JavaScript写定时器去改宽高,代码一大堆还容易掉帧,其实CSS3提供的@keyframes规则配合animation属性,几行代码就能让图片平滑地变大变小,颜色也能随之渐变,浏览器还会自动做性能优化,比脚本动画流畅得多。本文把这套动画的写法完整拆开讲一遍,看完直接就能用到自己的项目里。

CSS3动画@keyframes怎么实现图片变大变小和颜色变化?

@keyframes规则与animation属性基础

先说清楚@keyframes到底是什么。它是一个用来定义动画关键帧的规则,你可以把它理解成动画的“剧本”:在0%的时候元素是什么状态,在50%的时候变成什么状态,到100%的时候又是什么状态,都由你来编写。浏览器拿到这个剧本后,会自动把中间的过渡过程补齐,形成连续的动画。

剧本写好后,还需要让某个元素去“演出”,这就轮到animation属性出场了。它有以下几个常用子属性:animation-name指定要使用的关键帧名称,animation-duration设置一次动画的时长,animation-iteration-count控制播放次数(写infinite就是无限循环),animation-timing-function决定动画的速度曲线,animation-direction可以设置是否来回交替播放。一个最简的写法如下:

.box {
    animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
    0%   { transform: scale(1); }
    50%  { transform: scale(1.3); }
    100% { transform: scale(1); }
}

这段代码的意思是:类名为box的元素会循环播放名为pulse的动画,一个周期2秒。动画从原始大小开始,中间放大到1.3倍,最后又缩回原样。ease-in-out让变化先慢后快再慢,看起来更自然。如果希望图片放大后再“倒放”回去,可以加一句animation-direction: alternate,不过上面的写法已经在100%处回到了初始状态,两种方式效果接近,按需选择即可。

用transform的scale实现图片变大变小

控制元素大小有两条路:一是直接改width和height,二是用transform: scale()。强烈推荐第二种。原因在于width和height的变化会触发浏览器的回流重排,每一帧都要重新计算布局,性能开销大;而transform属于合成层操作,浏览器只需在GPU上对元素做缩放变换,不触发布局计算,动画非常流畅。

scale接收的参数是缩放倍数,1表示原始大小,1.5表示放大到1.5倍,0.5则是缩小一半。还可以传两个参数分别控制水平和垂直方向,比如scale(1.2, 0.8)表示横向拉伸、纵向压缩。下面给一个图片呼吸效果的实际例子,这是电商网站商品图上很常用的动效:

<div class="img-wrap">
    <img src="product.jpg" class="breath-img" alt="商品图">
</div>

<style>
.breath-img {
    width: 300px;
    animation: breathe 3s ease-in-out infinite;
}
@keyframes breathe {
    0%   { transform: scale(1); }
    50%  { transform: scale(1.15); }
    100% { transform: scale(1); }
}
</style>

有个细节需要注意:scale缩放不会改变元素占用的布局空间,也就是说图片放大时可能覆盖到周围的内容。如果不想遮挡邻居元素,可以给外层容器设置overflow: hidden,或者预留足够的边距。另外,为了让缩放以中心点为准,可以配合transform-origin: center,这个属性默认就是center,一般不用额外设置,但一旦你发现缩放的原点不对,第一个要检查的就是它。

颜色变化的两种实现方式

颜色变化在CSS3动画里有两条主流路线,各自适合不同的场景。第一种是直接对颜色属性做过渡,比如背景色从红色渐变到蓝色,浏览器会在关键帧之间自动做颜色插值,写法非常直观:

.color-box {
    width: 200px;
    height: 200px;
    animation: colorShift 4s linear infinite;
}
@keyframes colorShift {
    0%   { background-color: #ff6b6b; }
    33%  { background-color: #feca57; }
    66%  { background-color: #48dbfb; }
    100% { background-color: #ff6b6b; }
}

这里的关键帧用了33%和66%做中间节点,让红、黄、蓝三种颜色依次过渡,最后回到红色形成无缝循环。注意animation-duration设为4秒,那么每个颜色阶段大约各占1.3秒,节奏比较舒缓。如果你希望颜色跳变而不是平滑过渡,可以在相邻两个关键帧写相同的百分比,比如33%和34%分别写两种颜色,过渡时间几乎为零,看起来就是瞬间切换。

第二种方式是针对图片本身。图片的像素内容没法直接用background-color改,这时候要用filter滤镜。其中hue-rotate可以旋转色相,让图片整体呈现不同色调;grayscale能做黑白过渡;sepia则是复古泛黄效果。例如让一张图片在正常色调和暖色调之间来回变化:

.tone-img {
    width: 300px;
    animation: toneShift 5s ease-in-out infinite;
}
@keyframes toneShift {
    0%, 100% { filter: hue-rotate(0deg) saturate(1); }
    50%      { filter: hue-rotate(45deg) saturate(1.4); }
}

hue-rotate的取值范围是0到360度,50度左右偏黄绿,180度左右接近反色。saturate控制饱和度,1是原图,大于1会更鲜艳。需要注意的是,filter动画虽然不触发重排,但每一帧都要对像素做计算,大面积图片上可能有一定开销,建议对尺寸适中的图片使用,或者用will-change: filter提前告知浏览器做优化。

缩放与变色组合的完整案例

把前面的两个效果合到一个@keyframes里,就能得到一个既有大小变化又有颜色变化的完整动画。假设要做一个活动的推广图,图片循环呼吸式放大,同时叠加一层不断变换颜色的光晕,整体代码如下:

<div class="promo">
    <img src="banner.jpg" class="promo-img" alt="活动图">
</div>

<style>
.promo {
    position: relative;
    width: 400px;
    margin: 50px auto;
}
.promo-img {
    width: 100%;
    display: block;
    border-radius: 12px;
    animation: zoomTone 4s ease-in-out infinite;
}
@keyframes zoomTone {
    0% {
        transform: scale(1);
        filter: hue-rotate(0deg) brightness(1);
    }
    50% {
        transform: scale(1.2);
        filter: hue-rotate(30deg) brightness(1.15);
    }
    100% {
        transform: scale(1);
        filter: hue-rotate(0deg) brightness(1);
    }
}
</style>

这个例子把transform和filter写在同一个关键帧里,浏览器会同时对两个属性做插值,缩放和变色严格同步,视觉上非常协调。brightness让图片在放大时稍微提亮,产生一种被“点亮”的感觉。如果还想加文字变色,可以在容器里再放一层文字,给它单独写一个只改color的关键帧,两个动画同时播放互不干扰。

动画体验优化与兼容性建议

动画写完不等于万事大吉,实际部署前还有几点值得注意。首先是性能方面,尽量把动画限制在transform和opacity这两个属性上,它们能完全交给GPU处理;filter虽好用但开销略高,移动端上要控制使用面积。其次,如果动画元素会被频繁操作,可以加上will-change: transform, filter,让浏览器提前创建独立合成层,减少运行时的卡顿,但这个属性不要滥用,设置太多层反而浪费内存。

其次是用户偏好问题。部分用户会在系统里开启“减少动态效果”的选项,出于无障碍考虑,可以用媒体查询尊重他们的选择:

@media (prefers-reduced-motion: reduce) {
    .promo-img {
        animation: none;
    }
}

最后是兼容性。@keyframes、animation和transform在目前主流浏览器中都已经支持得很好,包括移动端浏览器,基本不需要加-webkit-前缀。只有一些老旧的iOS版本和Android WebView需要前缀,如果你的项目还要兼容它们,可以在animation前面加一行-webkit-animation,在@keyframes前加@-webkit-keyframes做兜底。一般现代项目直接写标准语法即可。掌握这些要点后,图片的缩放、变色动画就都能信手拈来了。

CSS3动画@keyframestransform修改时间:2026-09-06 11:22:41

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260906/51514.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。