Gallery

<!-- Gallery -->
<div class="gallery">
    <div class="gallery__slides-frame">
        <div class="gallery__slider">
            <div class="gallery__slider-item">
                <figure class="figure" aria-labelledby="figure-dda3bb-label"><a class="figure__media figure__media--lightbox js-lightbox" href="https://placehold.co/1046x588/A0A0A6/FFFFFF.png?text=1046x588" data-size="1046x588">
                        <picture>
                            <source srcset="https://placehold.co/1046x588/A0A0A6/FFFFFF.webp?text=1046x588-webp" type="image/webp" media="(min-width:78.75em)" />
                            <source srcset="https://placehold.co/1046x588/A0A0A6/FFFFFF.jpg?text=1046x588-jpg" type="image/jpg" media="(min-width:78.75em)" />
                            <source srcset="https://placehold.co/1144x644/A0A0A6/FFFFFF.webp?text=1144x644-webp" type="image/webp" media="(min-width:48em)" />
                            <source srcset="https://placehold.co/1144x644/A0A0A6/FFFFFF.jpg?text=1144x644-jpg" type="image/jpg" media="(min-width:48em)" />
                            <source srcset="https://placehold.co/682x384/A0A0A6/FFFFFF.webp?text=682x384-webp" type="image/webp" />
                            <img src="https://picsum.photos/id/FFFFFF/682/384" alt="Das ist ein Alt-Text. Das ist ein Pflichtfeld." width="682" height="384" loading="lazy" />
                        </picture><button class="figure__lightbox-button" aria-hidden="aria-hidden"><svg class="icon icon--plus" viewBox="0 0 200 200" role="presentation">
                                <use xlink:href="#icon-plus"></use>
                            </svg></button>
                    </a>
                    <figcaption class="figure__caption" id="figure-dda3bb-label"><span class="figure__caption__text">Slide 1: Ich bin eine Bildunterschrift</span></figcaption>
                </figure>
            </div>
            <div class="gallery__slider-item">
                <figure class="figure" aria-labelledby="figure-1f3a1f-label"><a class="figure__media figure__media--lightbox js-lightbox" href="https://placehold.co/1046x588/A0A0A6/FFFFFF.png?text=1046x588" data-size="1046x588">
                        <picture>
                            <source srcset="https://placehold.co/1046x588/A0A0A6/FFFFFF.webp?text=1046x588-webp" type="image/webp" media="(min-width:78.75em)" />
                            <source srcset="https://placehold.co/1046x588/A0A0A6/FFFFFF.jpg?text=1046x588-jpg" type="image/jpg" media="(min-width:78.75em)" />
                            <source srcset="https://placehold.co/1144x644/A0A0A6/FFFFFF.webp?text=1144x644-webp" type="image/webp" media="(min-width:48em)" />
                            <source srcset="https://placehold.co/1144x644/A0A0A6/FFFFFF.jpg?text=1144x644-jpg" type="image/jpg" media="(min-width:48em)" />
                            <source srcset="https://placehold.co/682x384/A0A0A6/FFFFFF.webp?text=682x384-webp" type="image/webp" />
                            <img src="https://picsum.photos/id/FFFFFF/682/384" alt="Das ist ein Alt-Text. Das ist ein Pflichtfeld." width="682" height="384" loading="lazy" />
                        </picture><button class="figure__lightbox-button" aria-hidden="aria-hidden"><svg class="icon icon--plus" viewBox="0 0 200 200" role="presentation">
                                <use xlink:href="#icon-plus"></use>
                            </svg></button>
                    </a>
                    <figcaption class="figure__caption" id="figure-1f3a1f-label"><span class="figure__caption__text">Slide 2: Ich bin eine Bildunterschrift</span></figcaption>
                </figure>
            </div>
        </div>
    </div><button class="button button--primary gallery__button" type="button"><span class="button__inner"><svg class="icon icon--foto" viewBox="0 0 200 200" role="presentation">
                <use xlink:href="#icon-foto"></use>
            </svg><span class="button__text">Bilder</span></span></button>
</div>

<!-- Gallery single -->
<div class="gallery">
    <div class="gallery__slides-frame">
        <div class="gallery__slider">
            <div class="gallery__slider-item">
                <figure class="figure" aria-labelledby="figure-7e7367-label"><a class="figure__media figure__media--lightbox js-lightbox" href="https://placehold.co/1000x1000/A0A0A6/FFFFFF.png?text=1000x1000" data-size="1000x1000">
                        <picture>
                            <source srcset="https://placehold.co/479x479/A0A0A6/FFFFFF.webp?text=479x479-webp" type="image/webp" />
                            <img src="https://picsum.photos/id/FFFFFF/500/500" alt="Das ist ein Alt-Text. Das ist ein Pflichtfeld." width="500" height="500" loading="lazy" />
                        </picture><button class="figure__lightbox-button" aria-hidden="aria-hidden"><svg class="icon icon--plus" viewBox="0 0 200 200" role="presentation">
                                <use xlink:href="#icon-plus"></use>
                            </svg></button>
                    </a>
                    <figcaption class="figure__caption" id="figure-7e7367-label"><span class="figure__caption__text">Ich bin eine Bildunterschrift</span></figcaption>
                </figure>
            </div>
        </div>
    </div>
