Vanilla JS · Zero Dependencies

TGLightbox

A lightweight, customizable lightbox plugin for images, videos, iframes, and inline HTML. Inspired by FancyBox.

Everything you need

Full-featured lightbox with zero dependencies. Just drop in the CSS and JS.

Multiple Content Types
Images, YouTube, Vimeo, HTML5 video, iframes, inline HTML, and Ajax content.
Touch & Swipe
Native touch gestures for swiping between slides, pinch-to-zoom, and drag-to-close.
Zoom
Click-to-zoom with mouse wheel support, pinch-to-zoom on touch devices, and pan.
Custom Icons
Replace any icon with Font Awesome, custom images, SVG, or unicode characters.
🎨
Theming
Full CSS custom properties support. Every color, size, and timing is configurable.
Events
Lifecycle events: onInit, onOpen, onChange, onLoad, onError, onClose, and more.
Keyboard Navigation
Arrow keys, Escape, +/- for zoom, F for fullscreen. Full keyboard accessibility.
📷
Thumbnails
Optional thumbnail strip for quick navigation through galleries.
Responsive
Mobile-first design that adapts to any screen size. Touch-optimized controls.

Try it out

Click any card below to open the lightbox. Each demo showcases a different content type.

Inline HTML Inline Carousel (Swiper-compatible)

Up and running in seconds

Step 1: Add files
<!-- CSS -->
<link rel="stylesheet" href="css/tglightbox.css">

<!-- JS -->
<script src="js/tglightbox.js"></script>
Step 2: Create links
<a data-tglb="gallery" href="large.jpg" data-caption="Photo 1">
  <img src="thumb.jpg" alt="Photo 1">
</a>

<a data-tglb="gallery" href="large2.jpg" data-caption="Photo 2">
  <img src="thumb2.jpg" alt="Photo 2">
</a>
Step 3: Initialize
// Declarative — binds click handlers to all matching elements
TGLightbox.bind('[data-tglb]');

// Programmatic — open from JavaScript
TGLightbox.show([
  { src: 'image.jpg', caption: 'Photo 1' },
  { src: 'https://youtube.com/watch?v=xyz', type: 'youtube' },
  { src: 'video.mp4', type: 'video' },
  { src: 'https://example.com', type: 'iframe' },
  { src: '#my-element', type: 'inline' },
  { src: '/api/data', type: 'ajax' },
], { loop: true, thumbnails: true });

Full documentation

Option Type Default Description
groupAll boolean false Merge all matching triggers into a single gallery, regardless of data-tglb value.
startIndex number 0 Which slide to start on when opening.
preload number 2 Number of adjacent slides to preload.
keyboard boolean true Enable keyboard navigation (arrows, Escape, +/-, F).
dragToClose boolean true Drag down to close on touch devices.
clickOutsideClose boolean true Click on overlay to close.
loop boolean true Infinite carousel loop.
wheel boolean true Mouse wheel to navigate slides.
zoom boolean true Enable zoom functionality.
zoomMax number 3 Maximum zoom level.
zoomStep number 0.5 Zoom increment per step.
toolbar boolean true Show the toolbar (zoom, fullscreen, close).
thumbnails boolean false Show thumbnail strip at the bottom.
closeButton boolean true Show the close button in the toolbar.
fullscreen boolean true Show the fullscreen button.
icons object {} Custom icons for buttons. See Icons tab.
animationDuration number 300 Animation duration in milliseconds.
mainClass string '' Extra CSS class added to the overlay element.
on object {} Event callbacks. See Events tab.
Event Callback Arguments Description
onInit (instance) Fired when the instance is created and DOM is ready.
onOpen (instance, slide) Fired when the lightbox begins opening. Return false to block.
onOpened (instance, slide) Fired after the open animation completes.
onChange (instance, newSlide, prevSlide) Fired when slide changes. Return false to block.
onChanged (instance, slide) Fired after slide change animation completes.
onLoad (instance, slide) Fired when content finishes loading.
onError (instance, slide, error) Fired when content fails to load.
onZoom (instance, slide, zoomLevel) Fired when zoom level changes.
onClose (instance) Fired when the lightbox begins closing. Return false to block.
onClosed (instance) Fired after the close animation completes.
onFullscreen (instance, isFullscreen) Fired when fullscreen is toggled.
onSwipe (instance, direction) Fired when a swipe gesture is detected.
Event Example
TGLightbox.bind('[data-tglb]', {
  on: {
    open: (instance, slide) => {
      console.log('Opened:', slide.src);
    },
    change: (instance, newSlide, prevSlide) => {
      console.log('Changed to:', newSlide.index);
    },
    close: (instance) => {
      console.log('Closing lightbox');
    },
  },
});
Method Arguments Description
TGLightbox.bind() (selector, options) Bind click handlers to all elements matching the selector.
TGLightbox.show() (slides, options) Create and open a new lightbox instance programmatically.
TGLightbox.close() () Close the topmost active instance.
TGLightbox.destroy() () Destroy all instances and clean up event listeners.
TGLightbox.getInstance() () Get the topmost active instance reference.
instance.next() () Navigate to the next slide.
instance.prev() () Navigate to the previous slide.
instance.jumpTo() (index) Jump to a specific slide by index.
instance.close() () Close this instance.
instance.on() (event, handler) Subscribe to an event on this instance.
instance.off() (event, handler) Unsubscribe from an event.
instance.zoomIn() () Zoom in by one step.
instance.zoomOut() () Zoom out by one step.
instance.resetZoom() () Reset zoom to 1x.
instance.toggleFullscreen() () Toggle fullscreen mode.

