用CSS实现苹果官网轮播图,我们先分析下要实现的轮播图效果。
- 每屏展示当前轮播图,
- 同时显示前一张图,和后一张图,前后图用遮罩盖住
- 轮播图下面有指示点 高亮点表明当前是哪一张轮播图
- 点击点可以跳转到对应的轮播图
- 自动轮播
技术实现思路
我们会用CSS的一些特性如scroll-snap-type
,scroll-snap-align
, 实现轮播每次切换,都是切换一整张幻灯片,而不是像滚动条自由随意的滚动效果,那样就不像轮播图了;同时我们也会利用CSS动画效果实现自动播放,利用a标签点击跳转实现点击圆点到对应的轮播图
展示当期轮播图 并且显示上一张图,和下一张图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>用CSS实现苹果官网轮播图</title>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: sans-serif;
background: #f0f0f0;
}
.carousel {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
gap: 1rem;
padding: 1rem;
}
.carousel::-webkit-scrollbar {
display: none;
}
.carousel__slide {
flex: 0 0 80%;
scroll-snap-align: center;
position: relative;
border-radius: 10px;
background: #fff;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
height: 676px;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
background-size: cover;
background-position: center;
}
#slide1 {
background-image: url('https://is1-ssl.mzstatic.com/image/thumb/hjmYsl20uNCFQ9sqjiQIYw/2500x1406.jpg');
}
#slide2 {
background-image: url('https://is1-ssl.mzstatic.com/image/thumb/Features221/v4/7d/6b/46/7d6b4699-b669-1c1b-7661-d5eae0ff00f8/6832cd56-83a4-43be-9eb0-c1ced85499b9.png/2500x1406.jpg');
}
#slide3 {
background-image: url('https://is1-ssl.mzstatic.com/image/thumb/4UEcdeb6Xoc40fhFSAr3Og/2500x1406.jpg');
}
#slide4 {
background-image: url('https://is1-ssl.mzstatic.com/image/thumb/Features/v4/1e/01/8a/1e018acf-c8ff-1fbe-844d-c7e573dd383a/57c591a9-2c28-4f62-b6ee-c69a3ff56a3d.png/2500x1406.jpg');
}
.carousel__nav {
text-align: center;
}
.carousel__nav a {
display: inline-block;
width: 12px;
height: 12px;
margin: 0 6px;
background: #ccc;
border-radius: 50%;
transition: background 0.3s;
}
.carousel__nav a:focus,
.carousel__nav a:hover {
background: #333;
}
</style>
</head>
<body>
<section class="carousel" aria-label="Gallery">
<div id="slide1" class="carousel__slide"></div>
<div id="slide2" class="carousel__slide"></div>
<div id="slide3" class="carousel__slide"></div>
<div id="slide4" class="carousel__slide"></div>
</section>
<nav class="carousel__nav">
<a href="#slide1"></a>
<a href="#slide2"></a>
<a href="#slide3"></a>
<a href="#slide4"></a>
</nav>
</body>
</html>
上面的代码实现了4张轮播图切换的效果,并且点击圆点可以切换到对应的轮播图
点击点可以跳转到对应的轮播图
<section class="carousel" aria-label="Gallery">
<div id="slide1" class="carousel__slide"></div>
<div id="slide2" class="carousel__slide"></div>
<div id="slide3" class="carousel__slide"></div>
<div id="slide4" class="carousel__slide"></div>
</section>
<nav class="carousel__nav">
<a href="#slide1"></a>
<a href="#slide2"></a>
<a href="#slide3"></a>
<a href="#slide4"></a>
</nav>
我们用锚点跳转(Anchor Link / Fragment Identifier),实现点击圆点可以切换到对应的轮播图,可以看到a标签的#slide1和id="slide1"是对应的
给前后图添加遮罩
.carousel {
/* 现有属性保留 */
display: flex;
...
/* 添加遮罩渐变 */
-webkit-mask-image: linear-gradient(to right, transparent 0%, black 20%, black 80%, transparent 100%);
mask-image: linear-gradient(to right, transparent 0%, black 20%, black 80%, transparent 100%);
}
黑色表示完全可见,白色表示完全不可见。这与直觉相反,因为我们通常认为黑色是 "遮挡" 的颜色,但在 CSS 遮罩系统中,逻辑是反向的。
这样有2个问题
- 第一张图/最后一张图我们不需要遮罩
- 遮罩是固定不变的,这不是我们要的效果,我们要的是当一个图离开中心区域,变成上一张或下一张的时候加上遮罩
苹果官网用的应该是不透明度遮罩,我们把渐变换成不透明度效果
/* 添加遮罩渐变 */
-webkit-mask-image: linear-gradient(
to right,
rgba(0, 0, 0, 0.5) 0%,
rgba(0, 0, 0, 0.5) 7%,
black 7%,
black 93%,
rgba(0, 0, 0, 0.5) 93%,
rgba(0, 0, 0, 0.5) 100%
);
mask-image: linear-gradient(
to right,
rgba(0, 0, 0, 0.5) 0%,
rgba(0, 0, 0, 0.5) 7%,
black 7%,
black 93%,
rgba(0, 0, 0, 0.5) 93%,
rgba(0, 0, 0, 0.5) 100%
);
实现自动轮播
我们用CSS动画实现轮播,这里我们多加了一个div, carousel__track
,
<section class="carousel" aria-label="Gallery">
<div class="carousel__track">
<div class="carousel__slide" id="slide1"></div>
<div class="carousel__slide" id="slide2"></div>
<div class="carousel__slide" id="slide3"></div>
<div class="carousel__slide" id="slide4"></div>
</div>
</section>
样式更改主要是在最外层增加了position: relative;overflow: hidden;
.carousel {
position: relative;
overflow: hidden;
width: 100%;
}
.carousel__track {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
gap: 1rem;
padding: 1rem;
/* 添加遮罩渐变 */
-webkit-mask-image: linear-gradient(
to right,
rgba(0, 0, 0, 0.5) 0%,
rgba(0, 0, 0, 0.5) 7%,
black 7%,
black 93%,
rgba(0, 0, 0, 0.5) 93%,
rgba(0, 0, 0, 0.5) 100%
);
mask-image: linear-gradient(
to right,
rgba(0, 0, 0, 0.5) 0%,
rgba(0, 0, 0, 0.5) 7%,
black 7%,
black 93%,
rgba(0, 0, 0, 0.5) 93%,
rgba(0, 0, 0, 0.5) 100%
);
}
.carousel__track::-webkit-scrollbar {
display: none;
}
.carousel__slide {
flex: 0 0 87%;
scroll-snap-align: center;
position: relative;
border-radius: 0px;
background: #fff;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
height: 676px;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
background-size: cover;
background-position: center;
animation: slide 6s infinite;
}
@keyframes slide {
0%,
20% {
transform: translateX(0);
}
25%,
45% {
transform: translateX(-90%);
}
50%,
70% {
transform: translateX(-180%);
}
75%,
95% {
transform: translateX(-270%);
}
100% {
transform: translateX(0);
}
}
GIF 上传不不成功,可以点击预览看下最终效果
结论: 花了挺长时间,用了各种大模型,还是实现不了,只用CSS 实现苹果官网那种带有前后图预览,遮罩,自动轮播,无缝切换的效果,需要Javascript,简单的轮播用CSS还是很容易实现的
附上完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>用CSS实现苹果官网轮播图</title>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: sans-serif;
background: #f0f0f0;
}
.carousel {
position: relative;
overflow: hidden;
width: 100%;
}
.carousel__track {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
gap: 1rem;
padding: 1rem;
/* 添加遮罩渐变 */
-webkit-mask-image: linear-gradient(
to right,
rgba(0, 0, 0, 0.5) 0%,
rgba(0, 0, 0, 0.5) 7%,
black 7%,
black 93%,
rgba(0, 0, 0, 0.5) 93%,
rgba(0, 0, 0, 0.5) 100%
);
mask-image: linear-gradient(
to right,
rgba(0, 0, 0, 0.5) 0%,
rgba(0, 0, 0, 0.5) 7%,
black 7%,
black 93%,
rgba(0, 0, 0, 0.5) 93%,
rgba(0, 0, 0, 0.5) 100%
);
}
.carousel__track::-webkit-scrollbar {
display: none;
}
.carousel__slide {
flex: 0 0 87%;
scroll-snap-align: center;
position: relative;
border-radius: 0px;
background: #fff;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
height: 676px;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
background-size: cover;
background-position: center;
animation: slide 6s infinite;
}
@keyframes slide {
0%,
20% {
transform: translateX(0);
}
25%,
45% {
transform: translateX(-90%);
}
50%,
70% {
transform: translateX(-180%);
}
75%,
95% {
transform: translateX(-270%);
}
100% {
transform: translateX(0);
}
}
#slide1 {
background-image: url('https://is1-ssl.mzstatic.com/image/thumb/hjmYsl20uNCFQ9sqjiQIYw/2500x1406.jpg');
}
#slide2 {
background-image: url('https://is1-ssl.mzstatic.com/image/thumb/Features221/v4/7d/6b/46/7d6b4699-b669-1c1b-7661-d5eae0ff00f8/6832cd56-83a4-43be-9eb0-c1ced85499b9.png/2500x1406.jpg');
}
#slide3 {
background-image: url('https://is1-ssl.mzstatic.com/image/thumb/4UEcdeb6Xoc40fhFSAr3Og/2500x1406.jpg');
}
#slide4 {
background-image: url('https://is1-ssl.mzstatic.com/image/thumb/Features/v4/1e/01/8a/1e018acf-c8ff-1fbe-844d-c7e573dd383a/57c591a9-2c28-4f62-b6ee-c69a3ff56a3d.png/2500x1406.jpg');
}
.carousel__nav {
text-align: center;
}
.carousel__nav a {
display: inline-block;
width: 10px;
height: 10px;
margin: 0 6px;
background: #ccc;
border-radius: 50%;
transition: background 0.3s;
}
.carousel__nav a:focus,
.carousel__nav a:hover {
background: #333;
}
</style>
</head>
<body>
<section class="carousel" aria-label="Gallery">
<div class="carousel__track">
<div class="carousel__slide" id="slide1"></div>
<div class="carousel__slide" id="slide2"></div>
<div class="carousel__slide" id="slide3"></div>
<div class="carousel__slide" id="slide4"></div>
</div>
</section>
<nav class="carousel__nav">
<a href="#slide1"></a>
<a href="#slide2"></a>
<a href="#slide3"></a>
<a href="#slide4"></a>
</nav>
</body>
</html>