Image Gallery For Mobile Devices - PhotoSwipe

File Size: 926 KB
Views Total: 35068
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
Image Gallery For Mobile Devices - PhotoSwipe

PhotoSwipe is a Vanilla JavaScript Image Gallery designed for both Mobile and Touch Devices.

It provides your visitors with a familiar and intuitive interface allowing them to interact with images on your mobile website.

Installation & Download:

$ npm install photoswipe --save

How to use it:

1. Include the PhotoSwipe's core JavaScript and UI library on the webpage.

<script src="/path/to/photoswipe.min.js"></script> 
<script src="/path/to/photoswipe-ui-default.min.js"></script> 

2. Include the PhotoSwipe's core stylesheet and a theme CSS of your choice on the webpage.

<link rel="stylesheet" href="/path/to/photoswipe.css"> 
<link rel="stylesheet" href="/path/to/default-skin/default-skin.css"> 

3. Create the HTML template for the Photoswipe.

<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

  <!-- Background of PhotoSwipe. 
       It's a separate element as animating opacity is faster than rgba(). -->
  <div class="pswp__bg"></div>

  <!-- Slides wrapper with overflow:hidden. -->
  <div class="pswp__scroll-wrap">

      <!-- Container that holds slides. 
          PhotoSwipe keeps only 3 of them in the DOM to save memory.
          Don't modify these 3 pswp__item elements, data is added later on. -->
      <div class="pswp__container">
          <div class="pswp__item"></div>
          <div class="pswp__item"></div>
          <div class="pswp__item"></div>

      <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
      <div class="pswp__ui pswp__ui--hidden">

          <div class="pswp__top-bar">

              <!--  Controls are self-explanatory. Order can be changed. -->

              <div class="pswp__counter"></div>

              <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

              <button class="pswp__button pswp__button--share" title="Share"></button>

              <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

              <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

              <!-- Preloader demo -->
              <!-- element will get class pswp__preloader--active when preloader is running -->
              <div class="pswp__preloader">
                  <div class="pswp__preloader__icn">
                    <div class="pswp__preloader__cut">
                      <div class="pswp__preloader__donut"></div>

          <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
              <div class="pswp__share-tooltip"></div> 

          <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">

          <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">

          <div class="pswp__caption">
              <div class="pswp__caption__center"></div>




4. Initialize the PhotoSwipe.

var pswpElement = document.querySelectorAll('.pswp')[0];

