Skip to content

A dynamic caption plugin for PhotoSwipe v5. Automatically positions the caption aside or below the image.

License

Notifications You must be signed in to change notification settings

dimsemenov/photoswipe-dynamic-caption-plugin

Repository files navigation

Dynamic caption plugin for PhotoSwipe v5

> Plugin demo <

The plugin can automatically position the text below or aside depending on the available space. For small to medium-sized captions. And only for images with the default fit scale mode.

For accessibility, make sure that important captions are always available without PhotoSwipe - either use an alt attribute on thumbnails or aria-labelledby.

Initialization

The plugin has a single JS file photoswipe-dynamic-caption-plugin.esm.js (UMD version is in the dist/ folder) and a single CSS file photoswipe-dynamic-caption-plugin.css. Include them directly or via npm:

npm i photoswipe-dynamic-caption-plugin --save

It can be initialized like this:

<script type="module">
import PhotoSwipeLightbox from 'photoswipe/dist/photoswipe-lightbox.esm.js';
// or 'photoswipe-dynamic-caption-plugin' if using package manager
import PhotoSwipeDynamicCaption from 'https://unpkg.com/photoswipe-dynamic-caption-plugin/photoswipe-dynamic-caption-plugin.esm.js';

const lightbox = new PhotoSwipeLightbox({
  gallerySelector: '#gallery',
  childSelector: '.pswp-gallery__item',
  pswpModule: () => import('photoswipe/dist/photoswipe.esm.js'),

  // Optional padding for images,
  // note that this is an option of PhotoSwipe, not a plugin
  paddingFn: (viewportSize) => {
    return {
      top: 30, bottom: 30, left: 70, right: 70
    }
  },
});

const captionPlugin = new PhotoSwipeDynamicCaption(lightbox, {
  // Plugins options, for example:
  type: 'auto',
});

// make sure you init photoswipe core after plugins are added
lightbox.init();
</script>
<link rel="stylesheet" href="https://unpkg.com/photoswipe-dynamic-caption-plugin/photoswipe-dynamic-caption-plugin.css">

Also refer the source of the demo page - index.html.

Plugin options

captionContent: '.pswp-caption-content'

Used to retrieve caption content.

Can be a selector of the element from which caption content will be retrieved, if the element is not found - the plugin will try to use the thumbnail image alt attribute.

<a href="path/to/large-image.jpg" data-pswp-width="1024" data-pswp-height="768">
  <img src="path/to/thumbnail.jpg" alt="" />
  <span class="pswp-caption-content">Caption content</span>
</a>

Or a function that should return caption content. For example:

captionContent: (slide) => {
  return slide.data.element.querySelector('img').getAttribute('alt');
}

type: 'auto'

Position type of the caption can be 'auto', 'below', or 'aside'.

  • 'below' - caption will always be placed below the image
  • 'aside' - caption will always be placed on the right side of the image
  • 'auto' - the plugin will try to automatically determine the best position (depending on available space)

mobileLayoutBreakpoint: 600

Maximum window width at which mobile layout should be used, or a function that should return true if mobile layout should be used. For example:

mobileLayoutBreakpoint: (pswp, captionPlugin) => {
  return (window.innerWidth < 750);
}

horizontalEdgeThreshold: 20

When the caption x position is less than this value, it'll get class pswp__dynamic-caption--on-hor-edge. You may use it to apply different styling, such as horizontal padding.

mobileCaptionOverlapRatio: 0.3

A ratio defines the amount of horizontal empty space before the mobile caption switches to an "overlap" layout. For example, if it's set to 0.3 - the caption will start overlapping the image when more than 30% of horizontal space is not occupied by an image. If you set it to 0 - the caption will always overlap. If you set it to 1 - the caption will constantly shift the image (unless it's taller than the viewport).

verticallyCenterImage: false

If enabled, the image will always be vertically centered in the remaining space between the caption and the rest of the viewport. If set to false (default value) - the image will lift up only if the caption does not fit below.

Styling

The caption has class pswp__dynamic-caption.

It can be in one of these states:

  • Below the main image - pswp__dynamic-caption--below.
  • Right side of the main image - pswp__dynamic-caption--aside.
  • "Mobile" (by default just pinned to bottom) - pswp__dynamic-caption--mobile

If the caption is near the left horizontal edge - it gets class pswp__dynamic-caption--on-hor-edge.

Feel free to adjust styles in the plugin CSS file (and use media queries if you need to):

.pswp__dynamic-caption--aside {
  max-width: 300px;
  padding: 20px 15px 20px 20px;
  margin-top: 70px;
}
.pswp__dynamic-caption--below {
  max-width: 700px;
  padding: 15px 0 0;
}
.pswp__dynamic-caption--mobile {
  background: rgba(0, 0, 0, 0.5);
  padding: 10px 15px;
}

How 'auto' positioning works

  • Check if there is more horizontal or vertical free space around the image.
  • If there is more free vertical space:
    • Set caption width to the width of the image
    • Add pswp__dynamic-caption--below class, so the size can also be adjusted via CSS.
    • Measure caption height.
    • Check if the caption will fit without any adjustments to the image position.
      • If it does - just show the caption below the image.
      • If it doesn't - reduce the pan area height by the height of the caption.
  • If there is more horizontal space:
    • Add pswp__dynamic-caption--aside class, so the size can be adjusted via CSS.
    • Measure caption width.
    • Check if caption will fit on the right side without any adjustments of image position.
      • If it does - just show the caption aside from the image.
      • If it doesn't - reduce the pan area width by the width of the caption.

If mobileLayoutBreakpoint requirements are met:

  • Measure caption height when it occupies 100% of width.
  • Reduce pan area height to fit the caption below the image.
  • Check the amount of free horizontal space after the adjustment.
  • If there is too much horizontal space (mobileCaptionOverlapRatio) - just overlap the caption and keep the image at the default position.

Changelog

1.2.0

  • Requires PhotoSwipe 5.3.0.
  • Caption now moves with the slide when dragged (instead of fading in and out).
  • Each slide now has a separate DOM element (before there was only a single caption element that changed content).
  • No longer uses temporary caption to measure size.
  • You may now access caption and its data via dynamicCaption property of a slide. For example pswp.currSlide.dynamicCaption.

1.1.0

  • No longer adjusts main image padding. If you need to dynamically change padding based on the screen size - use PhotoSwipe option paddingFn (introduced in 5.1.61)
  • Caption receives class pswp__dynamic-caption--on-hor-edge when it's on horizontal edge (x position is less than threshold). Added option horizontalEdgeThreshold to control this.
  • Reworked mobile layout. Now the caption tries to not overlap the main image if there is an empty space below. Added option mobileCaptionOverlapRatio to control this.