Beispiel:Scroll-Snap-4.html
Aus SELFHTML-Wiki
<!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>
<h1>Bilder-Karussell mit <code>scroll-button()</code><span>und <code>scroll-marker-group</code></span><span>und Button für automatische und zufällige Anzeige</span></h1>
<p id="browsersupport"><a href="https://caniuse.com/mdn-css_selectors_scroll-marker" target="_blank">Browser Support</a>: <code>scroll-marker</code> wird von diesem Browser <span></span></p>
<figure id="gallery">
<ul class="carousel">
<li><img src="//wiki.selfhtml.org/images/4/4b/Landscape-1.svg" alt="Landschaft in der Toskana"></li>
<li><img src="//wiki.selfhtml.org/images/d/dc/Landscape-2.svg" alt="Gebirge - Tagsüber"></li>
<li><img src="//wiki.selfhtml.org/images/6/6e/Landscape-2-night.svg" alt="Gebirge - nachts bei Mondschein"></li>
<li><img src="//wiki.selfhtml.org/images/b/bb/Landscape-3.svg" alt="Abendstimmung am See"></li>
<li><img src="https://wiki.selfhtml.org/images/b/b8/Landscape-3-dawn.svg" alt="Morgenstimmung bei Tagesanbruch"></li>
<li><img src="//wiki.selfhtml.org/images/b/b9/Seascape.svg" alt="Unterwasser-Landschaft"></li>
</ul>
<button type="button" value="auto_play" title="Automatisch anzeigen"><span class="visually-hidden">automatisch abspielen</span>
<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"><span class="visually-hidden">shuffle</span>
<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>
<!-- ▶️ 🔀 🛑 -->