使用纯 CSS(最简单,适合新手)
这种方法不使用任何 JavaScript,仅依靠 CSS 的 hover 伪类来实现鼠标悬停时切换图片,优点是代码量极少,性能好;缺点是交互方式单一(只能悬停)。

(图片来源网络,侵删)
原理
- 创建一个包含所有图片的容器。
- 将所有图片绝对定位在同一个位置上,使其完全重叠。
- 默认只显示第一张图片(
opacity: 1或z-index较高)。 - 为每张图片设置一个唯一的 ID。
- 使用相邻选择器 () 或兄弟选择器 (),让当鼠标悬停在容器上时,改变其他图片的透明度 (
opacity)。
示例代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">纯CSS幻灯片</title>
<style>
/* 幻灯片容器 */
.slideshow-container {
position: relative; /* 相对定位,作为内部图片的定位基准 */
max-width: 800px;
margin: auto;
height: 400px; /* 固定高度,防止图片切换时布局跳动 */
}
/* 所有图片的公共样式 */
.slide {
position: absolute; /* 绝对定位,使所有图片重叠 */
width: 100%;
height: 100%;
opacity: 0; /* 默认所有图片都透明 */
transition: opacity 1s ease-in-out; /* 添加淡入淡出效果 */
}
/* 默认显示第一张图片 */
#slide1 {
opacity: 1;
}
/* 鼠标悬停在容器上时的效果 */
.slideshow-container:hover #slide1 {
opacity: 0;
}
.slideshow-container:hover #slide2 {
opacity: 1;
}
.slideshow-container:hover #slide3 {
opacity: 0;
}
/* 鼠标悬停在第二张图片上时,显示第三张 */
/* 注意:这里需要将第二张图片也设为悬停目标 */
.slideshow-container:hover #slide2:hover ~ #slide3 {
opacity: 1;
}
.slideshow-container:hover #slide2:hover ~ #slide1 {
opacity: 0;
}
/* 鼠标悬停在第三张图片上时,显示第一张 */
.slideshow-container:hover #slide3:hover ~ #slide1 {
opacity: 1;
}
.slideshow-container:hover #slide3:hover ~ #slide2 {
opacity: 0;
}
</style>
</head>
<body>
<div class="slideshow-container">
<img src="https://picsum.photos/800/400?random=1" class="slide" id="slide1">
<img src="https://picsum.photos/800/400?random=2" class="slide" id="slide2">
<img src="https://picsum.photos/800/400?random=3" class="slide" id="slide3">
</div>
</body>
</html>
局限性:这种方法逻辑复杂,图片越多,CSS 规则就越臃肿,且无法实现自动轮播。
使用原生 JavaScript(最灵活,适合学习)
这种方法使用 JavaScript 来控制图片的显示和隐藏,可以实现自动轮播、手动切换、指示器等多种功能。
原理
- HTML:创建一个容器,里面包含所有图片。
- CSS:将所有图片设置为绝对定位,使其重叠,只默认显示第一张。
- JavaScript:
- 获取所有图片元素。
- 创建一个变量
currentIndex来追踪当前显示的是哪张图片。 - 编写一个
showSlide(index)函数,该函数会隐藏所有图片,然后只显示index指定的那张。 - 使用
setInterval来定时调用showSlide,实现自动轮播。 - 添加“上一个”、“下一个”按钮和指示器,并绑定点击事件。
示例代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">JavaScript幻灯片</title>
<style>
/* 幻灯片容器 */
.slideshow-container {
position: relative;
max-width: 800px;
margin: auto;
height: 400px;
}
/* 所有图片 */
.slide {
display: none; /* 默认隐藏所有图片 */
width: 100%;
height: 100%;
}
/* 只显示第一张图片 */
.slide.active {
display: block;
}
/* 按钮样式 */
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -22px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none; /* 防止文字被选中 */
}
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
.prev:hover, .next:hover {
background-color: rgba(0,0,0,0.8);
}
/* 指示器样式 */
.dots-container {
text-align: center;
padding: 20px;
}
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 5px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.dot.active, .dot:hover {
background-color: #717171;
}
</style>
</head>
<body>
<div class="slideshow-container">
<div class="slide active">
<img src="https://picsum.photos/800/400?random=1" style="width:100%; height:100%; object-fit:cover;">
</div>
<div class="slide">
<img src="https://picsum.photos/800/400?random=2" style="width:100%; height:100%; object-fit:cover;">
</div>
<div class="slide">
<img src="https://picsum.photos/800/400?random=3" style="width:100%; height:100%; object-fit:cover;">
</div>
<a class="prev">❮</a>
<a class="next">❯</a>
</div>
<div class="dots-container">
<span class="dot active" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
</div>
<script>
let slideIndex = 1;
showSlide(slideIndex);
// 自动轮播,每3秒切换一次
setInterval(function() {
plusSlides(1);
}, 3000);
// 上一个/下一个按钮功能
function plusSlides(n) {
showSlide(slideIndex += n);
}
// 指示器点击功能
function currentSlide(n) {
showSlide(slideIndex = n);
}
function showSlide(n) {
let i;
let slides = document.getElementsByClassName("slide");
let dots = document.getElementsByClassName("dot");
// n 超出范围,则循环到第一张或最后一张
if (n > slides.length) { slideIndex = 1; }
if (n < 1) { slideIndex = slides.length; }
// 隐藏所有图片
for (i = 0; i < slides.length; i++) {
slides[i].classList.remove("active");
}
// 移除所有指示点的激活状态
for (i = 0; i < dots.length; i++) {
dots[i].classList.remove("active");
}
// 显示当前图片
slides[slideIndex - 1].classList.add("active");
// 激活当前指示点
dots[slideIndex - 1].classList.add("active");
}
</script>
</body>
</html>
使用第三方库(最快捷,适合项目)
对于实际项目,尤其是使用现代框架(如 React, Vue)的项目,使用成熟的库是最高效、最稳定的选择,它们经过了大量测试,功能丰富,且易于使用。
推荐库
-
Swiper.js
(图片来源网络,侵删)- 特点:功能极其强大,移动端体验极佳,支持触摸滑动、3D 效果、分页、滚动条等,是目前最流行的幻灯片库之一。
- 官网:https://swiperjs.com/
-
Slick
- 特点:轻量级,配置简单,效果炫酷,支持响应式。
- 官网:https://kenwheeler.github.io/slick/
使用 Swiper.js 示例
第一步:引入 Swiper 的 CSS 和 JS 文件,你可以从 CDN 引入,也可以下载到本地。
<!-- Swiper CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css"/> <!-- Swiper JS --> <script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
第二步:编写 HTML 结构。
<!-- Swiper -->
<div class="swiper mySwiper">
<div class="swiper-wrapper">
<div class="swiper-slide">
<img src="https://picsum.photos/800/400?random=1">
</div>
<div class="swiper-slide">
<img src="https://picsum.photos/800/400?random=2">
</div>
<div class="swiper-slide">
<img src="https://picsum.photos/800/400?random=3">
</div>
</div>
<!-- 如果需要分页器 -->
<div class="swiper-pagination"></div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
<!-- 如果需要滚动条 -->
<div class="swiper-scrollbar"></div>
</div>
第三步:初始化 Swiper。

