Beispiel:Scroll-Snap-4.html
<!DOCTYPE html> <html> <head>
<meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Bilder-Karussell - Steuerung mit JS</title>
<style>
- gallery {
--button-base-color: gold; --button-accent1-color: skyblue; --button-accent2-color: steelblue; --button-accent3-color: navy;
margin: 0;
& .carousel { anchor-name: --carousel; margin: 0; padding: 0; list-style: none; width: min(100%, 60em); aspect-ratio: 5 / 3; display: flex; overflow-x: auto; color: var(--button-accent3-color); scroll-snap-type: x mandatory; scroll-behavior: auto; /* Damit es beim Shuffle ruhiger wirkt! */ scrollbar-color: var(--button-accent1-color) var(--button-base-color);
scrollbar-width: auto;
::-webkit-scrollbar { width: .5em; }
::-webkit-scrollbar-thumb { background-color: var(--button-accent1-color); border-radius: .25em; }
::-webkit-scrollbar-track { background: var(--button-base-color); }
& li { flex: 0 0 100%; scroll-snap-align: start; }
& img { width: 100%; height: 100%; } }
@supports selector(::scroll-marker) {
.carousel {
overflow: hidden;
scroll-marker-group: after;
font-size: 1.5em;
&::scroll-button(*) {
position-anchor: --carousel;
position: fixed;
align-self: anchor-center;
font-size: 1.25em;
aspect-ratio: 1;
background: var(--button-base-color);
border-color: var(--button-accent2-color);
border-radius: 50%;
}
&::scroll-button(left) {
content: "⬅︎";
left: calc(anchor(left) + 1em);
}
&::scroll-button(right) {
content: "⮕";
right: calc(anchor(right) + 1em);
}
&::scroll-button(*):hover {
background: var(--button-accent2-color);
border-color: var(--button-accent3-color);
}
&::scroll-marker-group {
position-anchor: --carousel;
display: flex;
gap: 1em;
position: fixed;
justify-self: anchor-center;
bottom: calc(anchor(bottom) + 1em);
}
& li::scroll-marker {
/* Stylized markers */
content: "";
width: 1.5em;
aspect-ratio: 1;
background: var(--button-base-color);
border-radius: 50%;
border: thin solid var(--button-accent1-color);
}
& li::scroll-marker:target-current {
background: var(--button-accent1-color);
border-color: var(--button-accent2-color);
}
& li::scroll-marker:hover {
background: var(--button-accent2-color);
border-color: var(--button-accent3-color);
}
}
}
& button {
position-anchor: --carousel;
position: fixed;
top: calc(anchor(top) + 1em);
width: 1.5em;
font-size: 1.5em;
aspect-ratio: 1;
padding:.25em .25em 0;
cursor: pointer;
background: var(--button-base-color);
border: thin solid var(--button-accent1-color);
border-radius: 50%;
text-shadow: none;
&[value=auto_play] {
left: calc(anchor(left) + 1em);
& svg:nth-of-type(1) { display: inline; }
& svg:nth-of-type(2) { display: none; }
}
&[value=auto_stop] {
left: calc(anchor(left) + 1em);
& svg:nth-of-type(1) { display: none; }
& svg:nth-of-type(2) { display: inline; }
}
&[value=random_play] {
right: calc(anchor(right) + 1em);
& svg:nth-of-type(1) { display: inline; }
& svg:nth-of-type(2) { display: none; }
}
&[value=random_stop] {
right: calc(anchor(right) + 1em);
& svg:nth-of-type(1) { display: none; }
& svg:nth-of-type(2) { display: inline; }
}
&:hover {
background: var(--button-accent2-color);
border-color: var(--button-accent3-color);
}
}
}
.visually-hidden {
position: absolute !important;
clip: rect(1px, 1px, 1px, 1px) !important;
padding: 0 !important;
border: 0 !important;
height: 1px !important;
width: 1px !important;
overflow: hidden !important;
white-space: nowrap !important;
}
#browsersupport span::before {
@supports selector(::scroll-marker) {
content: "unterstützt";
background: rgb(0 255 0 / 30%);
}
@supports not selector(::scroll-marker) {
content: "nicht unterstützt";
background: rgb(255 0 0 / 30%);
}
}
h1 span {
display: block;
margin-inline-start: 7em;
}
</style>
<script type="module">
const gallery = document.querySelector("#gallery");
const images = document.querySelectorAll("#gallery .carousel img");
const auto_button = document.querySelector("#gallery button[value=auto_play]");
const random_button = document.querySelector("#gallery button[value=random_play]");
let playlist = [],
to = 0;
function auto() {
for(let i=0;i<images.length;i++) playlist[i] = i;
stop();
showImage(0);
}
function random() {
for(let i=0;i<images.length;i++) playlist[i] = i;
shuffle(playlist);
stop();
showImage(0);
}
function stop() {
clearInterval(to);
}
function showImage(nr) {
if(nr >= images.length) nr = 0;
console.log(nr, playlist[nr], images[playlist[nr]]);
images[playlist[nr]].scrollIntoView();
to = setTimeout(showImage, 2000, ++nr);
}
function shuffle(array) {
let i=array.length,zi,t;
if(i<2) return array;
do {
zi=Math.floor(Math.random()*i);
t=array[zi];
array[zi]=array[--i];
array[i]=t;
} while (i);
return array;
}
gallery.addEventListener("click", clickevent => {
if(clickevent.target.closest("button") && clickevent.target.closest("button").value) {
switch(clickevent.target.closest("button").value) {
case "auto_play":
clickevent.target.closest("button").value = "auto_stop";
random_button.value = "random_play";
auto();
break;
case "auto_stop":
clickevent.target.closest("button").value = "auto_play";
stop();
break;
case "random_play":
auto_button.value = "auto_play";
clickevent.target.closest("button").value = "random_stop";
random();
break;
case "random_stop":
clickevent.target.closest("button").value = "random_play";
stop();
break;
}
}
});
</script>
</head>
<body>
Bilder-Karussell mit scroll-button()und scroll-marker-groupund Button für automatische und zufällige Anzeige
<a href="https://caniuse.com/mdn-css_selectors_scroll-marker" target="_blank">Browser Support</a>: scroll-marker wird von diesem Browser
<figure id="gallery">
- <img src="//wiki.selfhtml.org/images/4/4b/Landscape-1.svg" alt="Landschaft in der Toskana">
- <img src="//wiki.selfhtml.org/images/d/dc/Landscape-2.svg" alt="Gebirge - Tagsüber">
- <img src="//wiki.selfhtml.org/images/6/6e/Landscape-2-night.svg" alt="Gebirge - nachts bei Mondschein">
- <img src="//wiki.selfhtml.org/images/2/2c/Landscape-3-foggy.svg" alt="Abendstimmung am See mit Nebel">
- <img src="//wiki.selfhtml.org/images/b/b8/Landscape-3-dawn.svg" alt="Morgenstimmung bei Tagesanbruch">
- <img src="//wiki.selfhtml.org/images/b/b9/Seascape.svg" alt="Unterwasser-Landschaft">
- <img src="//wiki.selfhtml.org/images/9/93/Landscape-4.svg" alt="Karawane in der Wüste">
- <img src="//wiki.selfhtml.org/images/3/3a/Landscape-5.svg" alt="Fischer im Abendrot">
<button type="button" value="auto_play" title="Automatisch anzeigen">automatisch abspielen <svg viewBox="0 0 200 200"><rect width="200" height="200" fill="none"></rect> <path d="M60,30 l90,70 -90,70z" fill="var(--button-accent3-color)" stroke="var(--button-accent3-color)" stroke-width="30" stroke-linejoin="round"></path> </svg> <svg viewBox="0 0 100 100"> <path d="M30,20 L30,80 M70,20 L70,80" fill="var(--button-accent3-color)" stroke="var(--button-accent3-color)" stroke-width="25" stroke-linecap="round"></path> </svg> </button> <button type="button" value="random_play" title="Zufällig anzeigen">shuffle <svg viewBox="0 0 376 376"> <rect x="0" y="0" width="100%" height="100%" fill="none" stroke="none" stroke-width="1"></rect> <path d="M376 280l-79 68v-45h-13c-42 0-73-19-98-44 10-12 19-23 27-34 2-3 4-5 6-7 19 19 39 33 66 33h13v-38L376 280zM0 129h39c25 0 44 12 62 29 3-4 6-8 9-12 7-10 15-20 23-30 -25-23-55-40-95-40H0V129zM297 28v45h-13c-69 0-108 51-143 97 -31 41-58 76-101 76H0v53h39c69 0 108-51 143-97 31-41 58-76 101-76h13v38l79-68L297 28z" fill="var(--button-accent3-color)"></path> </svg> <svg viewBox="0 0 100 100"> <rect width="100" height="100" fill="none"></rect> <path d="M30,20 L30,80 M70,20 L70,80" fill="none" stroke="var(--button-accent3-color)" stroke-width="25" stroke-linecap="round"></path> </svg> </button> </figure>
</body></html>