三十的博客

Css 过渡和变换分步学习指南

本文内容基于 AI 生成结果整理,可能包含不准确信息,仅供参考使用。
发布时间
最后更新
阅读量 加载中...

基础概念

什么是 CSS 变换

变换可以改变元素的形状、位置和大小,但不影响文档流。

示例:

此演示仅在桌面端浏览器中可用

<!DOCTYPE html>
<html>
  <head>
    <style>
      .box {
        width: 100px;
        height: 100px;
        background-color: blue;
        margin: 50px;
        /* 水平移动50px */
        transform: translateX(50px);
      }
    </style>
  </head>
  <body>
    <div class="box"></div>
    <p>这个蓝色方块被向右移动了50px</p>
  </body>
</html>

什么是 CSS 过渡

过渡可以让 CSS 属性的变化变得平滑。

示例:

此演示仅在桌面端浏览器中可用

<!DOCTYPE html>
<html>
  <head>
    <style>
      .box {
        width: 100px;
        height: 100px;
        background-color: red;
        margin: 50px;
        /* 设置过渡:所有属性变化用时0.5秒 */
        transition: all 0.5s;
      }
      .box:hover {
        width: 200px;
      }
    </style>
  </head>
  <body>
    <div class="box"></div>
    <p>鼠标悬停在红色方块上,它会平滑地变宽</p>
  </body>
</html>

属性详解

过渡属性详解

transition 是 CSS3 中用来实现元素状态间平滑过渡的属性,它由以下几个子属性组成:

完整语法

transition: [property] [duration] [timing-function] [delay];

子属性说明

属性 说明 示例值
transition-property 指定过渡的 CSS 属性 all, width, opacity
transition-duration 过渡持续时间 0.3s, 1s, 500ms
transition-timing-function 过渡速度曲线 ease, linear, ease-in-out
transition-delay 过渡开始前的延迟时间 0s, 0.5s

简写示例

/* 所有属性变化,0.3秒完成,使用默认缓动,无延迟 */
transition: all 0.3s;

/* 仅宽度和透明度变化,1秒完成,慢快慢缓动,延迟0.2秒 */
transition: width 1s ease, opacity 1s ease 0.2s;

变换属性详解

transform 允许你对元素进行旋转、缩放、移动或倾斜等变换。

常用变换函数

函数 说明 示例
translate() 移动元素 translateX(10px), translate(10px, 20px)
rotate() 旋转元素 rotate(45deg)
scale() 缩放元素 scale(1.5), scaleX(2)
skew() 倾斜元素 skewX(15deg), skewY(10deg)
matrix() 矩阵变换 matrix(1, 0, 0, 1, 0, 0)

组合变换

可以同时应用多个变换函数:

transform: translateX(10px) rotate(45deg) scale(1.2);
当同时应用多个变换函数时,效果是按从右到左的顺序依次执行,每个变换都会影响下一个变换的坐标系,最终产生组合效果。

变换原点

使用 transform-origin 可以改变变换的基准点:

transform-origin: 50% 50%; /* 默认值,中心点 */
transform-origin: left top; /* 左上角 */
transform-origin: 20px 50px; /* 具体坐标 */

组合使用

变换 + 过渡

此演示仅在桌面端浏览器中可用

<!DOCTYPE html>
<html>
  <head>
    <style>
      .box {
        width: 100px;
        height: 100px;
        background-color: green;
        margin: 50px;
        transition: all 0.3s;
      }
      .box:hover {
        transform: translateX(20px);
        background-color: orange;
      }
    </style>
  </head>
  <body>
    <div class="box"></div>
    <p>鼠标悬停时,方块会向右移动并变色</p>
  </body>
</html>

过渡的各个属性

此演示仅在桌面端浏览器中可用

<!DOCTYPE html>
<html>
  <head>
    <style>
      .box {
        width: 100px;
        height: 100px;
        background-color: purple;
        margin: 50px;
        /* 分解的transition属性 */
        transition-property: transform, background-color;
        transition-duration: 1s;
        transition-timing-function: ease-in-out;
        transition-delay: 0.2s;
      }
      .box:hover {
        transform: translateX(50px) rotate(45deg);
        background-color: pink;
      }
    </style>
  </head>
  <body>
    <div class="box"></div>
    <p>鼠标悬停时,方块会向右移动、旋转45度并变色,有延迟和缓动效果</p>
  </body>
</html>

多种变换组合

此演示仅在桌面端浏览器中可用