Every button icon can be customized. Pass a string to the icons option — it can be a CSS class (Font Awesome), raw HTML (image/SVG), or a unicode character.

Font Awesome icons
TGLightbox.bind('[data-tglb]', {
  icons: {
    close: 'fas fa-times',
    prev:  'fas fa-chevron-left',
    next:  'fas fa-chevron-right',
    zoomIn: 'fas fa-search-plus',
    zoomOut: 'fas fa-search-minus',
    fullscreen: 'fas fa-expand',
  },
});
Custom image icons
TGLightbox.bind('[data-tglb]', {
  icons: {
    close: '<img src="icons/close.svg" alt="Close">',
    prev:  '<img src="icons/prev.svg" alt="Previous">',
    next:  '<img src="icons/next.svg" alt="Next">',
  },
});
Unicode / emoji icons
TGLightbox.bind('[data-tglb]', {
  icons: {
    close: '×',
    prev:  '←',
    next:  '→',
    zoomIn: '+',
    zoomOut: '−',
  },
});
Icon Key Button Default
close Close button (top right) × (CSS pseudo-element)
prev Previous arrow (left side) ‹ (CSS pseudo-element)
next Next arrow (right side) › (CSS pseudo-element)
zoomIn Zoom in button (toolbar) + (CSS pseudo-element)
zoomOut Zoom out button (toolbar) − (CSS pseudo-element)
fullscreen Fullscreen toggle (toolbar) ⤢ (CSS pseudo-element)
play Video play button overlay ▶ (CSS pseudo-element)

All visual properties are controlled via CSS custom properties. Override them in your stylesheet to match your design.

Variable Default Description
--tglb-bg rgba(0, 0, 0, 0.92) Overlay background color
--tglb-border-radius 8px Border radius for content and buttons
--tglb-toolbar-bg rgba(0, 0, 0, 0.6) Toolbar button background
--tglb-caption-color #fff Caption text color
--tglb-caption-bg rgba(0, 0, 0, 0.65) Caption background
--tglb-caption-font-size 14px Caption text size
--tglb-transition-duration 0.3s Animation speed
--tglb-transition-easing cubic-bezier(0.4, 0, 0.2, 1) Animation timing function
--tglb-z-index 9999 Overlay z-index
--tglb-icon-size 44px Toolbar button size
--tglb-icon-color #fff Icon color
--tglb-thumb-size 60px Thumbnail dimensions
--tglb-thumb-gap 6px Space between thumbnails
--tglb-thumb-active-border #fff Active thumbnail border color
--tglb-overlay-blur 8px Backdrop blur amount
--tglb-spinner-color rgba(255, 255, 255, 0.8) Loading spinner color
Custom theme example
:root {
  --tglb-bg: rgba(10, 10, 30, 0.95);
  --tglb-border-radius: 12px;
  --tglb-icon-color: #60a5fa;
  --tglb-caption-bg: rgba(10, 10, 30, 0.8);
  --tglb-thumb-active-border: #60a5fa;
  --tglb-overlay-blur: 12px;
}

Navigate with your keyboard

Key Action
Previous slide
Next slide
EscapeClose lightbox
+ / =Zoom in
-Zoom out
0Reset zoom
FToggle fullscreen