2015年前端开发已经进入了CSS3的时代。

以前要实现网页动画效果要么用JavaScript要么用Flash要么用GIF图片。这些方式要么性能差要么开发复杂要么效果不好。

而CSS3带来了强大的动画和过渡功能。通过纯CSS就能实现各种炫酷的动画效果而且性能好开发简单兼容性也越来越好了。

作为一个前端爱好者我一直很喜欢研究CSS3的动画效果。今天就来分享一下CSS3动画和过渡的实战技巧帮大家让自己的网页动起来。

CSS3过渡(Transition)

CSS3过渡是最简单的动画效果。它能让元素的某个属性在一段时间内平滑地变化而不是瞬间变化。

基本用法

transition属性的基本语法:

transition: property duration timing-function delay;
  • property:要过渡的属性比如width、height、background、opacity、transform等。可以用all表示所有属性。
  • duration:过渡持续的时间比如1s、500ms。
  • timing-function:过渡的时间函数比如ease、linear、ease-in、ease-out、ease-in-out、cubic-bezier()。
  • delay:过渡开始前的延迟时间比如1s、200ms。

比如一个简单的按钮悬停效果:

.button {
    background-color: #3498db;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.3s ease;
}

.button:hover {
    background-color: #2980b9;
}

这样当鼠标悬停在按钮上时背景色会在0.3秒内平滑地从,#3498db过渡到,#2980b9而不是瞬间变化。

多个属性过渡

如果要过渡多个属性可以用逗号分隔:

.button {
    transition: background-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
}

