一、 CSS 过渡 (Transitions)
过渡允许 CSS 属性值在一段时间内平滑地从一个状态变化到另一个状态(例如,当 :hover 或 :focus 状态激活时)。
-
transition-property
-
作用: 指定要应用过渡效果的 CSS 属性名称。
-
值:
- none: 没有属性会进行过渡。
- all: (默认值) 所有可动画的属性都将进行过渡。
- : 一个或多个 CSS 属性的名称,用逗号分隔。如 width, color, background-color, transform。
-
示例: transition-property: opacity, transform;
-
-
transition-duration
-
作用: 指定过渡效果完成所需的时间。
-
值:
-
示例: transition-duration: 0.3s;
-
-
transition-timing-function
-
作用: 指定过渡期间的速度曲线(加速度)。
-
值:
-
预定义关键字:
- ease: (默认值) 慢速开始,然后加速,最后慢速结束(类似 cubic-bezier(0.25, 0.1, 0.25, 1.0))。
- linear: 匀速过渡 (cubic-bezier(0.0, 0.0, 1.0, 1.0))。
- ease-in: 慢速开始,然后加速结束 (cubic-bezier(0.42, 0, 1.0, 1.0))。
- ease-out: 快速开始,然后减速结束 (cubic-bezier(0, 0, 0.58, 1.0))。
- ease-in-out: 慢速开始和结束,中间加速 (cubic-bezier(0.42, 0, 0.58, 1.0))。
- step-start: 等同于 steps(1, start),立即跳到结束状态。
- step-end: 等同于 steps(1, end),保持在开始状态直到时间结束,然后立即跳到结束状态。
-
函数:
- steps([, ]): 分步过渡。 是步数, 可选值为 jump-start (或 start) 或 jump-end (或 end, 默认)。如 steps(4, end)。
- cubic-bezier(, , , ): 定义自定义三次贝塞尔曲线,四个参数分别代表 P1 和 P2 控制点的 x, y 坐标。如 cubic-bezier(0.1, 0.7, 1.0, 0.1)。
-
-
示例: transition-timing-function: ease-in-out;
-
-
transition-delay
-
作用: 指定过渡效果开始前的延迟时间。
-
值:
-
示例: transition-delay: 0.1s;
-
-
transition (简写属性)
-
作用: 在一个声明中设置所有四个过渡属性。
-
语法: 可以按任意顺序列出最多四个值,对应 transition-property, transition-duration, transition-timing-function, transition-delay。
- 如果只提供一个时间值,它会被解析为 transition-duration。
- 如果提供两个时间值,第一个是 duration,第二个是 delay。
- 可以为多个属性分别设置过渡,用逗号分隔。
-
重要: 简写会重置未指定的属性为其默认值。
-
示例:
- transition: background-color 0.5s ease-out;
- transition: opacity 0.3s linear 0.1s; (属性 时长 缓动函数 延迟)
- transition: all 0.4s cubic-bezier(.17,.67,.83,.67);
- transition: width 0.2s ease-in, height 0.4s ease-out 0.1s; (两个属性的不同过渡)
-
二、 CSS 动画 (Animations)
动画允许你创建更复杂的、基于关键帧的动画序列,可以自动播放、重复,并有更多控制选项。
-
@keyframes 规则
-
作用: 定义动画的名称和关键帧(动画过程中的特定时间点及其样式)。
-
语法:
@keyframes <animation-name> { <keyframe-selector> { /* CSS 样式声明 */ } <keyframe-selector> { /* CSS 样式声明 */ } /* ... */ }
-
: 你为动画定义的名称,供 animation-name 属性引用。
-
: 定义关键帧的时间点。可以是:
- from: 等同于 0%。
- to: 等同于 100%。
- : 从 0% 到 100% 的百分比。
-
-
示例:
@keyframes slide-in { from { transform: translateX(-100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); } }
-
-
animation-name
-
作用: 指定要应用到元素的 @keyframes 动画的名称。
-
值:
- none: (默认值) 不应用任何动画。
- : 一个或多个 @keyframes 规则定义的名称,用逗号分隔。如 slide-in, pulse, fade-out。
-
示例: animation-name: pulse;
-
-
animation-duration
-
作用: 指定动画完成一个周期所需的时间。
-
值:
-
示例: animation-duration: 2s;
-
-
animation-timing-function
- 作用: 指定动画在每个周期内的速度曲线。
- 值: 与 transition-timing-function 的值相同 (ease, linear, ease-in, ease-out, ease-in-out, steps(), cubic-bezier() 等)。默认值为 ease。
- 示例: animation-timing-function: linear;
-
animation-delay
-
作用: 指定动画效果开始前的延迟时间。
-
值:
-
示例: animation-delay: 0.5s;
-
-
animation-iteration-count
-
作用: 指定动画应该播放的次数。
-
值:
- : 播放的具体次数。默认值为 1。
- infinite: 无限次重复播放。
-
示例: animation-iteration-count: infinite;
-
-
animation-direction
-
作用: 指定动画在每个周期结束后是否反向播放。
-
值:
- normal: (默认值) 每个周期都向前播放 (从 from 到 to)。
- reverse: 每个周期都反向播放 (从 to 到 from)。
- alternate: 奇数次向前播放,偶数次反向播放。
- alternate-reverse: 奇数次反向播放,偶数次向前播放。
-
示例: animation-direction: alternate;
-
-
animation-fill-mode
-
作用: 指定动画在执行之前和之后(即不在播放期间时)如何将样式应用于其目标。
-
值:
- none: (默认值) 动画结束后,元素样式返回到其原始状态。在 animation-delay 期间,应用原始样式。
- forwards: 动画结束后,元素将保持动画最后一个关键帧计算的样式。
- backwards: 在 animation-delay 期间,元素将应用动画第一个关键帧计算的样式。
- both: 同时应用 forwards 和 backwards 的规则。
-
示例: animation-fill-mode: forwards;
-
-
animation-play-state
-
作用: 指定动画是正在运行还是暂停。通常用于通过 JavaScript 控制动画。
-
值:
- running: (默认值) 动画正在播放。
- paused: 动画已暂停。
-
示例: animation-play-state: paused;
-
-
animation (简写属性)
-
作用: 在一个声明中设置一个或多个动画属性。
-
语法: 可以包含 animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode, animation-play-state 的值。顺序有一定要求(特别是时间值,duration 在前,delay 在后)。
- 可以为多个动画设置属性,用逗号分隔。
-
重要: 简写会重置未指定的属性为其默认值。
-
示例:
- animation: 3s ease-in 1s infinite reverse both paused slidein;
- animation: pulse 2s linear infinite, fadeout 1s ease-out forwards; (两个动画)
-
三、 CSS 变换 (Transforms)
变换允许你在不影响文档流的情况下,对元素进行移动、旋转、缩放或倾斜。变换通常发生在渲染过程的后期,利用 GPU 加速,性能较好,非常适合与过渡和动画结合使用。
-
transform
-
作用: 应用一个或多个 2D 或 3D 变换函数到元素。
-
值:
-
none: (默认值) 不应用任何变换。
-
+: 一个或多个变换函数,用空格分隔。顺序很重要! 变换是依次应用的。
-
2D 变换函数:
- translate([, ]): 沿 X 轴和 Y 轴移动。单位可以是 px, % (相对于自身尺寸) 等。如 translate(50px, 20%)。
- translateX(): 仅沿 X 轴移动。
- translateY(): 仅沿 Y 轴移动。
- scale([, ]): 沿 X 轴和 Y 轴缩放。1 是原始大小,1.5 是放大 50%,0.5 是缩小 50%。如 scale(1.2), scale(1, 0.8)。
- scaleX(): 仅沿 X 轴缩放。
- scaleY(): 仅沿 Y 轴缩放。
- rotate(): 在 2D 平面内旋转。单位是 deg (度), rad (弧度), grad (百分度), turn (圈)。如 rotate(45deg)。
- skew([, ]): 沿 X 轴和 Y 轴倾斜。单位是 deg, rad 等。如 skew(10deg, 5deg)。
- skewX(): 仅沿 X 轴倾斜。
- skewY(): 仅沿 Y 轴倾斜。
- matrix({6}): 使用 2x3 变换矩阵直接定义 2D 变换。
-
3D 变换函数:
- translate3d(, , ): 沿 X, Y, Z 轴移动。
- translateZ(): 沿 Z 轴移动(需要 perspective 才能看出效果)。
- scale3d(, , ): 沿 X, Y, Z 轴缩放。
- scaleZ(): 仅沿 Z 轴缩放。
- rotate3d(, , , ): 围绕一个 3D 向量 [x, y, z] 旋转指定角度。
- rotateX(): 围绕 X 轴旋转。
- rotateY(): 围绕 Y 轴旋转。
- rotateZ(): 围绕 Z 轴旋转 (效果同 rotate())。
- perspective(): 为当前元素设置透视距离(不同于父元素上的 perspective 属性)。
- matrix3d({16}): 使用 4x4 变换矩阵直接定义 3D 变换。
-
-
-
示例: transform: translateX(100px) rotate(30deg) scale(0.8);
-
-
transform-origin
-
作用: 设置变换操作(旋转、缩放、倾斜)的原点。默认是元素的中心点 (50% 50% 0)。
-
值: 可以是 1、2 或 3 个值,分别代表 X、Y、Z 轴的原点位置。
- 关键字: left, center, right, top, bottom。
- 长度/百分比: 或 。
-
示例: transform-origin: top left;, transform-origin: 50% 100%;, transform-origin: 0 0 -50px; (包含 Z 轴)
-
-
transform-style (应用于 3D 变换元素的父元素)
-
作用: 指定元素的子元素如何在 3D 空间中呈现。
-
值:
- flat: (默认值) 子元素不保留其 3D 位置,会被扁平化到父元素的平面。
- preserve-3d: 子元素保留其 3D 位置。创建嵌套的 3D 场景时必须设置。
-
示例: transform-style: preserve-3d;
-
-
perspective (应用于 3D 变换元素的父元素)
-
作用: 为其 3D 定位的子元素设置透视效果的强度。它定义了观察者与 Z=0 平面之间的距离。
-
值:
- none: (默认值) 无透视效果。
- : 一个正长度值,表示距离。值越小,透视效果越强烈(失真越大)。如 800px, 1000px。
-
示例: perspective: 1000px;
-
-
perspective-origin (应用于 3D 变换元素的父元素)
- 作用: 设置 perspective 属性的消失点 (vanishing point) 的位置。默认是父元素的中心 (50% 50%)。
- 值: 与 transform-origin 的 X, Y 值语法相同(关键字、长度、百分比)。
- 示例: perspective-origin: top right;, perspective-origin: 50% 0;
-
backface-visibility
-
作用: 定义当元素的背面面向观察者时是否可见。
-
值:
- visible: (默认值) 背面可见(通常是正面的镜像)。
- hidden: 背面不可见(元素变为透明)。
-
示例: backface-visibility: hidden; (常用于创建翻转卡片效果)
-
-
transform-box (较新属性)
-
作用: 定义 transform 和 transform-origin 属性所参照的布局框。主要用于 SVG 元素。
-
值:
- content-box: (HTML 默认,但不适用于 SVG)
- border-box: (HTML 默认)
- fill-box: 使用对象的填充框 (SVG 常用)。
- stroke-box: 使用对象的描边框 (SVG 常用)。
- view-box: 使用最近的 SVG 视口 (SVG 常用,通常是默认值)。
-
示例: transform-box: fill-box;
-
案例 1 transitions
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS 过渡 (Transitions) 示例</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>CSS 过渡 (Transitions) 演示</h1>
<div class="container">
<h2>鼠标悬停看效果</h2>
<!-- 示例 1: 基本过渡 -->
<button class="btn btn-basic">基础过渡</button>
<p>悬停时,背景色和文字颜色平滑过渡。</p>
<!-- 示例 2: 过渡多个属性,不同时长和延迟 -->
<button class="btn btn-multi">多属性过渡</button>
<p>悬停时,背景色快速过渡,大小(通过 transform: scale)稍慢过渡并有延迟。</p>
<!-- 示例 3: 使用不同的 timing-function -->
<button class="btn btn-timing ease-in">Ease-In</button>
<button class="btn btn-timing linear">Linear</button>
<button class="btn btn-timing ease-out">Ease-Out</button>
<button class="btn btn-timing cubic">Cubic Bezier</button>
<p>悬停时,观察不同速度曲线的效果 (translateX)。</p>
<!-- 示例 4: 分步过渡 (Steps) -->
<button class="btn btn-steps">分步过渡</button>
<p>悬停时,背景色分 4 步变化。</p>
</div>
</body>
</html>
body {
font-family: sans-serif;
padding: 20px;
background-color: #f0f0f0;
text-align: center; /* 让按钮居中显示 */
}
h1 {
color: #333;
margin-bottom: 30px;
}
h2 {
color: #555;
margin-bottom: 20px;
}
.container {
background-color: #fff;
padding: 30px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
margin-bottom: 30px;
}
.container p {
color: #666;
margin-top: 15px;
font-size: 0.9em;
}
/* 按钮基础样式 */
.btn {
display: inline-block; /* 使按钮可以并排,且能设置宽高 */
padding: 12px 25px;
margin: 10px;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
outline: none; /* 移除默认的点击轮廓 */
color: white; /* 默认文字颜色 */
background-color: steelblue; /* 默认背景色 */
}
/* --- 示例 1: 基本过渡 --- */
.btn-basic {
/* 定义要过渡的属性:背景色和文字颜色 */
transition-property: background-color, color;
/* 定义过渡的持续时间 */
transition-duration: 0.4s; /* 400毫秒 */
/* 定义过渡的速度曲线 (可选,默认是 ease) */
/* transition-timing-function: ease; */
/* 定义过渡的延迟 (可选,默认是 0s) */
/* transition-delay: 0s; */
/* 上面分开写的属性可以用简写代替: */
/* transition: background-color 0.4s ease, color 0.4s ease; */
/* 或者如果所有属性都用相同设置,可以更简洁: */
/* transition: all 0.4s ease; */
}
/* 鼠标悬停时的状态 */
.btn-basic:hover {
background-color: tomato; /* 目标背景色 */
color: black; /* 目标文字颜色 */
}
/* --- 示例 2: 过渡多个属性,不同时长和延迟 --- */
.btn-multi {
/* 为 background-color 和 transform 分别设置过渡 */
transition: background-color 0.2s ease-out, /* 背景色:0.2秒,快速开始 */
transform 0.5s ease-in-out 0.1s; /* 大小:0.5秒,缓入缓出,延迟0.1秒开始 */
transform-origin: center; /* 确保缩放从中心开始 */
}
.btn-multi:hover {
background-color: darkslateblue;
transform: scale(1.1); /* 放大 10% */
}
/* --- 示例 3: 使用不同的 timing-function --- */
.btn-timing {
background-color: mediumseagreen;
transition-property: transform; /* 只过渡 transform 属性 */
transition-duration: 0.8s; /* 持续时间 */
}
.btn-timing:hover {
transform: translateX(100px); /* 向右移动 100px */
}
/* 分别设置不同的 timing-function */
.btn-timing.ease-in {
transition-timing-function: ease-in;
}
.btn-timing.linear {
transition-timing-function: linear;
}
.btn-timing.ease-out {
transition-timing-function: ease-out;
}
.btn-timing.cubic {
/* 自定义贝塞尔曲线 */
transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55); /* 类似回弹效果 */
}
/* --- 示例 4: 分步过渡 (Steps) --- */
.btn-steps {
background-color: orange;
transition-property: background-color;
transition-duration: 1s; /* 总时长 1 秒 */
transition-timing-function: steps(4, end); /* 分成 4 步,在每步结束时跳变 */
/* 试试 steps(4, start) 看看区别 */
}
.btn-steps:hover {
background-color: purple;
}
案例 2 animations
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS 动画 (Animations) 示例</title>
<link rel="stylesheet" href="1.css">
</head>
<body>
<h1>CSS 动画 (Animations) 演示</h1>
<div class="animation-container">
<!-- 示例 1: 基本动画 (名称、时长) -->
<div class="box box-basic">基础动画</div>
<p>一个简单的从左侧滑入的动画,只播放一次。</p>
<!-- 示例 2: 无限循环与速度曲线 (iteration-count, timing-function) -->
<div class="box box-looping">无限循环 (linear)</div>
<p>一个无限循环的脉冲效果,使用线性速度曲线。</p>
<!-- 示例 3: 交替方向与填充模式 (direction, fill-mode) -->
<div class="box box-direction-fill">交替变色 (forwards)</div>
<p>背景色在红蓝之间来回交替变化,动画结束后保持在最终状态。</p>
<!-- 示例 4: 延迟与播放次数 (delay, iteration-count) -->
<div class="box box-delay-count">延迟播放 3 次</div>
<p>动画延迟 1 秒后开始,并播放 3 次后停止。</p>
<!-- 示例 5: 暂停动画 (play-state) -->
<div class="box box-play-state">悬停暂停旋转</div>
<p>一个无限旋转的动画,鼠标悬停时会暂停。</p>
<!-- 示例 6: animation 简写属性 -->
<div class="box box-shorthand">简写属性</div>
<p>使用 `animation` 简写属性设置所有动画参数。</p>
<!-- 示例 7: 应用多个动画 -->
<div class="box box-multiple">多重动画</div>
<p>同时应用滑动和缩放两种动画。</p>
</div>
</body>
</html>
body {
font-family: sans-serif;
padding: 20px;
background-color: #f4f4f4;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 40px;
}
p {
color: #666;
font-size: 0.9em;
text-align: center;
margin-top: 5px;
margin-bottom: 30px; /* 增加示例间距 */
}
.animation-container {
display: flex;
flex-direction: column; /* 垂直排列示例 */
align-items: center; /* 水平居中 */
}
/* 方块基础样式 */
.box {
width: 100px;
height: 100px;
background-color: steelblue;
color: white;
display: flex;
justify-content: center;
align-items: center;
border-radius: 5px;
margin-bottom: 10px; /* 方块和文字的间距 */
font-size: 0.9em;
text-align: center;
}
/* --- 定义关键帧动画 --- */
/* 动画 1: 从左滑入 */
@keyframes slide-in {
from { /* 或者 0% */
transform: translateX(-200px);
opacity: 0;
}
to { /* 或者 100% */
transform: translateX(0);
opacity: 1;
}
}
/* 动画 2: 脉冲(放大缩小) */
@keyframes pulse {
0% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(0, 123, 255, 0.4);
}
70% {
transform: scale(1.1);
box-shadow: 0 0 10px 20px rgba(0, 123, 255, 0);
}
100% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(0, 123, 255, 0);
}
}
/* 动画 3: 背景色变化 */
@keyframes color-change {
0% { background-color: tomato; }
100% { background-color: mediumpurple; }
}
/* 动画 4: 旋转 */
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* 动画 5: 弹跳(用于多重动画) */
@keyframes bounce-y {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
/* --- 应用动画属性 --- */
/* 示例 1: 基本动画 */
.box-basic {
animation-name: slide-in; /* 使用哪个 @keyframes 动画 */
animation-duration: 0.8s; /* 动画时长 0.8 秒 */
/* 其他属性使用默认值:
animation-timing-function: ease;
animation-delay: 0s;
animation-iteration-count: 1;
animation-direction: normal;
animation-fill-mode: none;
animation-play-state: running;
*/
animation-fill-mode: backwards; /* 演示:动画开始前就应用第一帧状态 */
}
/* 示例 2: 无限循环与速度曲线 */
.box-looping {
animation-name: pulse;
animation-duration: 1.5s;
animation-timing-function: linear; /* 匀速变化 */
animation-iteration-count: infinite; /* 无限循环 */
}
/* 示例 3: 交替方向与填充模式 */
.box-direction-fill {
animation-name: color-change;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate; /* 方向:正常 -> 反向 -> 正常 ... */
animation-fill-mode: forwards; /* 填充模式:动画结束后保持最后一帧状态 (虽然无限循环看不出来,但如果次数有限就可以) */
/* 如果 iteration-count 不是 infinite,可以看到 forwards 的效果 */
/* animation-iteration-count: 2; */
}
/* 示例 4: 延迟与播放次数 */
.box-delay-count {
animation-name: slide-in;
animation-duration: 0.6s;
animation-delay: 1s; /* 延迟 1 秒开始 */
animation-iteration-count: 3; /* 播放 3 次 */
animation-timing-function: ease-in-out;
}
/* 示例 5: 暂停动画 */
.box-play-state {
animation-name: spin;
animation-duration: 3s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-play-state: running; /* 初始状态:播放 */
}
.box-play-state:hover {
animation-play-state: paused; /* 鼠标悬停时:暂停 */
}
/* 示例 6: animation 简写属性 */
.box-shorthand {
/* animation: name duration timing-function delay iteration-count direction fill-mode play-state; */
/* 只需提供必要的值,其他会使用默认值 */
animation: color-change 2s ease-in-out 0.5s 4 alternate forwards;
/* 对应:名称 时长 速度曲线 延迟 次数 方向 填充模式 */
}
/* 示例 7: 应用多个动画 */
.box-multiple {
/* 用逗号分隔多个动画设置 */
animation: bounce-y 1.5s ease-in-out infinite, /* 第一个动画:上下弹跳 */
spin 4s linear infinite reverse; /* 第二个动画:反向旋转 */
}
案例 3 transforms
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS Transforms 示例</title>
<link rel="stylesheet" href="11.css">
</head>
<body>
<h1>CSS Transforms 演示</h1>
<div class="container">
<h2>2D 变换 (2D Transforms)</h2>
<div class="box-container">
<div class="box box-translate">Translate</div>
<p>向右下移动 (translate)</p>
</div>
<div class="box-container">
<div class="box box-rotate">Rotate</div>
<p>旋转 45 度 (rotate)</p>
</div>
<div class="box-container">
<div class="box box-scale">Scale</div>
<p>放大 1.2 倍 (scale)</p>
</div>
<div class="box-container">
<div class="box box-skew">Skew</div>
<p>沿 X 轴倾斜 (skewX)</p>
</div>
<div class="box-container">
<div class="box box-matrix">Matrix</div>
<p>使用 matrix 应用变换</p>
</div>
<div class="box-container">
<div class="box box-origin">Origin</div>
<p>改变变换原点后旋转 (transform-origin: top left)</p>
</div>
<div class="box-container">
<div class="box box-combo">Combo 2D</div>
<p>组合变换: 移动、旋转、缩放</p>
</div>
</div>
<div class="container perspective-container">
<h2>3D 变换 (3D Transforms)</h2>
<p>注意:需要父容器设置 `perspective` 才能看到 Z 轴效果。</p>
<div class="box-container">
<div class="box box-rotateX">Rotate X</div>
<p>绕 X 轴旋转 (rotateX)</p>
</div>
<div class="box-container">
<div class="box box-rotateY">Rotate Y</div>
<p>绕 Y 轴旋转 (rotateY)</p>
</div>
<div class="box-container">
<div class="box box-translateZ">Translate Z</div>
<p>沿 Z 轴移动 (靠近/远离) (translateZ)</p>
</div>
<div class="box-container card-container">
<div class="box card">
<div class="card-face card-front">Front</div>
<div class="card-face card-back">Back</div>
</div>
<p>3D 翻转卡片 (rotateY + backface-visibility)</p>
</div>
<div class="box-container preserve-3d-container">
<div class="box parent-3d">
Parent (preserve-3d)
<div class="box child-3d">Child (rotateY)</div>
</div>
<p>嵌套 3D 变换 (transform-style: preserve-3d)</p>
</div>
</div>
</body>
</html>
body {
font-family: sans-serif;
padding: 20px;
background-color: #f9f9f9;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 30px;
}
h2 {
color: steelblue;
margin-top: 30px;
margin-bottom: 20px;
border-bottom: 1px solid #ccc;
padding-bottom: 5px;
}
.container {
background-color: #fff;
padding: 20px;
margin-bottom: 30px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.box-container {
display: inline-block; /* 让容器并排显示 */
margin: 20px;
text-align: center;
vertical-align: top; /* 顶部对齐 */
width: 150px; /* 给容器一个宽度 */
}
.box-container p {
font-size: 0.85em;
color: #555;
margin-top: 10px;
}
/* 方块基础样式 */
.box {
width: 100px;
height: 100px;
background-color: lightcoral;
color: white;
display: flex; /* 使用 flex 居中文本 */
justify-content: center;
align-items: center;
margin: 0 auto; /* 在容器内水平居中 */
border-radius: 5px;
transition: transform 0.4s ease-in-out; /* 为所有变换添加过渡效果 */
}
/* 应用变换效果 (通常在 :hover 或类切换时应用) */
/* 为了演示方便,我们直接应用在默认状态 */
/* --- 2D Transforms --- */
.box-translate {
/* 向右移动 30px, 向下移动 20px */
transform: translate(30px, 20px);
}
.box-rotate {
/* 顺时针旋转 45 度 */
transform: rotate(45deg);
}
.box-scale {
/* 宽度放大 1.2 倍, 高度缩小到 0.8 倍 */
transform: scale(1.2, 0.8);
}
.box-skew {
/* 仅沿 X 轴倾斜 20 度 */
transform: skewX(20deg);
/* 试试 skew(10deg, 5deg) */
}
.box-matrix {
/* 使用 matrix 实现: scale(1.1) rotate(10deg) translate(10px, 5px) */
/* matrix(scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY()) */
transform: matrix(1.083, 0.191, -0.191, 1.083, 10, 5); /* 结果是复合效果 */
}
.box-origin {
transform-origin: top left; /* 将变换原点设置到左上角 */
transform: rotate(30deg); /* 现在绕左上角旋转 */
}
.box-combo {
/* 组合多个变换函数,注意顺序! */
transform: translateX(20px) rotate(-15deg) scale(0.9);
}
/* --- 3D Transforms --- */
/* 给 3D 变换的父容器设置透视 */
.perspective-container {
perspective: 800px; /* 设置观察者距离 */
/* perspective-origin: top right; */ /* 可以改变观察点 */
background-color: #eef; /* 换个背景色区分 */
}
.box-rotateX {
/* 绕 X 轴旋转 60 度 */
transform: rotateX(60deg);
}
.box-rotateY {
/* 绕 Y 轴旋转 60 度 */
transform: rotateY(60deg);
}
.box-translateZ {
/* 沿 Z 轴移动 50px (看起来变大了,靠近观察者) */
transform: translateZ(50px);
/* 试试 transform: translateZ(-50px); (看起来变小,远离观察者) */
}
/* 3D 卡片效果 */
.card-container {
position: relative; /* 为绝对定位的背面提供容器 */
width: 100px; /* 调整容器尺寸以匹配卡片 */
height: 100px;
margin: 20px auto;
}
.card {
width: 100%;
height: 100%;
position: absolute; /* 让正反面重叠 */
transform-style: preserve-3d; /* 关键:启用 3D 空间 */
transition: transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275); /* 加个过渡 */
cursor: pointer;
}
.card-face {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden; /* 关键:隐藏背面 */
display: flex;
justify-content: center;
align-items: center;
border-radius: 5px;
font-weight: bold;
}
.card-front {
background-color: dodgerblue;
color: white;
}
.card-back {
background-color: gold;
color: #333;
transform: rotateY(180deg); /* 关键:将背面翻转 180 度 */
}
/* 悬停时翻转卡片 */
.card-container:hover .card {
transform: rotateY(180deg);
}
/* 嵌套 3D 变换 */
.preserve-3d-container {
padding-top: 30px; /* 给点空间 */
}
.parent-3d {
width: 120px;
height: 120px;
background-color: rgba(0, 128, 0, 0.7); /* 半透明绿色 */
position: relative; /* 用于定位子元素 */
transform-style: preserve-3d; /* 关键:允许子元素在 3D 空间 */
transform: rotateX(30deg); /* 父元素也旋转一下 */
}
.child-3d {
width: 80px;
height: 80px;
background-color: rgba(255, 0, 0, 0.7); /* 半透明红色 */
position: absolute;
top: 20px;
left: 20px;
transform: rotateY(45deg) translateZ(30px); /* 子元素在 3D 空间旋转并移出 */
}