一套基于 Swiper.js 实现的响应式企业发展历程卡片轮播组件。
项目将企业历史、品牌里程碑、技术演进等具有明确时间顺序的内容组织为横向等高卡片,通过 slidesPerView: 'auto' + 自定义卡片宽度 + 下一张局部预览,在桌面端和手机端都保持清晰的浏览节奏。
与普通产品轮播不同,本组件强调的是 “按顺序阅读”,因此默认 不循环、不自动播放,并保留第一张与最后一张的导航禁用状态。
- 桌面端约显示 3 张完整卡片 + 下一张局部预览
- 中等屏幕自动增加单卡片宽度,减少同时显示数量
- 手机端卡片宽度约为 68.46vw,明显露出下一张
- 支持鼠标拖动、触控滑动和上一阶段 / 下一阶段按钮
- 使用 Swiper
slidesPerView: 'auto' - 不启用
loop - 不启用
autoplay - 首尾导航按钮不隐藏,而是以浅灰色表示禁用状态
- 卡片保持等高
- 标题区域预留统一高度,避免标题长短不同造成分隔线错位
- 图片统一使用
aspect-ratio + object-fit: cover - 年份与标题分隔线使用单一强调色
- 仅保留非常轻微的图片 Hover 动效
- 支持
prefers-reduced-motion - Swiper JS / CSS 本地加载,不依赖运行时 CDN
这套组件最适合内容本身具有明确先后顺序的展示场景,例如:
- 企业发展历程
- 品牌历史
- 公司里程碑
- 产品演进
- 技术路线
- 重大事件
- 项目阶段
- 制造能力升级
- 全球市场拓展过程
- 企业数字化转型历程
如果内容只是无顺序的产品、案例或图片浏览,普通卡片轮播会更合适。
responsive-history-card-carousel/
├── index.html
├── README.md
├── css/
│ └── style.css
├── js/
│ └── main.js
├── images/
│ ├── 01.svg
│ ├── 02.svg
│ ├── 03.svg
│ ├── 04.svg
│ ├── 05.svg
│ └── 06.svg
└── vendor/
└── swiper/
├── swiper-bundle.min.css
└── swiper-bundle.min.js
项目没有 npm、构建工具或远程运行依赖,直接打开 index.html 即可预览。
项目内置 6 个中文企业发展阶段:
| 时间 | 阶段 | 说明 |
|---|---|---|
| 2008 - 2011 | 创业起步 | 建立产品与制造基础 |
| 2012 - 2015 | 规模扩张 | 完善生产与质量体系 |
| 2016 - 2019 | 全球布局 | 拓展海外市场与合作网络 |
| 2020 - 2022 | 产品升级 | 构建更完整的解决方案 |
| 2023 - 2025 | 数字化转型 | 连接研发、制造与服务 |
| 2026 - 至今 | 智能化发展 | 面向下一阶段持续进化 |
这些内容仅用于展示组件结构,可以直接替换成真实企业数据。
Swiper 不负责计算“一屏必须显示几张”,而是让 CSS 决定每张卡片宽度:
new Swiper('.history-swiper', {
slidesPerView: 'auto',
spaceBetween: 24
});对应 CSS:
.history-slide {
width: 30.5%;
}因此实际可视数量由:
视口宽度
+
卡片宽度
+
卡片间距
共同决定。
这也是下一张卡片能够自然露出的关键。
如果使用:
slidesPerView: 3Swiper 会尽量把三张卡片正好填满容器,下一张通常完全隐藏。
本项目改为:
slidesPerView: auto
+
.history-slide { width: 30.5%; }
因此桌面端形成:
┌────────┐ ┌────────┐ ┌────────┐ ┌──
│ Card 1 │ │ Card 2 │ │ Card 3 │ │
└────────┘ └────────┘ └────────┘ └──
↑
下一阶段预览
这种局部露出本身就是一种视觉导航。
手机端:
.history-slide {
width: 68.46vw;
max-width: 300px;
}当前卡片不会占满整个屏幕,因此右侧可以明显看到下一阶段。
这种处理比 width: 100% 更容易让用户立即理解:
页面可以继续横向滑动。
本项目没有设置:
loop: true这是刻意的设计。
企业发展历程具有明确的时间方向:
过去 → 现在
如果最后一个阶段继续循环回第一个阶段:
2026 → 2008
会削弱时间线本身的语义。
因此第一张和最后一张都是真实边界。
本组件主要内容包括:
- 年份
- 图片
- 阶段标题
- 说明文字
用户需要一定时间阅读。
自动播放可能在文字尚未读完时切换到下一张,因此本项目默认完全由用户控制:
鼠标拖动
Touch Swipe
上一阶段
下一阶段
对于企业历史类内容,这通常比自动播放更合适。
组件没有把不可点击的按钮直接隐藏。
第一张时:
← 浅灰 / 不可点击
→ 正常
最后一张时:
← 正常
→ 浅灰 / 不可点击
CSS:
.history-arrow.swiper-button-disabled {
opacity: 1;
cursor: default;
}
.history-arrow.swiper-button-disabled path {
stroke: var(--nav-disabled);
}这种方式比直接隐藏按钮更稳定:
- 导航区域不会发生位置变化
- 用户能明确知道已经到达起点或终点
- 更符合时间顺序内容的浏览逻辑
.history-slide {
height: auto;
}.history-card {
display: flex;
flex-direction: column;
height: 100%;
}Swiper Wrapper 本身是 Flex 布局,因此卡片能够保持统一的视觉高度。
这对于不同阶段描述文字长度不完全一致的内容尤其重要。
中文企业历程标题经常会出现:
一行标题
和:
两行标题
如果完全依赖自然高度,标题下方的分隔线会出现上下错位。
本项目通过:
.history-card h2 {
min-height: 3.15em;
}为标题区域预留统一空间。
因此即使标题长短不同,仍然可以保持:
标题区
────────────
描述区
在多张卡片之间基本对齐。
项目使用:
.history-image {
aspect-ratio: 16 / 9;
}
.history-image img {
width: 100%;
height: 100%;
object-fit: cover;
}好处是:
- 不需要为图片写固定高度
- 所有卡片图片比例一致
- 替换不同尺寸真实照片时仍然保持统一布局
- 更容易长期维护
建议真实项目中的图片尽量保持相近构图。
.history-slide {
width: 30.5%;
}视觉目标:
约 3 张完整卡片 + 下一张预览
@media (max-width: 1280px) {
.history-slide {
width: 42%;
}
}随着屏幕缩小,单张卡片占比增加,避免内容过于拥挤。
@media (max-width: 767px) {
.history-slide {
width: 68.46vw;
max-width: 300px;
}
}手机端重点不是尽可能塞进更多卡片,而是:
- 当前卡片足够清楚
- 下一张仍明显可见
- 手指滑动区域足够大
--card-bg: #f5f5f5;使用极浅灰色与页面白色形成轻微层级,不依赖明显边框或阴影。
--accent: #e85f23;主要用于:
- 年份
- 标题下分隔线
- Hover / Focus 状态
建议真实项目中替换为品牌主色。
卡片圆角略大于图片圆角,使层级更自然。
.history-card:hover .history-image img {
transform: scale(1.015);
}缩放幅度非常小,只增加轻微反馈,不影响企业网站整体稳定感。
每一个阶段对应一个 .swiper-slide:
<article class="swiper-slide history-slide">
<div class="history-card">
<p class="history-years">
2016 - 2019
</p>
<div class="history-image">
<img src="images/03.jpg" alt="全球布局阶段">
</div>
<h2>
全球布局<br>
拓展海外市场与合作网络
</h2>
<p class="history-desc">
这里填写该阶段的企业发展说明。
</p>
</div>
</article>维护时通常只需要修改:
年份
图片
标题
描述
Swiper 初始化代码无需变化。
复制一个完整的:
<article class="swiper-slide history-slide">
...
</article>放入:
<div class="swiper-wrapper">即可。
Swiper 会自动识别新的 Slide。
不需要修改:
slidesPerView- 导航按钮
- JS 数量配置
- Pagination 数量
因为本项目没有手工维护卡片数量。
建议至少准备:
4 张以上
这样桌面端才能较明显体现横向轮播价值。
如果只有 1~3 张内容,更适合直接使用普通 Grid,而不是强行使用 Carousel。
只需要修改:
:root {
--accent: #e85f23;
}例如企业品牌色为蓝色:
--accent: #2468d8;年份、分隔线和交互状态会一起更新。
.history-slide {
width: 30.5%;
}数值越大:
卡片越宽
一屏显示越少
下一张预览越明显
数值越小:
卡片越窄
一屏显示越多
.history-slide {
width: 68.46vw;
}如果希望下一张露出更多,可以适当减小这个值。
当前初始化:
new Swiper('.history-swiper', {
slidesPerView: 'auto',
spaceBetween: 24,
speed: 650,
grabCursor: true,
watchOverflow: true,
navigation: {
prevEl: '.history-prev',
nextEl: '.history-next'
}
});其中最重要的是:
slidesPerView: auto
navigation
watchOverflow
watchOverflow 可以在内容不足以滚动时自动处理 Swiper 的锁定状态。
发展历程卡片本身已经包含清晰的:
年份
阶段
顺序
再增加:
● ● ● ● ● ●
通常信息价值不高,反而增加视觉噪音。
因此本项目只保留上一阶段 / 下一阶段按钮和卡片本身的局部预览。
项目已经包含基础可访问性处理:
- 导航按钮使用真实
<button> - 上一阶段 / 下一阶段提供
aria-label - 图片提供
alt - 键盘 Focus 状态清晰可见
- Swiper 区域带有描述性
aria-label - 支持
prefers-reduced-motion
实际项目中建议继续保证:
- 年份文字不要只存在于图片里
- 图片替代文本与真实内容匹配
- 不要依赖颜色作为唯一状态信息
企业发展历程通常只有数张到十几张图片,性能压力不大。
真实项目仍建议:
- 使用 WebP / AVIF 等现代图片格式
- 控制图片实际像素尺寸
- 不要直接上传数 MB 原图
- 非首屏模块可以考虑图片懒加载
- Swiper JS / CSS 保持本地加载或由项目统一管理
slidesPerView: 'auto'- 不循环
- 不自动播放
- 首尾导航禁用状态
- 等高卡片
- 标题最小高度
- 下一张局部预览
- 图片统一比例
- 3D Coverflow
- 自动无限循环
- 高频自动播放
- 大幅 Scale
- 每张卡片复杂独立动画
- 多套重复 Slider 初始化逻辑
这个组件的优势来自 内容顺序、卡片节奏和清晰阅读,而不是复杂动效。
普通产品 Carousel 更关注:
“还有哪些内容?”
History Carousel 更关注:
“接下来发生了什么?”
因此它具有明显的时间方向和终点。
这也是项目默认:
不 Loop
不 Autoplay
保留边界状态
的根本原因。
- HTML5
- CSS3
- Vanilla JavaScript
- Swiper.js
- SVG Demo Assets
核心使用到的前端知识:
- Flexbox
aspect-ratioobject-fitclamp()- CSS Custom Properties
- Media Queries
- Swiper
slidesPerView: 'auto' - Swiper Navigation
- Responsive Card Width
- Equal-height Cards
建议使用现代浏览器:
- Chrome
- Edge
- Firefox
- Safari
- iOS Safari
- Android Chrome
项目使用 aspect-ratio、CSS Variables、clamp() 等现代 CSS 特性,不建议以非常老旧的浏览器作为主要兼容目标。
首个稳定版本:
- 完成响应式企业发展历程卡片轮播
- 完成桌面多卡片 + 下一张预览
- 完成手机约 68vw 卡片布局
- 完成首尾导航禁用状态
- 完成等高卡片与标题对齐
- Swiper JS / CSS 本地化
- 使用 SVG 作为本地演示图片
- 补充完整中文 README
示例代码可根据实际项目需求修改与复用。
项目中的 SVG 仅作为演示占位资源,实际项目请替换为自己的企业图片与内容。