CSS 滑块使用 `transform: translateX` 循环浏览图像
CSS Slider Using `transform: translateX` To Cycle Through Images
在使用 translateX
变换 属性 制作动画时,是否可以让 CSS 滑块在两个图像之间循环?
我面临几个问题:
我似乎无法显示第二张图片,即使它在 HTML 中,除非我使用 position: absolute
然后 overflow: hidden
不显示在 parent 上工作吗?
如何重置第一张图片以回到开头重新开始?
注:在动画shorthand中,动画持续2.5s,初始延迟3s。
我只想用 translateX
属性 做这个,因为我想要 60FPS 的平滑度(完成后会用 translate3d
做,但为了让代码更简单阅读我使用过 translateX)。我不想为 margin: left
或 left
属性 等设置动画
任何帮助都会很棒。
代码在下方或 link 到 Codepen:https://codepen.io/anna_paul/pen/ZEJrvRp
body {
position: relative;
margin: 0;
display: flex;
justify-content: center;
}
.container {
width: 500px;
height: 333px;
overflow: hidden;
}
.slider-wrapper {
display: flex;
}
.image {
display: block;
}
.hero-image-1 {
transform: translateX(0);
animation: slide-out-image-1 2.5s 3s cubic-bezier(0.54, 0.12, 0.44, 1)
forwards;
}
@keyframes slide-out-image-1 {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100%);
}
}
.hero-image-2 {
transform: translateX(100%);
animation: slide-in-image-2 2.5s 3s cubic-bezier(0.54, 0.12, 0.44, 1) forwards;
}
@keyframes slide-in-image-2 {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(0);
}
}
<div class="container">
<div class="slider-wrapper">
<picture>
<img class="image hero-image-1" src="https://drive.google.com/uc?export=view&id=1l7cTX35wqd-4eYvFL8A5QLZ7LbOF9m4J">
</picture>
<picture>
<img class="image hero-image-2" src="https://drive.google.com/uc?export=view&id=1iB9R1aoeYSmkPX9Ju3NNOZhKylOjCA0y">
</picture>
</div>
</div>
不,没有 position:absolute
这是不可能的。
对于位置重置,您可以使用 Javascript。这是一个例子;
var counter = 1;
setInterval(function()
{
document.getElementById('radio' + counter).checked=true;
counter++;
if(counter>4){
counter=1;
}
}, 5000);
你可以给.container
一个position:relative
来使溢出生效。绝对定位的元素要求它的容器是 a positioned element.
body {
position: relative;
margin: 0;
display: flex;
justify-content: center;
}
.container {
width: 500px;
height: 333px;
overflow: hidden;
position:relative;
}
.slider-wrapper {
display: flex;
}
.image {
position:absolute;
display: block;
}
.hero-image-1 {
transform: translateX(0);
animation: slide-out-image-1 2.5s 3s cubic-bezier(0.54, 0.12, 0.44, 1)
forwards;
}
@keyframes slide-out-image-1 {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100%);
}
}
.hero-image-2 {
transform: translateX(100%);
animation: slide-in-image-2 2.5s 3s cubic-bezier(0.54, 0.12, 0.44, 1) forwards;
}
@keyframes slide-in-image-2 {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(0);
}
}
<div class="container">
<div class="slider-wrapper">
<picture>
<img class="image hero-image-1" src="https://drive.google.com/uc?export=view&id=1l7cTX35wqd-4eYvFL8A5QLZ7LbOF9m4J">
</picture>
<picture>
<img class="image hero-image-2" src="https://drive.google.com/uc?export=view&id=1iB9R1aoeYSmkPX9Ju3NNOZhKylOjCA0y">
</picture>
</div>
</div>
要创建滑块循环,您需要在滑块移动和停止时定义动画点。在你的情况下,看起来
2.5s + 3s +2.5s +3s = 11s or move + pause(out of container) + move + pause = total.
对于第一个图像,我们需要在容器外设置动画,然后移动到起始位置(在容器外),等待(第二个图像设置动画),然后设置到初始位置并暂停。
对于第二张图片,我们只显示然后隐藏。
body {
height: 100vh;
background-color: hsl(201, 27%, 10%);
color: white;
display: grid;
place-items: center;
position: relative;
}
:root {
--animate: 2.5s;
--pause: 3s;
--totall-duration: calc(var(--animate) * 2 + var(--pause) * 2);
}
.container {
width: 500px;
height: 333px;
overflow: hidden;
}
.slider-wrapper {
width: 200%;
display: flex;
position: relative;
}
.image {
display: flex;
width: 100%;
height: 100%;
}
.hero-image-1 {
top: 0;
left: 0;
position: absolute;
animation: slide-out-image-1 var(--totall-duration) 3s
cubic-bezier(0.54, 0.12, 0.44, 1) infinite;
}
/* start + pause + start + pause = totall */
/* 2.5s + 3s + 2.5s + 3s = 11s*/
@keyframes slide-out-image-1 {
0% {
transform: translateX(0);
}
25% {
transform: translateX(-100%);
}
25.0001% {
transform: translateX(100%);
}
50% {
transform: translateX(100%);
}
75% {
transform: translateX(0%);
}
100% {
transform: translateX(0%);
}
}
.hero-image-2 {
top: 0;
right: 0;
position: absolute;
animation: slide-in-image-2 var(--totall-duration) 3s
cubic-bezier(0.54, 0.12, 0.44, 1) infinite;
}
/* start + pause + start + pause = totall */
/* 2.5s + 3s + 2.5s + 3s = 11s*/
@keyframes slide-in-image-2 {
0% {
transform: translateX(0);
}
25% {
transform: translateX(-100%);
}
50% {
transform: translateX(-100%);
}
75% {
transform: translateX(-200%);
}
100% {
transform: translateX(-200%);
}
}
<div class="container">
<div class="slider-wrapper">
<picture class="hero-image-1">
<img class="image" src="https://drive.google.com/uc?export=view&id=1l7cTX35wqd-4eYvFL8A5QLZ7LbOF9m4J" />
</picture>
<picture class="hero-image-2">
<img class="image" src="https://drive.google.com/uc?export=view&id=1iB9R1aoeYSmkPX9Ju3NNOZhKylOjCA0y" />
</picture>
</div>
</div>
我们可以使用 background
属性.
来做滑块
<!DOCTYPE html>
<html>
<head>
<style>
body { background-color: wheat; }
h1 {
text-align: center;
color: tomato;
}
.slider {
width: 60vw;
margin: 0 auto;
aspect-ratio: 485/323;
transform: translate3d(0, 0, 0);
background-image: url("https://drive.google.com/uc?export=view&id=1l7cTX35wqd-4eYvFL8A5QLZ7LbOF9m4J"),
url("https://drive.google.com/uc?export=view&id=1iB9R1aoeYSmkPX9Ju3NNOZhKylOjCA0y");
background-attachment: scroll, scroll;
background-position: 0% 50%, 100% 50%;
background-repeat: no-repeat, no-repeat;
background-size: 100%, 100%;
animation: slide-background 11s cubic-bezier(0.50, 0.0, 0.50, 1) 3s infinite;
}
@keyframes slide-background {
0% { background-position: 0% 50%, 60vw 50%; }
25% { background-position: -60vw 50%, 0% 50%; }
25.01% { background-position: 60vw 50%, 0% 50%; }
50% { background-position: 60vw 50%, 0% 50%; }
75% { background-position: 0% 50%, -60vw 50%; }
100% { background-position: 0% 50%, 60vw 50%; }
}
</style>
</head>
<body>
<div class="slider"><h1>Cars!</h1></div>
</body>
</html>
如果您更改浏览器大小,它会调整大小。
我知道您想使用 translate
来提高性能。
不知道 transform: translate3d(0, 0, 0);
技巧在此处对 background-*
属性设置动画有多大作用。它是否获得相同的硬件加速?
我成功地创建了一个可扩展的 CSS 轮播。它基于 Christian Schaefer 的想法,即使用 scroll snap with shift。
以下是 5 幻灯片轮播。为了使其正常工作,您需要确保:
- 您将第一个
.carousel-slide
元素的副本放在列表末尾。
- 设置变量:
- --无幻灯片:6; //包括重复的第一张幻灯片= 5+1
- --幻灯片时间:4s; // 停留时间75% + 滑动时间25%
- 修改
tostart
关键帧规则,根据相应的计算设置时间。
/* variables */
:root {
--no-slides: 6; /* including duplicated first slide */
--slide-time: 4s; /* stay time 75% + transition time 25% */
}
/* document styles */
body {
max-width: 400px;
margin: 0 auto;
}
* {
box-sizing: border-box;
scrollbar-color: transparent transparent;
scrollbar-width: 0px;
}
*::-webkit-scrollbar {
width: 0;
}
*::-webkit-scrollbar-track {
background: transparent;
}
*::-webkit-scrollbar-thumb {
background: transparent;
border: none;
}
* {
-ms-overflow-style: none;
}
/* carousel styles */
.carousel {
position: relative;
padding-top: 75%;
perspective: 100px;
}
.carousel-viewport {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
overflow-x: scroll;
scroll-behavior: smooth;
scroll-snap-type: x mandatory;
}
.carousel-viewport,
.carousel-slide {
list-style: none;
margin: 0;
padding: 0;
}
.carousel-slide {
position: relative;
flex: 0 0 100%;
width: 100%;
background: linear-gradient(90deg,#ff4e50, #f9d423);
}
.carousel-pusher {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
scroll-snap-align: center;
}
/* animations */
@media (hover: hover) {
.carousel-pusher {
animation-delay: 0s;
animation-name: tonext, snap;
animation-timing-function: ease;
animation-duration: var(--slide-time);
animation-iteration-count: infinite;
}
.carousel-slide:last-child .carousel-pusher {
animation-name: tostart, snap;
animation-duration: calc(var(--slide-time) * (var(--no-slides) - 1)), var(--slide-time);
animation-delay: var(--slide-time), 0s;
}
}
@keyframes tonext {
0% {
filter: opacity(0);
}
75% {
transform: translateX(0);
}
95% {
transform: translateX(100%);
}
98% {
transform: translateX(100%);
}
99% {
filter: opacity(1);
transform: translateX(0%);
}
}
@keyframes snap {
96% {
scroll-snap-align: center;
}
97% {
scroll-snap-align: none;
}
99% {
scroll-snap-align: none;
}
100% {
scroll-snap-align: center;
}
}
@keyframes tostart {
95.8% { /* some fractions less than next frame time */
transform: translateX(0%);
}
95.823% { /* 0.75 * (100%/--no-slides) + 100% - (100%/--no-slides) +-0.500 adjustment*/
transform: translateX(calc((var(--no-slides)) * -100%));
}
99.5% { /* 0.99 * (100%/--no-slides) + 100% - (100%/--no-slides) +-0.500 adjustment*/
transform: translateX(calc((var(--no-slides) - 2) * -100%));
}
}
/* slide content styles */
.content {
padding: 20px ;
font-size: 150px;
text-align: center;
}
<div class="carousel">
<ul class="carousel-viewport">
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content">1 😊</div>
</li>
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content">2 😉</div>
</li>
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content">3 😄</div>
</li>
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content">4 🙄</div>
</li>
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content">5 😎</div>
</li>
<!-- repeat first slide -->
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content">1 😊</div>
</li>
</ul>
</div>
要获得正确和平滑的过渡,请修改 tostart
关键帧更改时间或添加更多帧。
注意:如果动画停止,您必须将轮播设置为第一张幻灯片,然后再开始动画。同步了三个动画运行。
2个幻灯片版本
<!DOCTYPE html>
<html>
<head>
<style>
/* variables */
:root {
--no-slides: 3; /* including duplicated first slide */
--slide-time: 4s; /* stay time 75% + transition time 25% */
}
/* document styles */
body {
max-width: 400px;
margin: 0 auto;
}
* {
box-sizing: border-box;
scrollbar-color: transparent transparent;
scrollbar-width: 0px;
}
*::-webkit-scrollbar {
width: 0;
}
*::-webkit-scrollbar-track {
background: transparent;
}
*::-webkit-scrollbar-thumb {
background: transparent;
border: none;
}
* {
-ms-overflow-style: none;
}
/* carousel styles */
.carousel {
position: relative;
padding-top: 75%;
perspective: 100px;
}
.carousel-viewport {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
overflow-x: scroll;
scroll-behavior: smooth;
scroll-snap-type: x mandatory;
}
.carousel-viewport,
.carousel-slide {
list-style: none;
margin: 0;
padding: 0;
}
.carousel-slide {
position: relative;
flex: 0 0 100%;
width: 100%;
background-color: #f995;
}
.carousel-slide:nth-child(odd) {
background-color: cadetblue;
}
.carousel-pusher {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
scroll-snap-align: center;
}
/* animations */
@media (hover: hover) {
.carousel-pusher {
animation-delay: 0s;
animation-name: tonext, snap;
animation-timing-function: ease;
animation-duration: var(--slide-time);
animation-iteration-count: infinite;
}
.carousel-slide:last-child .carousel-pusher {
animation-name: tostart, snap;
animation-duration: calc(var(--slide-time) * (var(--no-slides) - 1)),
var(--slide-time);
animation-delay: var(--slide-time), 0s;
}
}
@keyframes tonext {
0% {
filter: opacity(0);
}
75% {
transform: translateX(0);
}
95% {
transform: translateX(100%);
}
98% {
transform: translateX(100%);
}
99% {
filter: opacity(1);
transform: translateX(0%);
}
}
@keyframes snap {
96% {
scroll-snap-align: center;
}
97% {
scroll-snap-align: none;
}
99% {
scroll-snap-align: none;
}
100% {
scroll-snap-align: center;
}
}
@keyframes tostart {
74.999% {
/* some fractions less than next frame */
transform: translateX(0%);
}
75% {
/* 0.75 * (100%/--no-slides) + 100% - (100%/--no-slides) */
transform: translateX(calc((var(--no-slides)) * -100%));
}
99.3% {
/* 0.99 * (100%/--no-slides) + 100% - (100%/--no-slides) - <1.0 - 0.0 adjustment>*/
transform: translateX(calc((var(--no-slides) - 2) * -100%));
}
}
/* slide content styles */
.content {
object-fit: fill;
}
.image {
padding: 0px;
margin: 0px;
width: 100%;
height: 100%;
object-fit: fill;
}
</style>
</head>
<body>
<div class="carousel">
<ul class="carousel-viewport">
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content"
><img
class="image"
src="https://drive.google.com/uc?export=view&id=1l7cTX35wqd-4eYvFL8A5QLZ7LbOF9m4J"
/></div>
</li>
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content"
><img
class="image"
src="https://drive.google.com/uc?export=view&id=1iB9R1aoeYSmkPX9Ju3NNOZhKylOjCA0y"
/></div>
</li>
<!-- repeat first slide -->
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content"
><img
class="image"
src="https://drive.google.com/uc?export=view&id=1l7cTX35wqd-4eYvFL8A5QLZ7LbOF9m4J"
/></div>
</li>
</ul>
</div>
</body>
</html>
在使用 translateX
变换 属性 制作动画时,是否可以让 CSS 滑块在两个图像之间循环?
我面临几个问题:
我似乎无法显示第二张图片,即使它在 HTML 中,除非我使用
position: absolute
然后overflow: hidden
不显示在 parent 上工作吗?如何重置第一张图片以回到开头重新开始?
注:在动画shorthand中,动画持续2.5s,初始延迟3s。
我只想用 translateX
属性 做这个,因为我想要 60FPS 的平滑度(完成后会用 translate3d
做,但为了让代码更简单阅读我使用过 translateX)。我不想为 margin: left
或 left
属性 等设置动画
任何帮助都会很棒。
代码在下方或 link 到 Codepen:https://codepen.io/anna_paul/pen/ZEJrvRp
body {
position: relative;
margin: 0;
display: flex;
justify-content: center;
}
.container {
width: 500px;
height: 333px;
overflow: hidden;
}
.slider-wrapper {
display: flex;
}
.image {
display: block;
}
.hero-image-1 {
transform: translateX(0);
animation: slide-out-image-1 2.5s 3s cubic-bezier(0.54, 0.12, 0.44, 1)
forwards;
}
@keyframes slide-out-image-1 {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100%);
}
}
.hero-image-2 {
transform: translateX(100%);
animation: slide-in-image-2 2.5s 3s cubic-bezier(0.54, 0.12, 0.44, 1) forwards;
}
@keyframes slide-in-image-2 {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(0);
}
}
<div class="container">
<div class="slider-wrapper">
<picture>
<img class="image hero-image-1" src="https://drive.google.com/uc?export=view&id=1l7cTX35wqd-4eYvFL8A5QLZ7LbOF9m4J">
</picture>
<picture>
<img class="image hero-image-2" src="https://drive.google.com/uc?export=view&id=1iB9R1aoeYSmkPX9Ju3NNOZhKylOjCA0y">
</picture>
</div>
</div>
不,没有 position:absolute
这是不可能的。
对于位置重置,您可以使用 Javascript。这是一个例子;
var counter = 1;
setInterval(function()
{
document.getElementById('radio' + counter).checked=true;
counter++;
if(counter>4){
counter=1;
}
}, 5000);
你可以给.container
一个position:relative
来使溢出生效。绝对定位的元素要求它的容器是 a positioned element.
body {
position: relative;
margin: 0;
display: flex;
justify-content: center;
}
.container {
width: 500px;
height: 333px;
overflow: hidden;
position:relative;
}
.slider-wrapper {
display: flex;
}
.image {
position:absolute;
display: block;
}
.hero-image-1 {
transform: translateX(0);
animation: slide-out-image-1 2.5s 3s cubic-bezier(0.54, 0.12, 0.44, 1)
forwards;
}
@keyframes slide-out-image-1 {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100%);
}
}
.hero-image-2 {
transform: translateX(100%);
animation: slide-in-image-2 2.5s 3s cubic-bezier(0.54, 0.12, 0.44, 1) forwards;
}
@keyframes slide-in-image-2 {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(0);
}
}
<div class="container">
<div class="slider-wrapper">
<picture>
<img class="image hero-image-1" src="https://drive.google.com/uc?export=view&id=1l7cTX35wqd-4eYvFL8A5QLZ7LbOF9m4J">
</picture>
<picture>
<img class="image hero-image-2" src="https://drive.google.com/uc?export=view&id=1iB9R1aoeYSmkPX9Ju3NNOZhKylOjCA0y">
</picture>
</div>
</div>
要创建滑块循环,您需要在滑块移动和停止时定义动画点。在你的情况下,看起来
2.5s + 3s +2.5s +3s = 11s or move + pause(out of container) + move + pause = total.
对于第一个图像,我们需要在容器外设置动画,然后移动到起始位置(在容器外),等待(第二个图像设置动画),然后设置到初始位置并暂停。
对于第二张图片,我们只显示然后隐藏。
body {
height: 100vh;
background-color: hsl(201, 27%, 10%);
color: white;
display: grid;
place-items: center;
position: relative;
}
:root {
--animate: 2.5s;
--pause: 3s;
--totall-duration: calc(var(--animate) * 2 + var(--pause) * 2);
}
.container {
width: 500px;
height: 333px;
overflow: hidden;
}
.slider-wrapper {
width: 200%;
display: flex;
position: relative;
}
.image {
display: flex;
width: 100%;
height: 100%;
}
.hero-image-1 {
top: 0;
left: 0;
position: absolute;
animation: slide-out-image-1 var(--totall-duration) 3s
cubic-bezier(0.54, 0.12, 0.44, 1) infinite;
}
/* start + pause + start + pause = totall */
/* 2.5s + 3s + 2.5s + 3s = 11s*/
@keyframes slide-out-image-1 {
0% {
transform: translateX(0);
}
25% {
transform: translateX(-100%);
}
25.0001% {
transform: translateX(100%);
}
50% {
transform: translateX(100%);
}
75% {
transform: translateX(0%);
}
100% {
transform: translateX(0%);
}
}
.hero-image-2 {
top: 0;
right: 0;
position: absolute;
animation: slide-in-image-2 var(--totall-duration) 3s
cubic-bezier(0.54, 0.12, 0.44, 1) infinite;
}
/* start + pause + start + pause = totall */
/* 2.5s + 3s + 2.5s + 3s = 11s*/
@keyframes slide-in-image-2 {
0% {
transform: translateX(0);
}
25% {
transform: translateX(-100%);
}
50% {
transform: translateX(-100%);
}
75% {
transform: translateX(-200%);
}
100% {
transform: translateX(-200%);
}
}
<div class="container">
<div class="slider-wrapper">
<picture class="hero-image-1">
<img class="image" src="https://drive.google.com/uc?export=view&id=1l7cTX35wqd-4eYvFL8A5QLZ7LbOF9m4J" />
</picture>
<picture class="hero-image-2">
<img class="image" src="https://drive.google.com/uc?export=view&id=1iB9R1aoeYSmkPX9Ju3NNOZhKylOjCA0y" />
</picture>
</div>
</div>
我们可以使用 background
属性.
<!DOCTYPE html>
<html>
<head>
<style>
body { background-color: wheat; }
h1 {
text-align: center;
color: tomato;
}
.slider {
width: 60vw;
margin: 0 auto;
aspect-ratio: 485/323;
transform: translate3d(0, 0, 0);
background-image: url("https://drive.google.com/uc?export=view&id=1l7cTX35wqd-4eYvFL8A5QLZ7LbOF9m4J"),
url("https://drive.google.com/uc?export=view&id=1iB9R1aoeYSmkPX9Ju3NNOZhKylOjCA0y");
background-attachment: scroll, scroll;
background-position: 0% 50%, 100% 50%;
background-repeat: no-repeat, no-repeat;
background-size: 100%, 100%;
animation: slide-background 11s cubic-bezier(0.50, 0.0, 0.50, 1) 3s infinite;
}
@keyframes slide-background {
0% { background-position: 0% 50%, 60vw 50%; }
25% { background-position: -60vw 50%, 0% 50%; }
25.01% { background-position: 60vw 50%, 0% 50%; }
50% { background-position: 60vw 50%, 0% 50%; }
75% { background-position: 0% 50%, -60vw 50%; }
100% { background-position: 0% 50%, 60vw 50%; }
}
</style>
</head>
<body>
<div class="slider"><h1>Cars!</h1></div>
</body>
</html>
如果您更改浏览器大小,它会调整大小。
我知道您想使用 translate
来提高性能。
不知道 transform: translate3d(0, 0, 0);
技巧在此处对 background-*
属性设置动画有多大作用。它是否获得相同的硬件加速?
我成功地创建了一个可扩展的 CSS 轮播。它基于 Christian Schaefer 的想法,即使用 scroll snap with shift。
以下是 5 幻灯片轮播。为了使其正常工作,您需要确保:
- 您将第一个
.carousel-slide
元素的副本放在列表末尾。 - 设置变量:
- --无幻灯片:6; //包括重复的第一张幻灯片= 5+1
- --幻灯片时间:4s; // 停留时间75% + 滑动时间25%
- 修改
tostart
关键帧规则,根据相应的计算设置时间。
/* variables */
:root {
--no-slides: 6; /* including duplicated first slide */
--slide-time: 4s; /* stay time 75% + transition time 25% */
}
/* document styles */
body {
max-width: 400px;
margin: 0 auto;
}
* {
box-sizing: border-box;
scrollbar-color: transparent transparent;
scrollbar-width: 0px;
}
*::-webkit-scrollbar {
width: 0;
}
*::-webkit-scrollbar-track {
background: transparent;
}
*::-webkit-scrollbar-thumb {
background: transparent;
border: none;
}
* {
-ms-overflow-style: none;
}
/* carousel styles */
.carousel {
position: relative;
padding-top: 75%;
perspective: 100px;
}
.carousel-viewport {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
overflow-x: scroll;
scroll-behavior: smooth;
scroll-snap-type: x mandatory;
}
.carousel-viewport,
.carousel-slide {
list-style: none;
margin: 0;
padding: 0;
}
.carousel-slide {
position: relative;
flex: 0 0 100%;
width: 100%;
background: linear-gradient(90deg,#ff4e50, #f9d423);
}
.carousel-pusher {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
scroll-snap-align: center;
}
/* animations */
@media (hover: hover) {
.carousel-pusher {
animation-delay: 0s;
animation-name: tonext, snap;
animation-timing-function: ease;
animation-duration: var(--slide-time);
animation-iteration-count: infinite;
}
.carousel-slide:last-child .carousel-pusher {
animation-name: tostart, snap;
animation-duration: calc(var(--slide-time) * (var(--no-slides) - 1)), var(--slide-time);
animation-delay: var(--slide-time), 0s;
}
}
@keyframes tonext {
0% {
filter: opacity(0);
}
75% {
transform: translateX(0);
}
95% {
transform: translateX(100%);
}
98% {
transform: translateX(100%);
}
99% {
filter: opacity(1);
transform: translateX(0%);
}
}
@keyframes snap {
96% {
scroll-snap-align: center;
}
97% {
scroll-snap-align: none;
}
99% {
scroll-snap-align: none;
}
100% {
scroll-snap-align: center;
}
}
@keyframes tostart {
95.8% { /* some fractions less than next frame time */
transform: translateX(0%);
}
95.823% { /* 0.75 * (100%/--no-slides) + 100% - (100%/--no-slides) +-0.500 adjustment*/
transform: translateX(calc((var(--no-slides)) * -100%));
}
99.5% { /* 0.99 * (100%/--no-slides) + 100% - (100%/--no-slides) +-0.500 adjustment*/
transform: translateX(calc((var(--no-slides) - 2) * -100%));
}
}
/* slide content styles */
.content {
padding: 20px ;
font-size: 150px;
text-align: center;
}
<div class="carousel">
<ul class="carousel-viewport">
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content">1 😊</div>
</li>
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content">2 😉</div>
</li>
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content">3 😄</div>
</li>
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content">4 🙄</div>
</li>
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content">5 😎</div>
</li>
<!-- repeat first slide -->
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content">1 😊</div>
</li>
</ul>
</div>
要获得正确和平滑的过渡,请修改 tostart
关键帧更改时间或添加更多帧。
注意:如果动画停止,您必须将轮播设置为第一张幻灯片,然后再开始动画。同步了三个动画运行。
2个幻灯片版本
<!DOCTYPE html>
<html>
<head>
<style>
/* variables */
:root {
--no-slides: 3; /* including duplicated first slide */
--slide-time: 4s; /* stay time 75% + transition time 25% */
}
/* document styles */
body {
max-width: 400px;
margin: 0 auto;
}
* {
box-sizing: border-box;
scrollbar-color: transparent transparent;
scrollbar-width: 0px;
}
*::-webkit-scrollbar {
width: 0;
}
*::-webkit-scrollbar-track {
background: transparent;
}
*::-webkit-scrollbar-thumb {
background: transparent;
border: none;
}
* {
-ms-overflow-style: none;
}
/* carousel styles */
.carousel {
position: relative;
padding-top: 75%;
perspective: 100px;
}
.carousel-viewport {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
overflow-x: scroll;
scroll-behavior: smooth;
scroll-snap-type: x mandatory;
}
.carousel-viewport,
.carousel-slide {
list-style: none;
margin: 0;
padding: 0;
}
.carousel-slide {
position: relative;
flex: 0 0 100%;
width: 100%;
background-color: #f995;
}
.carousel-slide:nth-child(odd) {
background-color: cadetblue;
}
.carousel-pusher {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
scroll-snap-align: center;
}
/* animations */
@media (hover: hover) {
.carousel-pusher {
animation-delay: 0s;
animation-name: tonext, snap;
animation-timing-function: ease;
animation-duration: var(--slide-time);
animation-iteration-count: infinite;
}
.carousel-slide:last-child .carousel-pusher {
animation-name: tostart, snap;
animation-duration: calc(var(--slide-time) * (var(--no-slides) - 1)),
var(--slide-time);
animation-delay: var(--slide-time), 0s;
}
}
@keyframes tonext {
0% {
filter: opacity(0);
}
75% {
transform: translateX(0);
}
95% {
transform: translateX(100%);
}
98% {
transform: translateX(100%);
}
99% {
filter: opacity(1);
transform: translateX(0%);
}
}
@keyframes snap {
96% {
scroll-snap-align: center;
}
97% {
scroll-snap-align: none;
}
99% {
scroll-snap-align: none;
}
100% {
scroll-snap-align: center;
}
}
@keyframes tostart {
74.999% {
/* some fractions less than next frame */
transform: translateX(0%);
}
75% {
/* 0.75 * (100%/--no-slides) + 100% - (100%/--no-slides) */
transform: translateX(calc((var(--no-slides)) * -100%));
}
99.3% {
/* 0.99 * (100%/--no-slides) + 100% - (100%/--no-slides) - <1.0 - 0.0 adjustment>*/
transform: translateX(calc((var(--no-slides) - 2) * -100%));
}
}
/* slide content styles */
.content {
object-fit: fill;
}
.image {
padding: 0px;
margin: 0px;
width: 100%;
height: 100%;
object-fit: fill;
}
</style>
</head>
<body>
<div class="carousel">
<ul class="carousel-viewport">
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content"
><img
class="image"
src="https://drive.google.com/uc?export=view&id=1l7cTX35wqd-4eYvFL8A5QLZ7LbOF9m4J"
/></div>
</li>
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content"
><img
class="image"
src="https://drive.google.com/uc?export=view&id=1iB9R1aoeYSmkPX9Ju3NNOZhKylOjCA0y"
/></div>
</li>
<!-- repeat first slide -->
<li class="carousel-slide">
<div class="carousel-pusher"></div>
<div class="content"
><img
class="image"
src="https://drive.google.com/uc?export=view&id=1l7cTX35wqd-4eYvFL8A5QLZ7LbOF9m4J"
/></div>
</li>
</ul>
</div>
</body>
</html>