popupable

A lightweight, zero-dependency lightbox library using modern JavaScript and CSS.

Just add data-popupable to any image!

Features

  • No dependencies
  • Animates open from the element's original position
  • Works with mouse, touch, and keyboard
  • Gallery groups with swipe, scroll, keyboard, and button navigation
  • Thumbnail strip and image counter
  • Pinch-to-zoom on touch, with optional click/tap-to-zoom support
  • Load a hi-res image on open
  • Checkerboard background for transparent images
  • Customizable via CSS variables

Basic Usage

Add data-popupable to any image. Click an image to open it:

<img src="photo.jpg" data-popupable>

Title & Description

Add data-popupable-title and data-popupable-description to show text alongside the opened image:

<img src="photo.jpg" data-popupable
     data-popupable-title="Mountain Lake"
     data-popupable-description="A serene lake nestled in the mountains">

Hi-res Source

Use data-popupable-src to show a higher resolution image when opened. The thumbnail loads quickly, and the full image is revealed when expanded:

<img src="thumbnail.jpg" data-popupable
     data-popupable-src="full-res.jpg">

Zoom

All images support pinch-to-zoom on touch. Add data-popupable-zoomable to also enable click/tap-to-zoom and scroll wheel zoom. When zoomed, pan by dragging:

<img src="photo.jpg" data-popupable data-popupable-zoomable>

Transparent Images

Add data-popupable-transparent to show a checkerboard pattern behind transparent areas:

<img src="icon.png" data-popupable data-popupable-transparent>

Aspect Ratio

By default, the popup size is based on the image's natural dimensions. Add data-popupable-maintain-aspect to use the element's rendered aspect ratio instead — useful when the image is cropped or stretched via CSS. Toggle the checkbox to see the difference:

Cover (cropped)
Contain (bounds visible)
Stretch (distorted)
<img src="photo.jpg" data-popupable data-popupable-maintain-aspect>

Gallery Groups

Group images with data-popupable-group. Navigate with arrow buttons, swipe, scroll wheel, or keyboard arrows. Add data-popupable-counter and data-popupable-thumbnails to each image for a counter and thumbnail strip:

<img src="photo1.jpg" data-popupable data-popupable-group="gallery"
     data-popupable-counter data-popupable-thumbnails>
<img src="photo2.jpg" data-popupable data-popupable-group="gallery"
     data-popupable-counter data-popupable-thumbnails>

Unique IDs

Set a value on data-popupable to give the popup a CSS id. In a gallery, the id updates as you navigate, so each image can have its own backdrop colour:

<img src="photo.jpg" data-popupable="gallery2-1" data-popupable-group="gallery2">
<img src="photo.jpg" data-popupable="gallery2-2" data-popupable-group="gallery2">
<img src="photo.jpg" data-popupable="gallery2-3" data-popupable-group="gallery2">
<img src="photo.jpg" data-popupable="gallery2-4" data-popupable-group="gallery2">

<style>
  #gallery2-1.popupable-active { background: #0A4446BB; }
  #gallery2-2.popupable-active { background: #877E75BB; }
  #gallery2-3.popupable-active { background: #45511FBB; }
  #gallery2-4.popupable-active { background: #A00D3CBB; }
</style>

Customization Variables

Fine-tune the popup appearance with CSS variables:

<style>
  :root {
    --popupable-background: #000B;     /* Backdrop color */
    --popupable-blur: 6px;             /* Backdrop blur amount */
    --popupable-ui-background: #0008;  /* Header, footer, and button background */
    --popupable-screen-padding: 40px;  /* Gap between image and viewport edge */
    --popupable-open-duration: .25s;   /* Open/close transition duration */
    --popupable-switch-duration: .25s; /* Gallery navigation transition duration */
  }
</style>