(图片来源网络,侵删)
<script>
document.addEventListener('DOMContentLoaded', function () {
var swiper = new Swiper(".mySwiper", {
// 配置参数
loop: true, // 循环模式
// 自动播放
autoplay: {
delay: 2500,
disableOnInteraction: false,
},
// 分页器
pagination: {
el: ".swiper-pagination",
clickable: true,
},
// 导航按钮
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
// 滚动条
scrollbar: {
el: ".swiper-scrollbar",
},
});
});
</script>
总结与对比
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 纯 CSS | 代码量少,无 JS 依赖,性能好 | 交互单一,逻辑复杂,无法自动轮播 | 简单的鼠标悬停效果展示,学习 CSS 技巧 |
| 原生 JavaScript | 灵活性最高,无外部依赖,利于学习 | 代码量较多,需要自己处理所有细节 | 学习 JS DOM 操作,或对库有排斥的小型项目 |
| 第三方库 | 功能强大,效果丰富,移动端优化好,开发效率高 | 引入外部文件,有一定学习成本 | 绝大多数实际项目,特别是商业网站和应用 |
给你的建议:
- 如果你是初学者:先尝试 方法二(原生 JavaScript),它能帮你很好地理解 DOM 操作和事件处理。
- 如果你正在做一个实际项目:强烈推荐 方法三(Swiper.js),它能让你在几分钟内实现一个专业级的幻灯片,并把更多精力放在业务逻辑上。