.button:hover {
    background-color: #2980b9;
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

也可以用all过渡所有属性:

.button {
    transition: all 0.3s ease;
}

但是不建议滥用all因为它会过渡所有属性包括一些你不想过渡的属性可能会影响性能。最好明确指定要过渡的属性。

时间函数

时间函数决定了过渡的速度变化。常用的时间函数:

  • linear:匀速速度不变。
  • ease:默认值慢-快-慢开始慢中间快结束慢。
  • ease-in:慢入开始慢越来越快。
  • ease-out:慢出开始快越来越慢。
  • ease-in-out:慢入慢出开始慢中间快结束慢。
  • cubic-bezier(n,n,n,n):自定义贝塞尔曲线可以实现各种复杂的速度变化。

比如一个弹性效果:

.box {
    transition: transform 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

.box:hover {
    transform: scale(1.2);
}

这个cubic-bezier会让元素先缩小一点再放大超过目标值再弹回来实现弹性效果。

过渡实战:卡片悬停效果

下面实现一个常见的卡片悬停效果:

<div class="card">
    <img src="image.jpg" alt="图片">
    <h3>卡片标题</h3>
    <p>卡片内容描述...</p>
</div>
.card {
    width: 300px;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card:hover {
    transform: translateY(-5px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}

.card img {
    width: 100%;
    height: 200px;
    object-fit: cover;
    transition: transform 0.5s ease;
}

.card:hover img {
    transform: scale(1.05);
}

这样当鼠标悬停在卡片上时卡片会向上移动5px阴影会变大图片会放大1.05倍实现一个很有质感的悬停效果。

CSS3动画(Animation)

CSS3动画比过渡更强大。它能定义多个关键帧实现更复杂的动画效果。

基本用法

CSS3动画需要两步:

  1. 用,@keyframes定义动画的关键帧。
  2. 用animation属性把动画应用到元素上。

比如一个简单的淡入动画:

@keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

.fade-in {
    animation: fadeIn 1s ease;
}

@keyframes定义了一个叫fadeIn的动画。from表示动画开始时的状态;to表示动画结束时的状态。

animation属性的基本语法:

animation: name duration timing-function delay iteration-count direction fill-mode play-state;
  • name:动画名称对应,@keyframes的名字。
  • duration:动画持续时间。
  • timing-function:时间函数和过渡一样。
  • delay:动画开始前的延迟。
  • iteration-count:动画播放次数可以是数字或infinite(无限循环)。
  • direction:动画方向normal(正常)、reverse(反向)、alternate(交替)、alternate-reverse(反向交替)。
  • fill-mode:动画填充模式none、forwards(保持结束状态)、backwards(应用开始状态)、both。
  • play-state:动画播放状态running(播放)、paused(暂停)。

多关键帧动画

除了from和to还可以用百分比定义多个关键帧:

@keyframes bounce {
    0%, 20%, 50%, 80%, 100% {
        transform: translateY(0);
    }
    40% {
        transform: translateY(-30px);
    }
    60% {
        transform: translateY(-15px);
    }
}

.bounce {
    animation: bounce 1s ease;
}

这个动画实现了一个弹跳效果。元素会先向上跳30px落下来再向上跳15px再落下来。

动画实战:加载动画

下面实现一个常见的加载动画旋转的圆圈:

<div class="spinner"></div>
.spinner {
    width: 40px;
    height: 40px;
    border: 4px solid #f3f3f3;
    border-top: 4px solid #3498db;
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

这样就实现了一个旋转的加载圆圈。border设置了4个边的颜色其中上边是蓝色其他边是浅灰色。然后用animation让它无限旋转。

再比如一个跳动的点加载动画:

<div class="dots">
    <span></span>
    <span></span>
    <span></span>
</div>
.dots span {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: #3498db;
    margin: 0 3px;
    animation: dotBounce 1.4s ease-in-out infinite both;
}

.dots span:nth-child(1) {
    animation-delay: -0.32s;
}

.dots span:nth-child(2) {
    animation-delay: -0.16s;
}

@keyframes dotBounce {
    0%, 80%, 100% {
        transform: scale(0);
    }
    40% {
        transform: scale(1);
    }
}

这样三个点会依次跳动实现一个很常见的加载动画。

动画实战:页面入场动画

CSS3动画还常用于页面元素的入场动画。比如页面加载后元素依次淡入上移。

@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.fade-in-up {
    opacity: 0;
    animation: fadeInUp 0.6s ease forwards;
}

.fade-in-up:nth-child(1) { animation-delay: 0.1s; }
.fade-in-up:nth-child(2) { animation-delay: 0.2s; }
.fade-in-up:nth-child(3) { animation-delay: 0.3s; }

这样元素会依次淡入上移实现一个很流畅的入场效果。注意要设置opacity: 0和forwards否则动画结束后元素会回到初始状态。

CSS3变换(Transform)

CSS3变换虽然不是动画但它常和过渡动画配合使用实现各种炫酷的效果。

transform属性支持以下变换:

平移(Translate)

.box {
    transform: translate(50px, 30px);
    /* 也可以分开写 */
    transform: translateX(50px);
    transform: translateY(30px);
}

平移元素沿X轴和Y轴移动。

缩放(Scale)

.box {
    transform: scale(1.5);
    /* 也可以分开写 */
    transform: scaleX(1.5);
    transform: scaleY(0.8);
}

缩放元素放大或缩小。

旋转(Rotate)

.box {
    transform: rotate(45deg);
    /* 也可以分开写 */
    transform: rotateX(45deg);
    transform: rotateY(45deg);
}

旋转元素顺时针或逆时针旋转。rotateX和rotateY是3D旋转。

倾斜(Skew)

.box {
    transform: skew(20deg, 10deg);
    /* 也可以分开写 */
    transform: skewX(20deg);
    transform: skewY(10deg);
}

倾斜元素沿X轴和Y轴倾斜。

组合变换

多个变换可以组合使用:

.box {
    transform: translate(50px, 30px) rotate(45deg) scale(1.5);
}

注意变换的顺序很重要。不同的顺序会得到不同的结果。

变换原点

默认变换的原点是元素的中心。可以用transform-origin改变原点:

.box {
    transform-origin: top left;
    /* 也可以用百分比 */
    transform-origin: 0% 0%;
}

3D变换

CSS3还支持3D变换:

.container {
    perspective: 1000px;
}

.box {
    transform: rotateY(45deg);
    transform-style: preserve-3d;
    backface-visibility: hidden;
}
  • perspective:设置透视距离决定了3D效果的强度。
  • transform-style: preserve-3d:让子元素保留3D变换。
  • backface-visibility: hidden:隐藏元素的背面。

通过3D变换可以实现3D翻转卡片3D旋转木马等炫酷的效果。

性能优化

CSS3动画虽然强大但如果使用不当可能会影响性能。下面分享几个性能优化的技巧。

1. 使用transform和opacity

在CSS属性中transform和opacity是最高性能的动画属性。因为它们不会触发浏览器的重排(reflow),和重绘(repaint),而是直接由GPU合成性能非常,好。

而像width、height、margin、padding、top、left等属性会触发重排性能较差。所以在做动画时尽量用transform代替top/left用opacity代替display。

比如移动元素不要用top/left而用transform: translate()。

2. 开启硬件加速

可以用transform: translateZ(0),或will-change开启硬件加速让GPU参与动画渲染提高性能。

.animated {
    transform: translateZ(0);
    /* 或者 */
    will-change: transform, opacity;
}

但是不要滥用硬件加速。开启硬件加速会占用更多的内存和GPU资源。只在需要动画的元素上开启。

3. 避免同时动画太多元素

同时动画太多元素会消耗大量的CPU和GPU资源导致卡顿。尽量控制同时动画的元素数量。

如果需要动画大量元素可以考虑用Canvas或WebGL而不是CSS动画。

4. 使用animation-delay错开动画

如果有多个元素需要动画不要让它们同时开始而用animation-delay错开动画时间。这样可以避免瞬间的性能峰值让动画更流畅。

5. 尊重用户的减少动画偏好

有些用户可能因为前庭障碍或其他原因不喜欢动画。可以用prefers-reduced-motion媒体查询尊重用户的偏好:

@media (prefers-reduced-motion: reduce) {
    * {
        animation: none !important;
        transition: none !important;
    }
}

这样当用户在系统设置中开启了,"减少动态效果",时页面的动画会被禁用。

兼容性

2015年CSS3动画和过渡的兼容性已经比较好了。主流浏览器Chrome、Firefox、Safari、Opera都支持。IE需要IE10+,才支持。

如果需要兼容老版本浏览器可以加浏览器前缀:

.box {
    -webkit-transition: all 0.3s ease;
    -moz-transition: all 0.3s ease;
    -o-transition: all 0.3s ease;
    transition: all 0.3s ease;
}

@-webkit-keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

但是2015年大部分现代浏览器已经不需要前缀了。可以用Autoprefixer工具自动添加前缀不用手动,写。

实用动画库

如果不想自己写动画可以用一些现成的CSS动画,库:

  1. Animate.css:最流行的CSS动画库包含几十种动画效果引入就能,用。https://daneden.github.io/animate.css/
  2. Hover.css:专门的悬停效果库包含各种按钮链接的悬停效果。
  3. Magic Animations:包含各种炫酷的动画效果。
  4. CSShake:专门的抖动动画,库。

这些动画库都很好用引入CSS文件加类名就能,用。但是它们通常比较大如果只需要几个效果建议自己写或者只引入需要的部分。

写在最后

CSS3动画和过渡是前端开发中非常重要的技能。通过它们可以让网页更生动更有趣提升用户体验。

但是动画不是越多越好。过多的动画会让页面显得花哨影响性能甚至让用户感到不适。好的动画应该是恰到好处的自然的流畅的能提升用户体验而不是为了动画而动画。

学习CSS3动画最好的方法就是多写多练多看。看别人的优秀作品分析他们的动画实现然后自己动手实现。慢慢地你就能掌握CSS3动画的精髓做出炫酷而流畅的动画效果。

2015年前端技术发展很快。CSS3,HTML5,JavaScript各种框架库层出不穷。但是基础永远是最重要的。CSS3动画和过渡就是前端基础中非常重要的一部分。希望这篇文章能帮大家更好地掌握CSS3动画和过渡让自己的网页动起来。

"好的设计是无形的。" 好的动画也是如此。它应该自然地融入页面提升用户体验而不突兀。希望大家都能做出自然流畅优雅的CSS3动画。