前言
本文将带你使用纯 CSS 和少量 JavaScript 实现一个流行的扩展卡片效果,探索 Flexbox 布局和 CSS 过渡动画的强大能力。
效果预览
这是一个优雅的图片展示组件,包含多个卡片面板。当用户点击某个面板时,该面板会平滑扩展并显示标题,其他面板则相应收缩。这种交互方式不仅美观,还能有效吸引用户的注意力。
HTML 结构设计
首先,我们来看 HTML 结构的设计:
html
<div class="container">
<div class="panel" style="background-image: url('image1.jpg')">
<h3>Explore The World</h3>
</div>
<div class="panel" style="background-image: url('image2.jpg')">
<h3>Wild Forest</h3>
</div>
<!-- 更多面板... -->
</div>
设计思路:
- 使用容器包裹所有面板,便于整体布局控制
- 每个面板通过内联样式设置背景图片,保持灵活性
- 标题使用
<h3>标签,语义化且样式可控 - 结构简洁,便于维护和扩展
CSS 核心技术解析
1. 基础重置与整体布局
css
* {
margin: 0;
padding: 0;
}
body {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 100vh;
overflow: hidden;
}
关键技术点:
- 通配符重置消除浏览器默认样式差异
display: flex让 body 成为弹性容器,便于居中布局height: 100vh确保布局充满整个视口高度overflow: hidden防止滚动条出现
2. 弹性容器设置
css
.container {
display: flex;
width: 90vw;
}
这里将容器设置为 Flex 布局,width: 90vw 让容器宽度为视口宽度的 90%,留出适当的边距。
3. 面板基础样式
css
.panel {
height: 80vh;
border-radius: 50px;
color: #fff;
cursor: pointer;
flex: 0.5;
margin: 10px;
position: relative;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
transition: all 700ms ease-in;
}
样式解析:
height: 80vh- 相对视口高度,保持响应式border-radius: 50px- 圆角设计,现代感强flex: 0.5- 初始状态下每个面板占据较小空间position: relative- 为绝对定位的标题做准备- 背景相关属性确保图片完美显示
transition: all 700ms ease-in- 平滑的过渡动画
4. 标题样式与动画
css
.panel h3 {
font-size: 24px;
position: absolute;
left: 20px;
bottom: 20px;
margin: 0;
opacity: 0;
transition: opacity 300ms ease-in 400ms;
}
动画设计:
opacity: 0: 初始状态隐藏- 独立的过渡动画:
opacity 300ms ease-in 400ms - 400ms 延迟让面板扩展完成后再显示文字
5. 激活状态样式
css
.panel.active {
flex: 5;
}
.panel.active h3 {
opacity: 1;
}
激活状态时:
flex: 5:面板扩展占据更多空间opacity: 1: 标题透明度变为1,平滑显示
6. 响应式设计
css
@media (max-width: 480px) {
.container {
width: 100vw;
}
.panel:nth-of-type(4),
.panel:nth-of-type(5) {
display: none;
}
}
移动端适配:
- 小屏幕下隐藏最后两个面板,保持可用性
- 容器宽度调整为 100%,充分利用空间
JavaScript 交互逻辑
javascript
const panels = document.querySelectorAll(".panel");
panels.forEach(function(panel) {
panel.addEventListener("click", function() {
panel.classList.toggle("active");
})
})
交互逻辑:
- 使用事件委托模式,为每个面板添加点击监听
classList.toggle()方法智能切换 active 类- 简洁高效,易于理解和维护
CSS Transition 属性深度解析
在这个项目中,我们大量使用了 CSS transition 属性来创建平滑的动画效果。让我们深入了解这个强大的特性:
transition 属性完整语法
css
transition: property duration timing-function delay;
属性分解说明:
-
transition-property - 指定要过渡的 CSS 属性
csstransition-property: all; /* 所有可过渡属性 */ transition-property: opacity; /* 仅透明度 */ transition-property: transform, opacity; /* 多个属性 */ -
transition-duration - 过渡持续时间
csstransition-duration: 700ms; /* 700毫秒 */ transition-duration: 1s; /* 1秒 */ transition-duration: 0.5s; /* 0.5秒 */ -
transition-timing-function - 时间函数(动画速度曲线)
csstransition-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.1, 0.7, 1.0, 0.1); /* 贝塞尔曲线 */ -
transition-delay - 过渡延迟时间
csstransition-delay: 400ms; /* 400毫秒后开始 */ transition-delay: 0s; /* 立即开始(默认) */ transition-delay: 1s; /* 1秒后开始 */
项目中使用的过渡效果
css
/* 面板的主要过渡 */
.panel {
transition: all 700ms ease-in;
/* 等价于: */
transition-property: all;
transition-duration: 700ms;
transition-timing-function: ease-in;
transition-delay: 0s;
}
/* 标题的延迟过渡 */
.panel h3 {
transition: opacity 300ms ease-in 400ms;
/* 等价于: */
transition-property: opacity;
transition-duration: 300ms;
transition-timing-function: ease-in;
transition-delay: 400ms;
}
时间函数详解
时间函数控制动画的速度曲线,对动画的"感觉"至关重要:
-
ease-in - 慢开始,逐渐加速(项目中使用的)
csstransition-timing-function: ease-in;适合元素进入场景的动画
-
ease-out - 快速开始,慢结束
csstransition-timing-function: ease-out;适合元素离开场景的动画
-
ease-in-out - 慢开始和慢结束
csstransition-timing-function: ease-in-out;适合需要平滑变化的动画
-
linear - 匀速运动
csstransition-timing-function: linear;机械感强,适合进度条等
-
cubic-bezier - 自定义贝塞尔曲线
csstransition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);创建弹性、反弹等特殊效果
可过渡的 CSS 属性
并非所有 CSS 属性都可以应用过渡效果,常见的可过渡属性包括:
- 尺寸相关:width, height, flex-grow, flex-shrink
- 位置相关:margin, padding, top, left, right, bottom
- 颜色相关:color, background-color, border-color
- 视觉效果:opacity, visibility, box-shadow
- 变换相关:transform 的所有函数
多重过渡
一个元素可以同时应用多个不同的过渡效果:
css
.element {
transition:
opacity 300ms ease-in,
transform 500ms ease-out 100ms,
background-color 200ms linear;
}
弹性布局(Flexbox)深度解析
什么是弹性布局?
Flexbox(弹性盒子布局)是 CSS3 中一种新的布局模式,专门为解决复杂布局而设计。它能够让我们更轻松地创建响应式布局,特别是在一维布局中表现出色。
Flexbox 核心概念
1. 弹性容器和弹性项目
css
.container {
display: flex; /* 容器变为弹性容器 */
}
.panel {
/* 每个 panel 自动成为弹性项目 */
}
2. 主轴和交叉轴
- 主轴(main axis) :弹性项目主要沿此方向排列
- 交叉轴(cross axis) :与主轴垂直的方向
Flexbox 容器属性详解
1. flex-direction - 定义主轴方向
css
.container {
flex-direction: row; /* 默认:水平从左到右 */
flex-direction: row-reverse; /* 水平从右到左 */
flex-direction: column; /* 垂直从上到下 */
flex-direction: column-reverse; /* 垂直从下到上 */
}
2. justify-content - 主轴对齐方式
css
.container {
justify-content: flex-start; /* 默认:从主轴起点开始 */
justify-content: flex-end; /* 从主轴终点开始 */
justify-content: center; /* 居中对齐 */
justify-content: space-between; /* 两端对齐,项目间间隔相等 */
justify-content: space-around; /* 每个项目两侧间隔相等 */
justify-content: space-evenly; /* 项目间和两端间隔都相等 */
}
3. align-items - 交叉轴对齐方式
css
.container {
align-items: stretch; /* 默认:拉伸填满容器高度 */
align-items: flex-start; /* 交叉轴起点对齐 */
align-items: flex-end; /* 交叉轴终点对齐 */
align-items: center; /* 交叉轴居中对齐 */
align-items: baseline; /* 项目的第一行文字基线对齐 */
}
4. flex-wrap - 换行控制
css
.container {
flex-wrap: nowrap; /* 默认:不换行 */
flex-wrap: wrap; /* 换行,第一行在上方 */
flex-wrap: wrap-reverse; /* 换行,第一行在下方 */
}
Flexbox 项目属性详解
1. flex-grow - 放大比例
css
.panel {
flex-grow: 0.5; /* 默认0,不放大 */
}
.panel.active {
flex-grow: 5; /* 放大5倍 */
}
2. flex-shrink - 缩小比例
css
.panel {
flex-shrink: 1; /* 默认1,空间不足时等比例缩小 */
}
3. flex-basis - 项目初始大小
css
.panel {
flex-basis: auto; /* 默认auto,基于内容计算 */
flex-basis: 200px; /* 固定200px */
flex-basis: 20%; /* 容器宽度的20% */
}
简写顺序
flex: <grow> <shrink> <basis>
css
flex: 2 1 300px; /* grow = 2, shrink = 1, basis = 300px */
项目中 Flexbox 的应用
css
.container {
display: flex; /* 创建弹性容器 */
width: 90vw; /* 容器宽度 */
/* 默认值:flex-direction: row, justify-content: flex-start */
}
.panel {
flex: 0.5; /* 初始状态:flex-grow: 0.5 */
height: 80vh; /* 固定高度 */
}
.panel.active {
flex: 5; /* 激活状态:flex-grow: 5 */
}
布局计算原理:
- 初始状态:所有面板
flex-grow总和 = 0.5 × 5 = 2.5 - 激活面板占据:5 ÷ 2.5 = 2/5 的剩余空间
- 其他面板各占据:0.5 ÷ 2.5 = 1/5 的剩余空间
- flex-grow 分配的是剩余空间,不是总空间
- 分配比例 = 项目flex-grow ÷ 所有项目flex-grow总和
- 最终宽度 = 基础宽度 + 分配的剩余空间
弹性布局的实际应用技巧
1. 居中布局的多种方式
传统方式:
css
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Flexbox 方式:
css
.container {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
2. 等分布局
css
.container {
display: flex;
}
.item {
flex: 1; /* 所有项目等分空间 */
}
3. 圣杯布局
css
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.header, .footer {
flex: 0 0 auto; /* 不伸缩,基于内容高度 */
}
.content {
flex: 1; /* 占据剩余所有空间 */
}
4. 响应式导航
css
.nav {
display: flex;
flex-wrap: wrap;
}
.nav-item {
flex: 1 0 200px; /* 最小200px,可伸缩 */
}
Stylus 预处理器详解
项目中提供了 Stylus 版本,展示了 CSS 预处理器的强大功能:
Stylus 是什么?
Stylus 是一种 CSS 预处理器,它扩展了 CSS 的功能,提供了更简洁、更强大的语法,最终编译成标准的 CSS。
安装和使用
bash
# 全局安装 Stylus
npm install -g stylus
# 编译 Stylus 文件为 CSS
stylus style.styl -o style.css
# 监听文件变化自动编译
stylus style.styl -o style.css -w
Stylus 语法特性
1. 简洁的语法(可选花括号、分号和冒号)
stylus
/* Stylus 语法 */
.container
display flex
width 90vw
/* 编译后的 CSS */
.container {
display: flex;
width: 90vw;
}
2. 嵌套规则
stylus
.container
display flex
.panel
height 80vh
h3
font-size 24px
3. & 符号引用父选择器
stylus
.panel
height 80vh
&.active
flex 5
&:hover
transform scale(1.05)
4. 变量和计算
stylus
// 定义变量
primary-color = #fff
panel-height = 80vh
.panel
color primary-color
height panel-height
margin panel-height * 0.1
5. Mixins(混合)
stylus
// 定义混合
border-radius(n)
-webkit-border-radius n
-moz-border-radius n
border-radius n
// 使用混合
.panel
border-radius(50px)
Stylus 优势总结:
- 代码更简洁:减少约 40% 的代码量
- 可读性更强:清晰的嵌套结构
- 维护更方便:变量和混合功能
- 自动化前缀:自动添加浏览器前缀
- 减少重绘区域
- 确保动画元素有自己的复合层
- 使用
transform: translateZ(0)开启硬件加速
总结
通过这个扩展卡片项目,我们深入学习了:
- Flexbox 弹性布局的完整体系:容器属性、项目属性、主轴交叉轴概念
- CSS Transition 的详细配置:属性、时长、时间函数、延迟的完整用法
- Stylus 预处理器的强大功能:更简洁、更强大的 CSS 编写方式
- 响应式设计的实践:通过媒体查询确保多设备兼容性
弹性布局的核心价值在于它提供了一种更加直观、灵活的布局方式,特别适合构建现代 Web 应用的界面。结合 CSS 过渡动画,我们可以创建出既美观又交互流畅的用户体验。
前端开发的进阶之路在于掌握这些基础技术的深度原理,并能够灵活运用于实际项目中。通过这个项目,你不仅学会了一个酷炫的效果,更重要的是掌握了实现这种效果的核心技术原理。
完整代码已在文章中提供,建议亲手实践并尝试不同的修改。你可以调整 flex-grow 值观察布局变化,修改 transition 参数体验不同的动画效果,尝试用 Stylus 重写 CSS 代码,添加新的交互功能或动画效果,创造出属于你自己的独特效果!