翻页效果的核心是 CSS 的 transform 和 transition 属性,以及 JavaScript 来控制翻页的时机和逻辑。

(图片来源网络,侵删)
最简单的单页翻转效果 (纯 CSS)
这种效果非常基础,点击页面时,整个页面会像一张纸一样翻转过来,显示背面的内容。
核心思路:
- HTML 结构: 创建一个包含“正面”和“背面”两个子元素的容器。
- CSS 样式:
- 设置容器为
perspective(透视),这是产生 3D 效果的关键。 - 给容器内的子元素设置
backface-visibility: hidden;,这样背面一开始就是不可见的。 - 给背面元素设置一个
transform: rotateY(180deg);,让它一开始就旋转到背面。 - 为容器添加一个
.flipped类,当这个类被添加时,让整个容器旋转180deg。
- 设置容器为
- JavaScript: 监听点击事件,点击时给容器添加或移除
.flipped类。
完整代码示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">简单翻页效果</title>
<style>
/* 基础样式 */
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
font-family: sans-serif;
}
/* 3D 场景容器 */
.scene {
width: 400px;
height: 600px;
perspective: 1000px; /* 透视距离,值越大,3D 效果越不明显 */
}
/* 翻页卡片 */
.card {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d; /* 保持 3D 变换 */
transition: transform 0.8s; /* 翻转动画的持续时间 */
cursor: pointer;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
/* 点击后添加的翻转类 */
.card.flipped {
transform: rotateY(180deg);
}
/* 卡片的正反两面 */
.card-face {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden; /* 隐藏背面 */
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
font-size: 2em;
color: white;
text-align: center;
padding: 20px;
box-sizing: border-box;
}
/* 正面 */
.card-front {
background-color: #3498db; /* 蓝色 */
}
/* 背面 (一开始就旋转180度,所以是正的) */
.card-back {
background-color: #e74c3c; /* 红色 */
transform: rotateY(180deg);
}
</style>
</head>
<body>
<div class="scene">
<div class="card" id="myCard">
<div class="card-face card-front">
<h1>点击我</h1>
<p>翻到背面</p>
</div>
<div class="card-face card-back">
<h1>你好!</h1>
<p>这是背面</p>
</div>
</div>
</div>
<script>
const card = document.getElementById('myCard');
card.addEventListener('click', () => {
// 切换 flipped 类
card.classList.toggle('flipped');
});
</script>
</body>
</html>
模拟书本翻页效果 (更逼真)
这种效果更复杂,它会模拟书页从一侧卷曲翻过去的过程,这通常需要更高级的 CSS 技术,clip-path 或 transform-origin。
核心思路:
- HTML 结构: 创建一个代表书页的元素,它包含“当前页”和“下一页”的内容。
- CSS 样式:
- 使用
transform-origin: left center;将旋转的轴心设置在左侧。 - 使用
border-radius创建卷曲的圆角效果。 - 使用
box-shadow模拟翻页时的阴影。 - 使用
transform: rotateY(-30deg);来模拟翻页过程中的弯曲效果。
- 使用
- JavaScript: 控制动画的起始和结束。
完整代码示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">书本翻页效果</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #2c3e50;
font-family: 'Georgia', serif;
perspective: 2000px;
}
.book {
position: relative;
width: 300px;
height: 400px;
}
.page {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: #fff;
border-radius: 0 5px 5px 0;
box-shadow: 0 0 20px rgba(0,0,0,0.2);
padding: 20px;
box-sizing: border-box;
transform-origin: left center;
transition: transform 1.5s cubic-bezier(0.645, 0.045, 0.355, 1); /* 使用贝塞尔曲线让动画更自然 */
backface-visibility: hidden;
}
.page-front {
z-index: 2; /* 确保它在下一页之上 */
}
.page-back {
z-index: 1;
background-color: #f9f9f9;
}
/* 翻转后的状态 */
.page.flipped {
transform: rotateY(-180deg);
}
.page-content {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.page-content h2 {
margin-top: 0;
}
.page-number {
position: absolute;
bottom: 10px;
right: 10px;
font-size: 12px;
color: #888;
}
</style>
</head>
<body>
<div class="book">
<div class="page page-front" id="page1">
<div class="page-content">
<h2>第一页</h2>
<p>这是书本的第一页内容。</p>
<p>点击页面,翻到下一页。</p>
</div>
<div class="page-number">1</div>
</div>
<div class="page page-back" id="page2">
<div class="page-content">
<h2>第二页</h2>
<p>这是书本的第二页内容。</p>
<p>再次点击可以翻回来。</p>
</div>
<div class="page-number">2</div>
</div>
</div>
<script>
const page1 = document.getElementById('page1');
const page2 = document.getElementById('page2');
page1.addEventListener('click', () => {
page1.classList.toggle('flipped');
// page2 也需要翻转才能显示正面
page2.classList.toggle('flipped');
});
</script>
</body>
</html>
多页书籍翻页效果 (高级)
这是最接近真实书本体验的效果,可以向前或向后翻页,它需要更多的 HTML 元素来代表每一页,并用 JavaScript 来管理当前页的状态。
核心思路:
- HTML 结构: 创建一个包含多个
.page元素的容器,每个.page代表一页,奇数页在右侧,偶数页在左侧。 - CSS 样式:
- 使用
transform-style: preserve-3d;和transform: rotateY(180deg);来处理页面堆叠和朝向,确保所有页面的内容都是正的。 - 使用
z-index来控制页面的层级,确保当前页在最上面。 - 翻页动画与方案二类似,但轴心位置和旋转方向会根据是向前还是向后翻页而改变。
- 使用
- JavaScript:
- 记录当前页码。
- 监听点击事件(或按钮事件)。
- 根据点击位置(左半部分还是右半部分)决定是向前还是向后翻页。
- 给目标页添加
.flipped类来触发动画。 - 在动画结束后,更新当前页码并重置页面状态,为下一次翻页做准备。
完整代码示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">多页书籍翻页效果</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #333;
font-family: 'Arial', sans-serif;
overflow: hidden;
}
.book-container {
position: relative;
width: 800px;
height: 600px;
perspective: 3000px;
}
.book {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
}
.page {
position: absolute;
width: 50%;
height: 100%;
top: 0;
background: linear-gradient(to right, #eee, #f5f5f5);
box-shadow: 0 0 15px rgba(0,0,0,0.1);
padding: 20px;
box-sizing: border-box;
transform-origin: left center; /* 默认从左边翻 */
transition: transform 1.8s cubic-bezier(0.645, 0.045, 0.355, 1);
backface-visibility: hidden;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
font-size: 1.2em;
color: #333;
}
/* 奇数页 (右侧) */
.page:nth-child(odd) {
left: 50%;
border-radius: 0 5px 5px 0;
box-shadow: -2px 0 15px rgba(0,0,0,0.1);
}
/* 偶数页 (左侧) */
.page:nth-child(even) {
left: 0;
border-radius: 5px 0 0 5px;
transform-origin: right center; /* 从右边翻时,轴心在右侧 */
}
/* 翻转后的状态 */
.page.flipped {
transform: rotateY(-180deg);
}
/* 控制按钮 */
.controls {
position: absolute;
bottom: -50px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 20px;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="book-container">
<div class="book" id="book">
<!-- 封面 -->
<div class="page">
<h1>我的魔法书</h1>
<p>点击右侧开始阅读</p>
</div>
<!-- 第1页 (右侧) -->
<div class="page" data-page="1">
<h2>第一章:开始</h2>
<p>这是一个关于代码和想象力的故事...</p>
</div>
<!-- 第2页 (左侧) -->
<div class="page" data-page="2">
<p>故事发生在一个充满数字和逻辑的世界。</p>
</div>
<!-- 第3页 (右侧) -->
<div class="page" data-page="3">
<h2>第二章:探索</h2>
<p>主角开始了一段奇妙的旅程...</p>
</div>
<!-- 第4页 (左侧) -->
<div class="page" data-page="4">
<p>他遇到了许多挑战,但也学到了很多。</p>
</div>
<!-- 第5页 (右侧) -->
<div class="page" data-page="5">
<h2>第三章:结局</h2>
<p>他找到了答案...</p>
</div>
<!-- 第6页 (左侧) -->
<div class="page" data-page="6">
<p>生活又恢复了平静。</p>
</div>
<!-- 封底 -->
<div class="page">
<h1>谢谢阅读</h1>
</div>
</div>
<div class="controls">
<button id="prevBtn">上一页</button>
<button id="nextBtn">下一页</button>
</div>
</div>
<script>
const book = document.getElementById('book');
const pages = book.querySelectorAll('.page');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
let currentPageIndex = 0; // 当前页的索引
const totalPages = pages.length;
function flipPage(direction) {
// 确定目标页
let targetPageIndex;
if (direction === 'next' && currentPageIndex < totalPages - 1) {
targetPageIndex = currentPageIndex + 1;
} else if (direction === 'prev' && currentPageIndex > 0) {
targetPageIndex = currentPageIndex - 1;
} else {
return; // 已经是第一页或最后一页,不执行操作
}
const targetPage = pages[targetPageIndex];
// 翻转目标页
targetPage.classList.add('flipped');
// 更新当前页索引
currentPageIndex = targetPageIndex;
// 更新按钮状态
updateButtons();
}
function updateButtons() {
prevBtn.disabled = currentPageIndex === 0;
nextBtn.disabled = currentPageIndex === totalPages - 1;
}
prevBtn.addEventListener('click', () => flipPage('prev'));
nextBtn.addEventListener('click', () => flipPage('next'));
// 初始化按钮状态
updateButtons();
</script>
</body>
</html>
总结与选择建议
| 方案 | 复杂度 | 效果 | 适用场景 |
|---|---|---|---|
| 方案一 | 低 | 简单的 180 度翻转 | 卡片式翻转、展示正反两面信息。 |
| 方案二 | 中 | 书本式单页翻转 | 展示一个简单的两页内容,如邀请函、贺卡。 |
| 方案三 | 高 | 多页书本式翻页 | 创建完整的在线书籍、相册、杂志等。 |
如何选择?

(图片来源网络,侵删)
- 如果只是想做一个简单的卡片翻转,方案一 完全足够。
- 如果想做一个类似“翻书”效果的两页展示,方案二 是一个很好的起点。
- 如果你想构建一个功能完整的在线书籍,需要多页、前进后退功能,那么应该参考 方案三 的思路。
希望这些代码和解释能帮助您实现想要的翻页效果!

(图片来源网络,侵删)