<!DOCTYPE html>
<html>
  <head>
    <style>
      .box {
        width: 100px;
        height: 100px;
        background-color: teal;
        margin: 100px;
        transition: all 0.5s;
      }
      .box:hover {
        /* 组合变换:移动、旋转、缩放 */
        transform: translateX(50px) rotate(30deg) scale(1.5);
        background-color: gold;
      }
    </style>
  </head>
  <body>
    <div class="box"></div>
    <p>鼠标悬停时,方块会移动、旋转、放大并变色</p>
  </body>
</html>

实际应用

按钮悬停效果

此演示仅在桌面端浏览器中可用

<!DOCTYPE html>
<html>
  <head>
    <style>
      .button {
        display: inline-block;
        padding: 10px 20px;
        background-color: #4caf50;
        color: white;
        text-decoration: none;
        border-radius: 5px;
        transition: all 0.3s;
      }
      .button:hover {
        transform: translateY(-3px);
        box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
        background-color: #45a049;
      }
    </style>
  </head>
  <body>
    <a href="#" class="button">悬停按钮</a>
    <p>鼠标悬停时,按钮会上浮并显示阴影</p>
  </body>
</html>

书悬停打开效果

此演示仅在桌面端浏览器中可用

<!DOCTYPE html>
<html>
  <head>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      .book {
        position: relative;
        height: 280px;
        width: 240px;
        margin: 10px auto;
      }

      .book div {
        position: absolute;
        top: 0;
        left: 0;
        width: 240px;
        height: 280px;
        border-radius: 0 30px 40px 40px;
        transition: 0.8s cubic-bezier(0.075, 0.82, 0.165, 1);
      }

      .book .front {
        z-index: 1;
        background-color: rgba(255, 255, 255, 0.4);
        backdrop-filter: blur(40px);
      }

      .book .back {
        width: 220px;
        background-color: purple;
        transform-origin: left top;
        transform: skewY(8deg);
      }

      .book:hover .front {
        transform: translateY(-3px);
      }

      .book:hover .back {
        width: 200px;
        transform: skewY(15deg);
      }
    </style>
  </head>
  <body>
    <div class="book">
      <div class="front"></div>
      <div class="back"></div>
    </div>
  </body>
</html>

3D卡片悬浮展开效果

