PhotoSwipe Documentation

website·Indexed 36 days ago

https://photoswipe.com

A JavaScript image gallery library featuring a lightbox with zoom, pan, and transition effects. Documentation covers initialization, configuration options like bgOpacity and zoom levels, API methods for PhotoSwipeLightbox, event binding, and integration examples for React, Vue, and Svelte.

Tokens
15.3K
Snippets
81
Records
90
Agent score
70%

What's inside PhotoSwipe

  1. Customize the content error element

    The contentErrorElement filter allows you to define a custom DOM element to display when content fails to load (e.g., a broken image link).
    import PhotoSwipeLightbox from '/photoswipe/photoswipe-lightbox.esm.js';
    
    const lightbox = new PhotoSwipeLightbox({
      gallery: '#gallery--content-error-element',
      children: 'a',
      pswpModule: () => import('/photoswipe/photoswipe.esm.js')
    });
    
    lightbox.addFilter('contentErrorElement', (contentErrorElement, content) => {
      const el = document.createElement('div');
      el.className = 'pswp__error-msg';
      el.innerHTML = `<a href="${content.data.src}" target="_blank">The image #${content.slide.index + 1}</a> cannot be loaded</a>`;
      return el;
    });
    
    lightbox.init();
  2. Add a custom last slide to a gallery

    To append a custom slide (like an HTML slide) to the end of a gallery, increment the total count using the numItems filter and return the custom data in the itemData filter when the index matches the last item.
    lightbox.addFilter('numItems', (numItems) => {
      return ++numItems;
    });
    
    lightbox.addFilter('itemData', (itemData, index) => {
      if (index === lightbox.getNumItems() - 1) {
        return {
          html: '<div class="custom-html-slide">Custom Last Slide</div>',
        };
      }
      return itemData;
    });
  3. Hide overlapping elements during PhotoSwipe transitions

    To prevent UI elements (such as fixed headers, sharing icons, or carousel arrows) from interfering with the opening or closing transitions in PhotoSwipe, you can use a CSS class to toggle their visibility. By applying a class like .badge--hidden that sets opacity: 0, you can smoothly hide these elements during the animation process.
    .badge {
      position: absolute;
      bottom: 5px;
      left: 5px;
      padding: 5px;
      color: #FFF;
      background: rgba(0,0,0,0.5);
      line-height: 1;
      transition: opacity 100ms linear;
      font-size: 16px;
      font-weight: normal;
    }
    
    .badge--hidden {
      opacity: 0;
    }
  4. Initialize PhotoSwipe v6 using ES modules

    PhotoSwipe v6 is composed of three parts: the Core (photoswipe.esm.js), the Lightbox (photoswipe-lightbox.esm.js), and the CSS (photoswipe.css). The recommended approach is to use a module script to dynamically load the Core only when needed, reducing the initial bundle size.
    <link rel="stylesheet" href="photoswipe/dist/photoswipe.css">
    
    <script type="module">
    import PhotoSwipeLightbox from 'photoswipe/dist/photoswipe-lightbox.esm.js';
    
    const lightbox = new PhotoSwipeLightbox({
      gallery: '#my-gallery',
      children: 'a',
      pswpModule: () => import('photoswipe/dist/photoswipe.esm.js')
    });
    lightbox.init();
    </script>
  5. Modify slide item data using the itemData filter

    The itemData filter allows you to modify the data associated with a specific slide. It provides the current item data and the slide index.
    lightbox.addFilter('itemData', (itemData, index) => {
      return itemData;
    });
  6. Implement a custom caption in PhotoSwipe

    PhotoSwipe does not support captions natively. You can implement a basic caption by using the uiRegister event to register a custom UI element. This element can be dynamically updated during the change event to pull text from a hidden element (e.g., .hidden-caption-content) or from the image's alt attribute.

    Accessibility Note: Ensure captions are accessible to screen reader users outside of the lightbox (e.g., using alt attributes, aria-labelledby, or <figcaption> inside a <figure>), as the lightbox may be disabled in unsupported browsers.

    import PhotoSwipeLightbox from '/photoswipe/photoswipe-lightbox.esm.js';
    
    const options = {
      gallery:'#gallery--with-custom-caption',
      children:'.pswp-gallery__item',
      pswpModule: () => import('/photoswipe/photoswipe.esm.js')
    };
    const lightbox = new PhotoSwipeLightbox(options);
    
    lightbox.on('uiRegister', function() {
      lightbox.pswp.ui.registerElement({
        name: 'custom-caption',
        order: 9,
        isButton: false,
        appendTo: 'root',
        html: 'Caption text',
        onInit: (el, pswp) => {
          lightbox.pswp.on('change', () => {
            const currSlideElement = lightbox.pswp.currSlide.data.element;
            let captionHTML = '';
            if (currSlideElement) {
              const hiddenCaption = currSlideElement.querySelector('.hidden-caption-content');
              if (hiddenCaption) {
                // get caption from element with class hidden-caption-content
                captionHTML = hiddenCaption.innerHTML;
              } else {
                // get caption from alt attribute
                captionHTML = currSlideElement.querySelector('img').getAttribute('alt');
              }
            }
            el.innerHTML = captionHTML || '';
          });
        }
      });
    });
    
    lightbox.init();
  7. Control pointer event prevention

    By default, PhotoSwipe calls preventDefault on pointermove (including touchmove and mousemove) to disable browser gestures and page scrolling. Use the preventPointerEvent filter to conditionally allow or prevent these events based on the event target or pointer type.
    lightbox.addFilter('preventPointerEvent', (preventPointerEvent, originalEvent, pointerType) => {
      // return true to preventDefault pointermove/pointerdown events
      return true;
    });
  8. Implement responsive images with srcset

    To support responsive images, use the data-pswp-srcset attribute. This attribute follows the standard native srcset syntax. You must still provide data-pswp-width and data-pswp-height based on the largest image size available in the set.
    <a href="image-large.jpg"
       data-pswp-srcset="image-small.jpg 500w, image-medium.jpg 1000w, image-large.jpg 2000w"
       data-pswp-width="2000"
       data-pswp-height="1500">
       <img src="thumbnail.jpg" alt="Responsive Image" />
    </a>
  9. PhotoSwipe v6 constraints and requirements

    When implementing PhotoSwipe v6, keep the following constraints in mind:

    • Image Dimensions: Predefined width and height must be provided for every image.
    • Image Size: Not designed for extremely large images; the maximum recommended size is 3000x3000px. For larger images, use the experimental tiling plugin.
    • Browser Support: Designed for modern browsers. It is recommended to provide a fallback (e.g., a direct link to the image) for progressive enhancement.
  10. Open images individually instead of as a gallery

    To prevent images from being grouped into a single gallery and instead open each image individually, set the gallery option to target the individual links directly.
    const lightbox = new PhotoSwipeLightbox({
      gallery: '#gallery--individual a',
      pswpModule: () => import('/photoswipe/photoswipe.esm.js')
    });
    lightbox.init();
  11. Register custom UI elements in PhotoSwipe

    To add interactive elements to the PhotoSwipe interface, use the pswp.ui.registerElement method. This method must be called within or after the uiRegister event. Custom elements can be buttons, indicators, or other HTML structures.
    lightbox.on('uiRegister', function() {
      lightbox.pswp.ui.registerElement({
        name: 'my-custom-element',
        // configuration options here
      });
    });
  12. Implement custom HTML content (e.g., Google Maps) in PhotoSwipe

    PhotoSwipe can be extended to show custom content types (like iframes) by using the data-pswp-type attribute on the anchor tag. You must use the itemData filter to capture custom data attributes and the contentLoad event to override the default image behavior and inject your custom HTML element.
    import PhotoSwipeLightbox from '/photoswipe/photoswipe-lightbox.esm.js';
    
    const lightbox = new PhotoSwipeLightbox({
      gallery: '#gallery--google-map-demo',
      children: 'a',
      pswpModule: () => import('/photoswipe/photoswipe.esm.js')
    });
    
    // Parse custom data attribute for the map URL
    lightbox.addFilter('itemData', (itemData, index) => {
      const googleMapUrl = itemData.element.dataset.googleMapUrl;
      if (googleMapUrl) {
        itemData.googleMapUrl = googleMapUrl;
      }
      return itemData;
    });
    
    // Override slide content for the 'google-map' type
    lightbox.on('contentLoad', (e) => {
        const { content } = e;
        if (content.type === 'google-map') {
          e.preventDefault();
    
          content.element = document.createElement('div');
          content.element.className = 'pswp__google-map-container';
    
          const iframe = document.createElement('iframe');
          iframe.setAttribute('allowfullscreen', '');
          iframe.src = content.data.googleMapUrl;
          content.element.appendChild(iframe);
        }
    });
    
    lightbox.init();

    <!-- HTML Example --> <a data-pswp-type="google-map" data-google-map-url="https://www.google.com/maps/embed?..." href="https://maps.google.com/..." target="_blank"> <img src="map-thumb.png" alt=""> </a>

    <!-- CSS Example --> <style> .pswp__google-map-container { position: relative; width: 100%; height: 100%; pointer-events: none; } .pswp__google-map-container iframe { background: #444; width: 100%; height: 100%; max-width: 800px; max-height: 600px; pointer-events: auto; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } </style>