这个方案将使用 纯CSS3和少量JavaScript 来实现,无需引入任何外部库(如jQuery),轻量且高效,效果模拟了真实的书籍翻页,包括页面阴影、卷曲效果和3D透视。

(图片来源网络,侵删)
最终效果预览
核心实现思路
-
HTML结构:
- 一个容器
.book,作为整本书的包裹,设置3D透视。 - 两个页面
.page,分别代表左页和右页。 - 每个页面内部包含
.page-front(正面) 和.page-back(背面),用于实现翻过去后能看到背面内容。
- 一个容器
-
CSS3 (核心部分):
- 3D变换: 使用
transform-style: preserve-3d;让子元素可以在3D空间中渲染。 - 翻页动画: 使用
transform: rotateY(-180deg);配合transition实现平滑的翻页旋转。 - 页面阴影: 使用
box-shadow创建逼真的页面厚度和阴影效果。 - 伪元素: 使用
:before和:after伪元素来创建页面卷曲的边缘和阴影,增加真实感。
- 3D变换: 使用
-
JavaScript (交互部分):
- 监听触摸事件(
touchstart,touchmove,touchend)和鼠标事件(mousedown,mousemove,mouseup),以实现移动端和PC端的兼容。 - 通过计算手指/鼠标的移动距离,动态设置页面的旋转角度,实现“拖拽翻页”的交互。
- 在翻页结束时,根据最终角度判断是否翻到下一页,并重置状态。
- 监听触摸事件(
完整代码
你可以直接将以下代码保存为一个 .html 文件,然后在浏览器中打开(建议使用手机浏览器或开启手机模拟模式查看)。

(图片来源网络,侵删)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">HTML5 手机电子书翻页效果</title>
<style>
/* 全局样式和重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', sans-serif;
background: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow: hidden; /* 防止页面滚动 */
-webkit-user-select: none; /* 禁止文字选择 */
user-select: none;
}
/* 书本容器 */
.book {
position: relative;
width: 90vw; /* 视窗宽度的90% */
max-width: 400px;
height: 60vh; /* 视窗高度的60% */
perspective: 2000px; /* 3D透视距离,值越大,3D效果越弱 */
}
/* 单页容器 */
.page {
position: absolute;
width: 50%;
height: 100%;
top: 0;
transform-origin: left center; /* 设置旋转原点在左侧中心 */
transition: transform 0.5s ease-in-out;
transform-style: preserve-3d; /* 让子元素在3D空间中呈现 */
background-color: #fff;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
}
/* 右页 */
.page.right {
left: 50%;
border-radius: 0 15px 15px 0;
}
/* 左页 */
.page.left {
right: 50%;
border-radius: 15px 0 0 15px;
transform-origin: right center; /* 左页的旋转原点在右侧 */
}
/* 页面的正面和背面 */
.page-front, .page-back {
position: absolute;
width: 100%;
height: 100%;
padding: 20px;
backface-visibility: hidden; /* 背面不可见 */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
font-size: 1.2rem;
color: #333;
}
/* 页面背面需要旋转180度,使其内容正向 */
.page-back {
transform: rotateY(180deg);
background-color: #fafafa; /* 背面颜色稍作区分 */
}
/* 翻页后的状态 */
.page.flipped {
transform: rotateY(-180deg); /* 右页向右翻 */
}
.page.left.flipped {
transform: rotateY(180deg); /* 左页向左翻 */
}
/* 页面卷曲和阴影效果 (使用伪元素) */
.page::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to right, rgba(0,0,0,0.1) 0%, transparent 10%);
opacity: 0;
transition: opacity 0.5s;
pointer-events: none;
}
.page.flipped::before {
opacity: 1;
}
/* 状态提示 */
.status {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 10px 20px;
border-radius: 20px;
font-size: 14px;
}
</style>
</head>
<body>
<div class="status" id="status">点击或拖拽页面进行翻页</div>
<div class="book" id="book">
<!-- 左页 -->
<div class="page left" id="page-left">
<div class="page-front">
<h2>第一章:开始</h2>
<p>欢迎来到这本电子书的世界。</p>
<p>请点击或拖拽右侧页面开始阅读。</p>
</div>
<div class="page-back">
<!-- 左页的背面通常是上一页的背面,但为了演示,我们留空或放一些装饰 -->
</div>
</div>
<!-- 右页 -->
<div class="page right" id="page-right">
<div class="page-front">
<h2>第一章:开始 (续)</h2>
<p>HTML5 提供了许多强大的特性,让我们能够创造出更加丰富和互动的网页体验。</p>
<p>这个翻页效果就是利用 CSS3 的 3D 变换实现的。</p>
</div>
<div class="page-back">
<h2>第二章:探索</h2>
<p>翻过这一页,我们将探索更多关于 CSS3 的奥秘。</p>
<p>包括动画、过渡和 3D 变换。</p>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const book = document.getElementById('book');
const pageLeft = document.getElementById('page-left');
const pageRight = document.getElementById('page-right');
const status = document.getElementById('status');
let isDragging = false;
let startX = 0;
let currentPage = 0; // 0: 初始页, 1: 第二页, 2: 第三页
const totalPages = 3; // 总页数(演示用)
// 更新状态提示
function updateStatus(text) {
status.textContent = text;
}
// 翻页逻辑
function flipPage(pageElement) {
if (!pageElement.classList.contains('flipped')) {
pageElement.classList.add('flipped');
currentPage++;
updateStatus(`当前页: ${currentPage + 1} / ${totalPages}`);
} else {
pageElement.classList.remove('flipped');
currentPage--;
updateStatus(`当前页: ${currentPage + 1} / ${totalPages}`);
}
}
// 鼠标/触摸开始
function handleStart(e) {
isDragging = true;
startX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
book.style.cursor = 'grabbing';
}
// 鼠标/触摸移动
function handleMove(e) {
if (!isDragging) return;
e.preventDefault(); // 阻止默认行为,如页面滚动
const currentX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
const diffX = currentX - startX;
const page = diffX > 0 ? pageLeft : pageRight;
// 根据拖动距离设置旋转角度
const rotation = Math.max(-180, Math.min(180, diffX / 2));
if (page === pageLeft) {
pageLeft.style.transform = `rotateY(${rotation}deg)`;
} else {
pageRight.style.transform = `rotateY(${-rotation}deg)`;
}
}
// 鼠标/触摸结束
function handleEnd(e) {
if (!isDragging) return;
isDragging = false;
book.style.cursor = 'grab';
const currentX = e.type.includes('mouse') ? e.clientX : e.changedTouches[0].clientX;
const diffX = currentX - startX;
// 判断是否翻页(拖动距离超过50px)
if (Math.abs(diffX) > 50) {
if (diffX > 0 && currentPage > 0) {
// 向右拖,如果是左页,则翻回
pageLeft.style.transform = '';
flipPage(pageLeft);
} else if (diffX < 0 && currentPage < totalPages - 1) {
// 向左拖,如果是右页,则翻过
pageRight.style.transform = '';
flipPage(pageRight);
}
} else {
// 拖动距离不足,回弹
pageLeft.style.transform = '';
pageRight.style.transform = '';
}
}
// 为书本添加事件监听
book.addEventListener('mousedown', handleStart);
book.addEventListener('touchstart', handleStart);
document.addEventListener('mousemove', handleMove);
document.addEventListener('touchmove', handleMove);
document.addEventListener('mouseup', handleEnd);
document.addEventListener('touchend', handleEnd);
// 点击翻页
pageRight.addEventListener('click', () => {
if (currentPage < totalPages - 1) {
flipPage(pageRight);
}
});
pageLeft.addEventListener('click', () => {
if (currentPage > 0) {
flipPage(pageLeft);
}
});
updateStatus(`当前页: ${currentPage + 1} / ${totalPages}`);
});
</script>
</body>
</html>
如何扩展和自定义
-
增加更多页面:
- 在HTML中,复制
.page结构,并根据需要调整left/right位置和内容。 - 在JavaScript中,增加
totalPages的值。 - 翻页逻辑需要更复杂一些,通常需要一个数组来管理所有页面的DOM元素,然后根据
currentPage索引来控制当前显示的页面。
- 在HTML中,复制
-
加载真实内容:
- 你可以将
.page-front和.page-back中的内容替换为<div class="content"></div>。 - 通过JavaScript,你可以使用
fetch或XMLHttpRequest从服务器或本地JSON文件加载章节内容,然后动态插入到这些contentdiv中。
- 你可以将
-
美化样式:
- 修改
.page的background-color、box-shadow来模拟不同质感的纸张。 - 调整
.book的perspective值来改变3D效果的强度。 - 在
.page内部添加页码、页眉、页脚等元素。
- 修改
-
添加动画效果:
(图片来源网络,侵删)- 目前的代码已经包含了基础的
transition,你可以通过JavaScript动态修改transition-duration来实现快慢翻页的效果。 - 更高级的翻页效果(如撕纸效果、波浪效果)则需要更复杂的CSS和JavaScript,或者使用专门的书本渲染库(如
turn.js)。
- 目前的代码已经包含了基础的
这个示例为你提供了一个坚实的基础,你可以在此基础上进行二次开发,打造出功能更完善的手机电子书应用。