</div>

#{tag || 'div'}.gallery&attributes(attr)
  if items
    .gallery__slides-frame: .gallery__slider
      each item in items
        .gallery__slider-item
          +include('@figure', item.figure, false)

  if button
    +include('@button',  _.merge(button, {
        attr: {
          class: 'gallery__button'
        },
    }), false)
/* Gallery */
{
  "items": [
    {
      "figure": {
        "picture": {
          "src": null,
          "width": 682,
          "height": 384,
          "lazyload": true,
          "items": [
            {
              "src": "https://placehold.co/1046x588/A0A0A6/FFFFFF.webp?text=1046x588-webp",
              "type": "webp",
              "breakpoint": 1260
            },
            {
              "src": "https://placehold.co/1046x588/A0A0A6/FFFFFF.jpg?text=1046x588-jpg",
              "type": "jpg",
              "breakpoint": 1260
            },
            {
              "src": "https://placehold.co/1144x644/A0A0A6/FFFFFF.webp?text=1144x644-webp",
              "type": "webp",
              "breakpoint": 768
            },
            {
              "src": "https://placehold.co/1144x644/A0A0A6/FFFFFF.jpg?text=1144x644-jpg",
              "type": "jpg",
              "breakpoint": 768
            },
            {
              "src": "https://placehold.co/682x384/A0A0A6/FFFFFF.webp?text=682x384-webp",
              "type": "webp",
              "breakpoint": null
            }
          ]
        },
        "lightbox": {
          "src": "https://placehold.co/1046x588/A0A0A6/FFFFFF.png?text=1046x588",
          "width": 1046,
          "height": 588
        },
        "caption": {
          "text": "Slide 1: Ich bin eine Bildunterschrift"
        }
      }
    },
    {
      "figure": {
        "picture": {
          "src": null,
          "width": 682,
          "height": 384,
          "lazyload": true,
          "items": [
            {
              "src": "https://placehold.co/1046x588/A0A0A6/FFFFFF.webp?text=1046x588-webp",
              "type": "webp",
              "breakpoint": 1260
            },
            {
              "src": "https://placehold.co/1046x588/A0A0A6/FFFFFF.jpg?text=1046x588-jpg",
              "type": "jpg",
              "breakpoint": 1260
            },
            {
              "src": "https://placehold.co/1144x644/A0A0A6/FFFFFF.webp?text=1144x644-webp",
              "type": "webp",
              "breakpoint": 768
            },
            {
              "src": "https://placehold.co/1144x644/A0A0A6/FFFFFF.jpg?text=1144x644-jpg",
              "type": "jpg",
              "breakpoint": 768
            },
            {
              "src": "https://placehold.co/682x384/A0A0A6/FFFFFF.webp?text=682x384-webp",
              "type": "webp",
              "breakpoint": null
            }
          ]
        },
        "lightbox": {
          "src": "https://placehold.co/1046x588/A0A0A6/FFFFFF.png?text=1046x588",
          "width": 1046,
          "height": 588
        },
        "caption": {
          "text": "Slide 2: Ich bin eine Bildunterschrift"
        }
      }
    }
  ],
  "button": {
    "text": "Bilder",
    "icon": "foto"
  }
}