此演示仅在桌面端浏览器中可用

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>wanglei.live</title>
    <style>
      .box {
        position: relative;
        width: 80%;
        margin: 10px auto;
        perspective: 5000px;
        perspective-origin: left bottom;
        transform-style: flat;
      }

      .box > * {
        transform: rotateY(-20deg) rotateX(20deg);
        transition: 2s cubic-bezier(0.075, 0.82, 0.165, 1);
      }

      .box:hover > * {
        transform: rotateY(0deg) rotateX(0deg);
      }

      .box:hover .item1 {
        transform: translate(-30px, -30px);
      }

      .box:hover .item2 {
        transform: translate(0px, -30px);
      }
      .box:hover .item3 {
        transform: translate(0px, 0px);
      }
      .box:hover .item4 {
        transform: translate(-120px, 60px);
        z-index: 4;
      }
      .box:hover .item5 {
        transform: translate(30px, 30px);
        z-index: 5;
      }

      .item1 {
        position: absolute;
        top: 150px;
        left: -37px;
        width: 183px;
        height: 120px;
        border-radius: 10px;
        background: radial-gradient(
          218.51% 281.09% at 100% 100%,
          rgba(253, 63, 51, 0.6) 0%,
          rgba(76, 0, 200, 0.6) 45.83%,
          rgba(76, 0, 200, 0.6) 100%
        );
      }

      .item2 {
        position: absolute;
        top: 150px;
        left: 176px;
        width: 183px;
        height: 120px;
        border-radius: 10px;
        background: linear-gradient(
          192.64deg,
          rgb(67, 22, 219) 12.72%,
          rgb(144, 118, 231) 54.49%,
          rgb(162, 238, 255) 100.01%
        );
        box-shadow: rgba(0, 0, 0, 0.25) 0px 20px 40px,
          rgba(255, 255, 255, 0.2) 0px 0px 0px 0.5px inset;
      }
      .item3 {
        position: absolute;
        top: 200px;
        left: 0;
        width: 701px;
        height: 428px;
        border-radius: 10px;
        backdrop-filter: blur(10px);
        background: rgba(23, 12, 61, 0.3);
        box-shadow: rgba(0, 0, 0, 0.25) 0px 20px 40px,
          rgba(255, 255, 255, 0.2) 0px 0px 0px 0.5px inset;
      }
      .item4 {
        position: absolute;
        top: 370px;
        left: 40px;
        background: rgba(23, 12, 61, 0.2);
        width: 400px;
        height: 273px;
        border-radius: 10px;
        backdrop-filter: blur(10px);
        box-shadow: rgba(255, 255, 255, 0.2) 0px 0px 0px 0.5px inset;
      }
      .item5 {
        position: absolute;
        top: 400px;
        left: 340px;
        background: rgba(23, 12, 61, 0.2);
        width: 414px;
        height: 273px;
        border-radius: 10px;
        backdrop-filter: blur(10px);
        box-shadow: rgba(255, 255, 255, 0.2) 0px 0px 0px 0.5px inset;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="item1"><img src="./svg/svg1.svg" alt="" /></div>
      <div class="item2"><img src="./svg/svg1.svg" alt="" /></div>
      <div class="item3"><img src="./svg/svg2.svg" alt="" /></div>
      <div class="item4"><img src="./svg/svg3.svg" alt="" /></div>
      <div class="item5"><img src="./svg/svg4.svg" alt="" /></div>
    </div>
  </body>
</html>

网格悬停聚焦布局

此演示仅在桌面端浏览器中可用

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>wanglei.live</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      ul,
      ol {
        list-style: none;
      }

      .box {
        width: 80%;
        margin: 10px auto;
        overflow: hidden;
      }

      .box > ul {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        grid-template-rows: 100px;
        gap: 3px;
        transition: all 0.3s;
      }

      ul > .item:nth-child(1) {
        background-color: lightpink;
      }

      ul > .item:nth-child(2) {
        background-color: lightblue;
      }

      ul > .item:nth-child(3) {
        background-color: lightgreen;
      }

      ul > .item:nth-child(4) {
        background-color: lightgray;
      }

      ul:has(.item:nth-child(1):hover) {
        grid-template-columns: 2fr 1fr 1fr 1fr;
      }

      ul:has(.item:nth-child(2):hover) {
        grid-template-columns: 1fr 2fr 1fr 1fr;
      }

      ul:has(.item:nth-child(3):hover) {
        grid-template-columns: 1fr 1fr 2fr 1fr;
      }

      ul:has(.item:nth-child(4):hover) {
        grid-template-columns: 1fr 1fr 1fr 2fr;
      }

      .item {
        position: relative;
      }

      .item:hover > p {
        transform: translateY(0);
        transition: all 0.3s;
      }

      .item > p {
        position: absolute;
        left: 0;
        bottom: 0;
        transform: translateY(100px);
        padding: 10px;
        color: white;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <ul>
        <li class="item">
          <p>我是一段描述文字。</p>
        </li>
        <li class="item">
          <p>我是一段描述文字。</p>
        </li>
        <li class="item">
          <p>我是一段描述文字。</p>
        </li>
        <li class="item">
          <p>我是一段描述文字。</p>
        </li>
      </ul>
    </div>
  </body>
</html>

无缝轮播动画

此演示仅在桌面端浏览器中可用

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>wanglei.live</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      .box {
        width: 415px;
        margin: 10px auto;
        overflow: hidden;
      }

      .box:hover .scroll {
        animation-play-state: paused;
      }

      .scroll {
        display: flex;
        width: 840px;
        animation: move 6s linear infinite;
      }

      .item1 > * {
        width: 100px;
        height: 50px;
        line-height: 50px;
        text-align: center;
        border-radius: 3px;
        background-color: #ccc;
      }

      .item1 {
        display: grid;
        grid-template-columns: repeat(4, 100px);
        grid-template-rows: repeat(3, 50px);
        gap: 8px 5px;
        margin-right: 5px;
      }

      @keyframes move {
        0% {
          transform: translateX(0);
        }
        100% {
          transform: translateX(-420px);
        }
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="scroll">
        <div class="item1">
          <div>1</div>
          <div>2</div>
          <div>3</div>
          <div>4</div>
          <div>5</div>
          <div>6</div>
          <div>7</div>
          <div>8</div>
          <div>9</div>
          <div>10</div>
          <div>11</div>
          <div>12</div>
        </div>
        <div class="item1">
          <div>1</div>
          <div>2</div>
          <div>3</div>
          <div>4</div>
          <div>5</div>
          <div>6</div>
          <div>7</div>
          <div>8</div>
          <div>9</div>
          <div>10</div>
          <div>11</div>
          <div>12</div>
        </div>
      </div>
    </div>
  </body>
</html>

3D卡片悬停聚焦画廊

此演示仅在桌面端浏览器中可用

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>wanglei.live</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      .box {
        display: grid;
        grid-template-columns: repeat(5, 100px);
        grid-template-rows: 130px;
        gap: 5px;
        width: 520px;
        margin: 40px auto;
      }

      .box > * {
        text-align: center;
        line-height: 130px;
        -webkit-box-reflect: below 1px
          linear-gradient(transparent, rgba(0, 0, 0, 0.3));
        transition: all 0.3s;
      }

      .box > .item:hover {
        z-index: 1;
        transform: scale(1.2);
      }

      .box:hover > .item:not(:hover) {
        transform: perspective(500px) scale(0.9) rotateY(45deg);
        margin: 0 -20px;
      }

      .box:hover > .item:hover ~ .item {
        transform: perspective(500px) scale(0.9) rotateY(-45deg);
      }

      .item:nth-child(1) {
        background-color: lightgreen;
      }
      .item:nth-child(2) {
        background-color: lightblue;
      }
      .item:nth-child(3) {
        background-color: lightcoral;
      }
      .item:nth-child(4) {
        background-color: lightgray;
      }
      .item:nth-child(5) {
        background-color: lightpink;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
      <div class="item">5</div>
    </div>
  </body>
</html>

注意事项

  1. 性能考虑: transform 和 opacity 的变化不会触发重排(relayout),性能较好
  2. 硬件加速: 3D 变换会启用 GPU 加速 transform: translateZ(0);
  3. 过渡限制: 不是所有 CSS 属性都可以过渡,如 display 属性
  4. 变换顺序: 变换函数的顺序会影响最终效果:
/* 先旋转再移动 */
transform: rotate(45deg) translateX(50px);

/* 先移动再旋转 - 效果不同 */
transform: translateX(50px) rotate(45deg);

3D 变化和透视

CSS 3D 效果通过将二维元素在三维空间中进行变换,为网页添加立体感和动态交互体验。

3D 旋转

旋转(rotate)通过改变元素在 3D 空间中的角度实现视觉效果。

语法:

transform: rotateX(45deg); /* 围绕X轴旋转45度 */
transform: rotateY(45deg); /* 围绕Y轴旋转45度 */
transform: rotateZ(45deg); /* 围绕Z轴旋转45度 */

透视

在 CSS 中,透视效果用于模拟人眼观察 3D 空间时的近大远小效果。

语法:

perspective:1000px; /* 透视效果 */
transform: perspective(1000px) rotateX(45deg); /* 同时使用多个属性 */
perspective 必须作为 transform 属性的第一个参数(否则无效)

实际应用

卡片翻转

此演示仅在桌面端浏览器中可用

<!DOCTYPE html>
<html>
  <head>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      .card {
        position: relative;
        height: 260px;
        width: 200px;
        margin: 10px auto;
        /* 添加3D透视效果 */
        perspective: 1000px;
      }

      .card > div {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        background-color: pink;
        color: black;
        font-weight: bold;
        font-size: 36px;
        text-align: center;
        line-height: 260px;
        /* 设置背面不可见 */
        backface-visibility: hidden;
        transition: all 1.7s;
        transform-style: preserve-3d;
      }

      .card .back {
        background-color: green;
        transform: rotateY(180deg);
      }

      .card:hover .front {
        transform: rotateY(-180deg);
      }

      .card:hover .back {
        transform: rotateY(0deg);
      }

      p {
        backface-visibility: hidden;
        transform: translateZ(50px);
      }
    </style>
  </head>
  <body>
    <div class="card">
      <div class="front"><p>前面</p></div>
      <div class="back"><p>背面</p></div>
    </div>
  </body>
</html>

立体翻转动效

此演示仅在桌面端浏览器中可用

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>wanglei.live</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      .box {
        display: flex;
        gap: 5px;
        width: 320px;
        margin: 10px auto;
      }

      .box > .item {
        position: relative;
        width: 100px;
        height: 50px;
        line-height: 50px;
        text-align: center;
        transform-style: preserve-3d;
        transition: all 0.3s;
      }

      .front,
      .back {
        position: absolute;
        top: 0px;
        left: 0px;
        width: 100%;
        height: 100%;
      }

      .front {
        transform: translateZ(25px);
      }

      .back {
        transform: translateY(25px) rotateX(-90deg);
      }

      .item:hover {
        transform: rotateX(90deg);
      }

      .item:nth-child(1) > .front {
        background-color: lightgreen;
      }

      .item:nth-child(1) > .back {
        background-color: green;
      }

      .item:nth-child(2) > .front {
        background-color: lightgray;
      }

      .item:nth-child(2) > .back {
        background-color: gray;
      }

      .item:nth-child(3) > .front {
        background-color: lightblue;
      }

      .item:nth-child(3) > .back {
        background-color: blue;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="item">
        <div class="front">1</div>
        <div class="back">1</div>
      </div>
      <div class="item">
        <div class="front">2</div>
        <div class="back">2</div>
      </div>
      <div class="item">
        <div class="front">3</div>
        <div class="back">3</div>
      </div>
    </div>
  </body>
</html>
#动画 #Css