// build items array
var items = [
        src: '',
        w: 600,
        h: 400
        src: '',
        w: 1200,
        h: 900

// define options (if needed)
var options = {
    // optionName: 'option value'
    // for example:
    index: 0 // start at first slide

// Initializes and opens PhotoSwipe
var gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options);

5. Available configuration options


  // allow swipe navigation to next/prev item

  // Spacing ratio between slides
  spacing: 0.12,

  // opacity of background
  bgOpacity: 1,

  // predefine if mouse was used or not
  mouseUsed: false,

  // infinite loop
  loop: true,

  // pinch to close
  pinchToClose: true,

  // close on scroll
  closeOnScroll: true,

  // close on vertical drag
  closeOnVerticalDrag: true,

  // vertical drag range
  verticalDragRange: 0.75,

  // duration of animation
  hideAnimationDuration: 333,
  showAnimationDuration: 333,

  // enable/disable show/hide opacity
  showHideOpacity: false,

  // auto set focus on element
  focus: true,

  // ESC to close
  escKey: true,

  // enable arrow keys
  arrowKeys: true,

  // Trap focus within PhotoSwipe element while it's open.
  trapFocus: true,

  // main scroll end friction
  mainScrollEndFriction: 0.35,

  // pan end friction
  panEndFriction: 0.35,

  // function
  isClickableElement: function(el) {
    return el.tagName === 'A';

  // function
  getDoubleTapZoom: function(isMouseClick, item) {
    if(isMouseClick) {
      return 1;
    } else {
      return item.initialZoomLevel < 0.7 ? 1 : 1.33;

  // max spread zoom
  maxSpreadZoom: 1.33,

  // modal mode
  modal: true


6. Default UI options.


  // Size of top & bottom bars in pixels,
  // "bottom" parameter can be 'auto' (will calculate height of caption)
  // option applies only when mouse is used, 
  // or width of screen is more than 1200px
  // (Also refer to `parseVerticalMargin` event)
  barsSize: {top:44, bottom:'auto'}, 

  // Adds class pswp__ui--idle to pswp__ui element when mouse isn't moving for 4000ms
  timeToIdle: 4000,

  // Same as above, but this timer applies when mouse leaves the window
  timeToIdleOutside: 1000,

  // Delay until loading indicator is displayed
  loadingIndicatorDelay: 1000,

  // Function builds caption markup
  addCaptionHTMLFn: function(item, captionEl, isFake) {
    // item      - slide object
    // captionEl - caption DOM element
    // isFake    - true when content is added to fake caption container
    //             (used to get size of next or previous caption)

    if(!item.title) {
        captionEl.children[0].innerHTML = '';
        return false;
    captionEl.children[0].innerHTML = item.title;
    return true;

  // Buttons/elements
  captionEl: true,
  fullscreenEl: true,
  zoomEl: true,
  shareEl: true,
  counterEl: true,
  arrowEl: true,
  preloaderEl: true,

  // Tap on sliding area should close gallery
  tapToClose: false,

  // Tap should toggle visibility of controls
  tapToToggleControls: true,

  // Mouse click on image should close the gallery,
  // only when image is smaller than size of the viewport
  clickToCloseNonZoomable: true,

  // Element classes click on which should close the PhotoSwipe.
  // In HTML markup, class should always start with "pswp__", e.g.: "pswp__item", "pswp__caption".
  // "pswp__ui--over-close" class will be added to root element of UI when mouse is over one of these elements
  // By default it's used to highlight the close button.
  closeElClasses: ['item', 'caption', 'zoom-wrap', 'ui', 'top-bar'], 

  // Separator for "1 of X" counter
  indexIndicatorSep: ' / ',

  // Share buttons
  // Available variables for URL:
  // {{url}}             - url to current page
  // {{text}}            - title
  // {{image_url}}       - encoded image url
  // {{raw_image_url}}   - raw image url
  shareButtons: [
    {id:'facebook', label:'Share on Facebook', url:'{{url}}'},
    {id:'twitter', label:'Tweet', url:'{{text}}&url={{url}}'},
    {id:'pinterest', label:'Pin it', url:'{{url}}&media={{image_url}}&description={{text}}'},
    {id:'download', label:'Download image', url:'{{raw_image_url}}', download:true}

  // Next 3 functions return data for share links
  // functions are triggered after click on button that opens share modal,
  // which means that data should be about current (active) slide
  getImageURLForShare: function( shareButtonData ) {
    // `shareButtonData` - object from shareButtons array
    // `pswp` is the gallery instance object,
    // you should define it by yourself
    return pswp.currItem.src || '';
  getPageURLForShare: function( shareButtonData ) {
    return window.location.href;
  getTextForShare: function( shareButtonData ) {
    return pswp.currItem.title || '';

  // Parse output of share links
  parseShareButtonOut: function(shareButtonData, shareButtonOut) {
    // `shareButtonData` - object from shareButtons array
    // `shareButtonOut` - raw string of share link element
    return shareButtonOut;


v5.4.2 (2023-09-30)

  • dataSource param is now optional for PhotoSwipeLightbox.loadAndOpen method, the first gallery is chosen if it's not provided.

v5.4.1 (2023-09-18)

  • Added trapFocus option (by default PhotoSwipe traps tab focus within the dialog, this option allows disabling the functionality)
  • Added preventPointerEvent filter (by default PhotoSwipe calls e.preventDefault() during pointer-move events, this filter allows you to disable it over certain elements)

v5.4.0 (2023-09-08)

  • Fix: lower version browsers do not support nullish-coalescing syntax

v5.3.9 (2023-09-03)

  • fix: lower version browsers do not support optional chain syntax

v5.3.8 (2023-07-03)

  • Removed navigator.onLine check so the gallery can be used while offline

v5.3.7 (2023-03-29)

  • Bugfix

v5.3.6 (2023-02-27)

  • Fixed an issue that caused lazy-loading of the full image (from src) rather than srcset. This problem was caused by the prev release (5.3.5).
  • Use classList.toggle where possible

v5.3.5 (2023-02-01)

  • Bugfixes

v5.3.4 (2022-11-22)

  • Check if element exists before applying aria attributes

v5.3.0 (2022-10-25)

  • Fixed bugs.

v5.3.0 (2022-07-23)

  • Adjust zoomed-in class behaviour to reflect toggleZoom method

v5.2.2 (2022-03-28)

  • Code quality and rewrite in ES6
  • Simpler initialization and dynamic import support
  • Animation and gesture engine update
  • Single CSS file and no external assets
  • Built-in responsive images support
  • Open images in zoomed state
  • Removed some features from the core
  • Doc update (TBD)

v4.1.3 (2019-01-09)

  • This minor patch fixes issue with devices that have multiple types on input, running Windows 10 and Chrome.


  • Fix iOS 10.3 resize bug


  • Fix iOS 10.3 resize bug

This awesome jQuery plugin is developed by dimsemenov. For more Advanced Usages, please check the demo page or visit the official website.