变换与过渡
2025年3月2日大约 9 分钟
CSS变换与过渡
概述
CSS 变换与过渡是现代网页设计中创建动态视觉效果的重要技术。本文将详细介绍 CSS 变换(Transform)和过渡(Transition)的相关知识,包括基本概念、实际应用以及最佳实践,帮助您创建流畅、自然的网页动效。
目录
基本概念
变换(Transform)
CSS 变换允许您以非破坏性的方式改变元素的形状、大小和位置,而不影响文档流。变换不会改变元素的盒模型或周围元素的布局。
过渡(Transition)
CSS 过渡使元素的属性值能够平滑地从一个状态变化到另一个状态,创建动画效果。过渡定义了变化的持续时间、时间函数和延迟。
变换原点
变换原点是应用变换效果的参考点,默认为元素的中心点。可以通过 transform-origin
属性修改。
CSS 变换
2D 变换
平移(Translate)
.translate-example {
/* 水平和垂直平移 */
transform: translate(50px, 30px);
/* 单独平移 */
transform: translateX(50px);
transform: translateY(30px);
}
旋转(Rotate)
.rotate-example {
/* 顺时针旋转45度 */
transform: rotate(45deg);
/* 逆时针旋转 */
transform: rotate(-45deg);
}
缩放(Scale)
.scale-example {
/* 等比例缩放 */
transform: scale(1.5);
/* 分别设置水平和垂直缩放 */
transform: scale(1.5, 0.8);
/* 单独缩放 */
transform: scaleX(1.5);
transform: scaleY(0.8);
}
倾斜(Skew)
.skew-example {
/* X轴和Y轴倾斜 */
transform: skew(15deg, 10deg);
/* 单独倾斜 */
transform: skewX(15deg);
transform: skewY(10deg);
}
组合变换
.combined-transform {
/* 多个变换组合(从右到左应用) */
transform: translate(50px, 30px) rotate(45deg) scale(1.5);
}
3D 变换
3D 平移
.translate3d-example {
/* 三维平移 */
transform: translate3d(50px, 30px, 100px);
/* Z轴平移 */
transform: translateZ(100px);
}
3D 旋转
.rotate3d-example {
/* 绕X轴旋转 */
transform: rotateX(45deg);
/* 绕Y轴旋转 */
transform: rotateY(45deg);
/* 绕Z轴旋转(等同于2D旋转) */
transform: rotateZ(45deg);
/* 绕自定义轴旋转 */
transform: rotate3d(1, 1, 1, 45deg);
}
3D 透视
.perspective-example {
/* 父元素设置透视 */
perspective: 1000px;
}
.child {
/* 子元素应用3D变换 */
transform: rotateY(45deg);
}
变换原点
.transform-origin-example {
/* 设置变换原点 */
transform-origin: left top;
transform-origin: 0 0;
/* 3D变换原点 */
transform-origin: center center 50px;
}
CSS 过渡
基本语法
.transition-example {
/* 单个属性过渡 */
transition-property: opacity;
transition-duration: 0.3s;
transition-timing-function: ease-in-out;
transition-delay: 0.1s;
/* 简写形式 */
transition: opacity 0.3s ease-in-out 0.1s;
/* 多个属性过渡 */
transition:
opacity 0.3s ease-in-out,
transform 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55);
}
过渡属性
.transition-property-example {
/* 指定属性 */
transition-property: opacity, transform;
/* 所有可动画属性 */
transition-property: all;
/* 不进行过渡 */
transition-property: none;
}
过渡持续时间
.transition-duration-example {
/* 单一持续时间 */
transition-duration: 0.5s;
transition-duration: 500ms;
/* 多个持续时间 */
transition-duration: 0.5s, 1s;
}
过渡时间函数
.transition-timing-function-example {
/* 预定义函数 */
transition-timing-function: ease;
transition-timing-function: ease-in;
transition-timing-function: ease-out;
transition-timing-function: ease-in-out;
transition-timing-function: linear;
/* 贝塞尔曲线 */
transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);
/* 阶跃函数 */
transition-timing-function: steps(5, end);
}
过渡延迟
.transition-delay-example {
/* 单一延迟 */
transition-delay: 0.2s;
transition-delay: 200ms;
/* 多个延迟 */
transition-delay: 0.2s, 0.5s;
}
实际应用
1. 悬停效果
.hover-card {
padding: 20px;
background-color: #f8f9fa;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
&:hover {
transform: translateY(-5px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
}
}
2. 按钮动效
.animated-button {
padding: 12px 24px;
background-color: #3498db;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s, transform 0.2s, box-shadow 0.3s;
&:hover {
background-color: #2980b9;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
&:active {
transform: translateY(0);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
}
3. 导航菜单
.nav-menu {
display: flex;
list-style: none;
padding: 0;
margin: 0;
.nav-item {
position: relative;
a {
display: block;
padding: 10px 20px;
color: #333;
text-decoration: none;
transition: color 0.3s;
&:hover {
color: #3498db;
}
}
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 2px;
background-color: #3498db;
transition: width 0.3s ease, left 0.3s ease;
}
&:hover::after {
width: 100%;
left: 0;
}
}
}
4. 折叠面板
.accordion {
.accordion-header {
padding: 15px;
background-color: #f8f9fa;
cursor: pointer;
transition: background-color 0.3s;
&:hover {
background-color: #e9ecef;
}
}
.accordion-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.5s ease;
}
&.active .accordion-content {
max-height: 500px; /* 足够大的值 */
}
}
高级技巧
1. 3D 卡片翻转
.flip-card {
perspective: 1000px;
width: 300px;
height: 200px;
.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.6s;
transform-style: preserve-3d;
}
&:hover .flip-card-inner {
transform: rotateY(180deg);
}
.flip-card-front,
.flip-card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
border-radius: 8px;
overflow: hidden;
}
.flip-card-front {
background-color: #f8f9fa;
}
.flip-card-back {
background-color: #3498db;
color: white;
transform: rotateY(180deg);
}
}
2. 视差效果
.parallax-container {
perspective: 1px;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
.parallax-layer {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
&.back {
transform: translateZ(-1px) scale(2);
}
&.middle {
transform: translateZ(-0.5px) scale(1.5);
}
&.front {
transform: translateZ(0);
}
}
}
3. 自定义动画曲线
.custom-easing {
/* 弹跳效果 */
transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);
/* 回弹效果 */
transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1.5);
/* 缓入急出 */
transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1.5);
}
4. 变换组合与链式动画
.sequential-animation {
.item {
opacity: 0;
transform: translateY(20px);
transition: opacity 0.3s ease, transform 0.3s ease;
&:nth-child(1) { transition-delay: 0.1s; }
&:nth-child(2) { transition-delay: 0.2s; }
&:nth-child(3) { transition-delay: 0.3s; }
&:nth-child(4) { transition-delay: 0.4s; }
}
&:hover .item {
opacity: 1;
transform: translateY(0);
}
}
浏览器兼容性
特性支持
特性 | Chrome | Firefox | Safari | Edge |
---|---|---|---|---|
2D 变换 | 36+ | 16+ | 9+ | 12+ |
3D 变换 | 36+ | 16+ | 9+ | 12+ |
CSS 过渡 | 26+ | 16+ | 9+ | 12+ |
兼容性处理
/* 添加浏览器前缀 */
.cross-browser {
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-ms-transition: all 0.3s ease;
transition: all 0.3s ease;
}
/* 使用 @supports 检测 */
@supports (transform: rotate(45deg)) {
.transform-supported {
transform: rotate(45deg);
}
}
最佳实践
1. 性能优化
/* 优化变换性能 */
.performance-optimized {
/* 使用 will-change 提示浏览器 */
will-change: transform, opacity;
/* 使用硬件加速 */
transform: translateZ(0);
/* 只过渡必要的属性 */
transition-property: transform, opacity;
/* 避免过渡 all */
/* 不推荐: transition: all 0.3s; */
}
2. 可访问性考虑
/* 尊重用户偏好 */
@media (prefers-reduced-motion: reduce) {
* {
transition-duration: 0.01s !important;
animation-duration: 0.01s !important;
animation-iteration-count: 1 !important;
scroll-behavior: auto !important;
}
}
3. 维护性与可读性
/* 使用 CSS 变量管理过渡 */
:root {
/* 过渡时间 */
--transition-fast: 0.2s;
--transition-normal: 0.3s;
--transition-slow: 0.5s;
/* 过渡曲线 */
--ease-standard: ease;
--ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
--ease-in-out-smooth: cubic-bezier(0.645, 0.045, 0.355, 1);
}
.maintainable {
transition:
transform var(--transition-normal) var(--ease-out-back),
opacity var(--transition-fast) var(--ease-standard);
}
4. 避免常见陷阱
/* 避免过渡高消耗属性 */
.avoid-expensive {
/* 不推荐 */
/* transition: box-shadow 0.3s, filter 0.3s; */
/* 推荐:使用 opacity 和 transform */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition: transform 0.3s, opacity 0.3s;
&:hover {
transform: translateY(-2px);
opacity: 0.9;
}
}
/* 避免过渡 height/width 到 auto */
.height-transition {
/* 不推荐 */
/* height: 0;
transition: height 0.3s;
&:hover { height: auto; } */
/* 推荐:使用 max-height */
max-height: 0;
transition: max-height 0.3s ease;
&:hover {
max-height: 200px; /* 足够大的值 */
}
}
实际案例分析
案例 1:交互式导航栏
<nav class="main-nav">
<div class="logo">Logo</div>
<ul class="nav-links">
<li><a href="#" class="active">首页</a></li>
<li><a href="#">关于</a></li>
<li><a href="#">服务</a></li>
<li><a href="#">联系</a></li>
</ul>
<button class="mobile-toggle">
<span></span>
<span></span>
<span></span>
</button>
</nav>
.main-nav {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 2rem;
background-color: white;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.logo {
font-size: 1.5rem;
font-weight: bold;
}
.nav-links {
display: flex;
list-style: none;
margin: 0;
padding: 0;
li {
margin: 0 1rem;
}
a {
position: relative;
color: #333;
text-decoration: none;
padding: 0.5rem 0;
transition: color 0.3s;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background-color: #3498db;
transition: width 0.3s ease;
}
&:hover, &.active {
color: #3498db;
&::after {
width: 100%;
}
}
}
}
.mobile-toggle {
display: none;
background: none;
border: none;
cursor: pointer;
padding: 0.5rem;
span {
display: block;
width: 25px;
height: 3px;
background-color: #333;
margin: 5px 0;
transition: transform 0.3s, opacity 0.3s;
}
}
@media (max-width: 768px) {
.nav-links {
position: absolute;
top: 70px;
left: 0;
right: 0;
flex-direction: column;
background-color: white;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
transform: translateY(-100%);
opacity: 0;
transition: transform 0.3s ease, opacity 0.3s ease;
z-index: 10;
li {
margin: 0;
a {
display: block;
padding: 1rem 2rem;
}
}
}
.mobile-toggle {
display: block;
}
.nav-open {
.nav-links {
transform: translateY(0);
opacity: 1;
}
.mobile-toggle {
span:nth-child(1) {
transform: translateY(8px) rotate(45deg);
}
span:nth-child(2) {
opacity: 0;
}
span:nth-child(3) {
transform: translateY(-8px) rotate(-45deg);
}
}
}
}
案例 2:图片画廊
<div class="gallery">
<div class="gallery-item">
<img src="image1.jpg" alt="图片描述">
<div class="overlay">
<h3>标题 1</h3>
<p>描述文本</p>
</div>
</div>
<!-- 更多 gallery-item -->
</div>
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-gap: 20px;
}
.gallery-item {
position: relative;
overflow: hidden;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s ease;
}
.overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
padding: 20px;
color: white;
transform: translateY(100%);
transition: transform 0.3s ease;
h3 {
margin: 0 0 10px;
transform: translateY(20px);
opacity: 0;
transition: transform 0.3s ease 0.1s, opacity 0.3s ease 0.1s;
}
p {
margin: 0;
transform: translateY(20px);
opacity: 0;
transition: transform 0.3s ease 0.2s, opacity 0.3s ease 0.2s;
}
}
&:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
img {
transform: scale(1.1);
}
.overlay {
transform: translateY(0);
h3, p {
transform: translateY(0);
opacity: 1;
}
}
}
}
参考资源
- MDN Web Docs: CSS 变换
- MDN Web Docs: CSS 过渡
- CSS-Tricks: 变换与过渡指南
- W3C CSS 变换规范
- W3C CSS 过渡规范
- Cubic Bezier 可视化工具
- Can I Use: CSS 变换与过渡支持情况
总结
CSS 变换与过渡是创建现代、动态网页体验的强大工具。通过变换,我们可以以非破坏性的方式改变元素的形状、大小和位置;通过过渡,我们可以使这些变化平滑自然地发生。
关键要点:
- 变换不影响文档流:变换操作不会改变元素的盒模型或周围元素的布局
- 过渡创建平滑动画:过渡定义了属性如何从一个状态变化到另一个状态
- 性能优化很重要:优先使用 transform 和 opacity 进行动画,避免高消耗属性
- 考虑可访问性:尊重用户的减少动画偏好设置
- 组合使用创建复杂效果:通过组合不同的变换和过渡可以创建丰富的交互体验
通过掌握这些技术,您可以创建出既美观又高效的网页动效,提升用户体验和界面交互。