Beispiel:Scroll-Snap-4.html

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche
<!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>
<!-- ▶️ 🔀 🛑 -->