/* Gallery single */
{
  "items": [
    {
      "figure": {
        "picture": {
          "src": null,
          "width": 500,
          "height": 500,
          "lazyload": true,
          "items": [
            {
              "src": "https://placehold.co/479x479/A0A0A6/FFFFFF.webp?text=479x479-webp",
              "type": "webp",
              "breakpoint": null
            }
          ]
        },
        "lightbox": {
          "src": "https://placehold.co/1000x1000/A0A0A6/FFFFFF.png?text=1000x1000",
          "width": 1000,
          "height": 1000
        },
        "caption": {
          "text": "Ich bin eine Bildunterschrift"
        }
      }
    }
  ]
}

  • Content:
    import { lory } from '@rsm/allfarblori';
    import initPhotoswipe from '../../../javascripts/utils/photoswipe';
    
    export default class Gallery {
      constructor($el, options) {
        this.$el = $el;
        this.$slidesFrame = this.$el.querySelector('.gallery__slides-frame');
        this.$slidesContainer = this.$el.querySelector('.gallery__slider');
        this.$slides = this.$el.querySelectorAll('.gallery__slider-item');
        this.$galleryButton = this.$el.querySelector('.gallery__button');
    
        // Bring in the options
        this.options = {
          ...options,
        };
    
        // Don't init slider, if only one slide exists
        if (this.$slides.length === 1) {
          return;
        }
    
        this.constructGallery();
      }
    
      deconstructor() {
        if (this.lory) {
          this.lory.destroy();
        }
      }
    
      constructGallery() {
        this.$el.addEventListener('before.lory.init', () => {
          this.$slidesContainer.scrollLeft = 0;
        });
    
        this.$el.addEventListener('after.lory.init', () => {
          this.$el.classList.add('slider--initialized');
          if (this.$galleryButton) {
            this.$galleryButtonText = this.$galleryButton.querySelector('.button__text');
            this.$galleryButtonText.innerHTML = `${this.$slides.length} ${this.$galleryButtonText.innerHTML}`;
          }
        });
    
        // this.$el.addEventListener('on.lory.resize', () => {
        //   this.positionGalleryButton();
        // });
    
        this.lory = lory(this.$el, {
          rewind: true,
          rewindPrev: true,
          rewindSpeed: 200,
          slideSpeed: 350,
          ease: 'cubic-bezier(0.455, 0.03, 0.515, 0.955)',
          classNameFrame: 'gallery__slides-frame',
          classNameSlideContainer: 'gallery__slider',
        });
    
        // this.positionGalleryButton();
      }
    
      // positionGalleryButton() {
      // const $activeItemMedia = this.$el.querySelector('picture img');
      // const activeMediaHeight = $activeItemMedia.offsetHeight;
      // const buttonHeight = this.$galleryButton.offsetHeight;
      // this.$galleryButton.style.top = `${activeMediaHeight - buttonHeight}px`;
      // }
    }
    
    // Trigger Gallery by Breakpoint
    // const mql = [
    //   window.matchMedia('(min-width: 480px)'),
    //   window.matchMedia('(min-width: 768px)'),
    //   window.matchMedia('(min-width: 1203px)'),
    // ];
    
    let componentStore = [];
    
    export function onMediaQueryChange() {
      componentStore.forEach(component => component.deconstructor && component.deconstructor());
      componentStore = [];
    
      document
        .querySelectorAll('.gallery')
        .forEach(($gallery) => {
          componentStore.push(new Gallery($gallery, {
            sizerTarget: 'figure__media',
          }));
    
          initPhotoswipe(Array.prototype.slice.call($gallery.querySelectorAll('.js-lightbox')));
    
          const $galleryButton = $gallery.querySelector('.gallery__button');
          if ($galleryButton) {
            $galleryButton.addEventListener('click', () => {
              const $lightboxEl = $gallery.querySelector('.gallery__slider-item .js-lightbox');
              if ($lightboxEl) {
                const evt = new MouseEvent('click', {
                  bubbles: true,
                  cancelable: true,
                  view: window,
                });
                $lightboxEl.dispatchEvent(evt);
              }
            });
          }
        });
    }
    
    // mql.forEach(((el) => {
    //   el.addListener(onMediaQueryChange);
    // }));
    
    document.addEventListener('DOMContentLoaded', () => {
      onMediaQueryChange();
    }, false);
    
  • URL: /components/raw/gallery/gallery.js
  • Filesystem Path: src/components/molecules/gallery/gallery.js
  • Size: 3.3 KB
  • Content:
    .gallery {
      position: relative;
    }
    
    .gallery__slides-frame {
      flex-shrink: 0;
      position: relative;
      width: 100%;
    }
    
    .gallery__slider {
      display: flex;
      transition-property: transform;
    }
    
    .gallery__slider-item {
      flex: 1 0 100%;
    
      &:not(:first-child) {
        @include hidden-visually();
        /* stylelint-disable-next-line max-nesting-depth */
        .figure__lightbox-button {
          @include hidden-visually();
        }
      }
    
      .figure__caption {
        font-variation-settings: 'wght' $font-weight-bold;
        font-weight: $font-weight-bold;
      }
    }
    
    .gallery__button {
      height: 5.2rem;
      left: 1.5rem;
      position: absolute;
      top: 1.5rem;
      width: auto;
    
      .icon {
        pointer-events: none;
      }
    
      .icon--gallery {
        opacity: 1;
      }
    }
    
    .pswp__bg {
      background-color: $color-dark;
    }
    
    .pswp__button:not(.pswp__button--close) {
      @include mq($from: m) {
        background-color: transparent !important;
        border-radius: 0;
        color: #fff;
      }
    }
    
    .pswp__counter {
      font-size: 1.7rem;
      margin-left: 2rem;
      margin-top: 0.5rem;
    }
    
    .pswp__button--close {
      margin-right: 2rem;
      margin-top: 2rem;
    
      .icon {
        height: 4rem;
        width: 4rem;
      }
    
      .pswp__button-title {
        display: none;
      }
    }
    
    .pswp__caption .text {
      display: block;
      font-size: 1.7rem;
      font-weight: $font-weight-normal;
      line-height: calc(2.8 / 1.7);
      margin: 0 auto;
      max-width: 83rem;
    }
    
    // stylelint-disable
    @include mq($until: m) {
      .pswp__button--arrow--right,
      .pswp__button--arrow--left {
        display: none;
      }
    }
    // stylelint-enable
    
  • URL: /components/raw/gallery/gallery.scss
  • Filesystem Path: src/components/molecules/gallery/gallery.scss
  • Size: 1.5 KB

Image Sizes

default: 682 * 384, ratio 16 / 9

>768: 1144 * 644, ratio 16 / 9

>1260: 1046 * 588, ratio 16 / 9