Obsidium

A fully featured, dependency-free lightbox component for displaying image and text collections

Get started

Download the latest release from the releases page and include the library in your project:

<link rel="stylesheet" href="/obsidium/obsidium.css">
<script src="/obsidium/obsidium.js"></script>

Create a container with preview images and full-resolution sources:

<div id="obsidium-images">
    <img src="/preview/img1.jpg" data-src="/images/img1.jpg">
    <img src="/preview/img2.jpg" data-src="/images/img2.jpg">
    <img src="/preview/img3.jpg" data-src="/images/img3.jpg">
    <img src="/preview/img4.jpg" data-src="/images/img4.jpg">
</div>

Instantiate Obsidium and call init():

new Obsidium("obsidium-images").init()

That’s all — the lightbox is ready to use.

Initialization

Image elements

Option 1. Initialize the lightbox using <img> elements that provide a data-src attribute for the full-resolution image.

<div id="obsidium-images">
    <img src="/preview/img1.jpg" data-src="/images/img1.jpg">
    <img src="/preview/img2.jpg" data-src="/images/img2.jpg">
    <img src="/preview/img3.jpg" data-src="/images/img3.jpg">
    <img src="/preview/img4.jpg" data-src="/images/img4.jpg">
</div>
new Obsidium("obsidium-images").init()

Custom elements

Option 2. Use any HTML elements that expose data-preview and data-src attributes.

<div id="obsidium-custom">
    <span data-preview="/preview/img1.jpg" data-src="/images/img1.jpg">Link</span>
    <span data-preview="/preview/img2.jpg" data-src="/images/img2.jpg">Link</span>
    <span data-preview="/preview/img3.jpg" data-src="/images/img3.jpg">Link</span>
    <span data-preview="/preview/img4.jpg" data-src="/images/img4.jpg" data-title="Some title">Link</span>
</div>
new Obsidium("obsidium-custom", "span").init()
Open sunset Open coast Open forest Open road

Programmatic invocation

Option 3. Provide the image list programmatically and trigger the lightbox manually through any user interaction.

<button id="open-obsidium">Open</button>
const images = [
    { preview: "/preview/img1.jpg", src: "/images/img1.jpg" },
    { preview: "/preview/img2.jpg", src: "/images/img2.jpg" },
    { preview: "/preview/img3.jpg", src: "/images/img3.jpg" },
    { preview: "/preview/img4.jpg", src: "/images/img4.jpg" },
]

const obsidium = new Obsidium(images2).init()
document.getElementById('open-obsidium').addEventListener('click', () => obsidium.open())

Passing options

Additional configuration options can be passed to the init method to customize appearance and behavior.

new Obsidium("obsidium", images).init({
    animation: 'long-slide',
    theme: 'light'
})

Features

+ No dependencies Fully standalone, requires no external libraries.
+ Responsive Automatically adjusts to any device, orientation, or screen size.
+ Swipes Swipe left/right to navigate and swipe down to close.
+ Themes Supports light and dark themes.
+ Customization Fine-grained control over visuals and behavior.
+ Zoom levels Adjustable zoom levels via buttons or keyboard shortcuts.
+ Animations Multiple built-in transition animations.
+ Preloading Preloads the next two slides for smooth navigation.
+ Text content Supports HTML and plain text slides.
+ Thumbnails Thumbnail strip navigation.
+ Keyboard Full keyboard navigation and accessibility features.
+ EXIF Optional display of EXIF metadata when available.

Themes

Choose between the built-in dark (default) and light themes, or define a custom theme.

new Obsidium("obsidium", images).init({
    theme: 'light'
})

Customization

Most UI and behavior features can be individually enabled or disabled using init() options.

new Obsidium("obsidium", images).init({
    zoom: false,
    counter: false,
    preload: false,
    title: false,
    thumbnails: false,
    info: false,
    hide: false
})

Animations

obsidium.css includes only the default short-slide animation. Additional animations can be imported from the obsidium/animations directory.
Custom animations can be added by following the naming conventions.

<link rel="stylesheet" href="/obsidium/animations/flip.css">
new Obsidium("obsidium", images).init({
    animation: 'flip'
})

Thumbnails

Thumbnail size and spacing can be customized or disabled entirely.

new Obsidium("obsidium", images).init({
    thumbnailsSize: '7rem',
    thumbnailsGap: '0.5rem'
})

Text content

You can provide HTML or plain text as content slides.
The element option should reference the ID of an existing DOM node.

<div id="source" style="display: none">
    <p>The woods are lovely, dark and deep,<br>
    But I have promises to keep,<br>
    And miles to go before I sleep,<br>
    And miles to go before I sleep.</p>
</div>
const slides = [
    { "element": "source" }
    { "text": "Plain text content" }
]

new Obsidium("obsidium", slides).init({
    thumbnails: false,
    zoom: false
})

EXIF metadata

To enable EXIF extraction in the info panel, include the exifr library.
Ensure that image files are served from the same origin or have CORS properly configured.

<script src="https://cdn.jsdelivr.net/npm/exifr/dist/lite.umd.js"></script>

new Obsidium("obsidium", images).init()

Keyboard bindings

Right, Space Next slide
Left, Backspace Prev slide
Down / Up Hide/show interface

Escape Close
+ / - Zoom in/out
i Toggle the info panel

Options

zoom
Default: true (boolean)
Enables or disables zoom functionality.
zoomLevels
Default: [1.5, 2, 2.5, 3] (array)
List of zoom multipliers used for zoom-in steps.
counter
Default: true (boolean)
Displays the slide counter (e.g., 1 / 6)
preload
Default: true (boolean)
Preloads adjacent slides to enhance navigation responsiveness.
title
Default: true (boolean)
Displays the slide title below the image.
info
Default: true (boolean)
Enables the EXIF/info panel.
hide
Default: true (boolean)
Allows the interface (controls, overlays) to be hidden or shown.
loadExif
Default: true (boolean)
Allows EXIF loading from images using the exifr library.
thumbnails
Default: true (boolean)
Enables the thumbnail strip under the viewer.
thumbnailsSize
Default: "3rem" (string)
Defines the size of thumbnails (CSS unit).
thumbnailsGap
Default: "0.25rem" (string)
Defines spacing between thumbnails (CSS unit).
clickOutsideToClose
Default: true (boolean)
Closes the lightbox when the user clicks outside the image area.
translateOnHorizontalSwipe
Default: true (boolean)
Enables slight horizontal translation while swiping (cosmetic).
Useful to disable when using complex transitions.
translateOnVerticalSwipe
Default: true (boolean)
Enables vertical translation when swiping down to close.
animation
Default: "short-slide" (string)
Specifies the transition animation between slides (CSS class suffix).
theme
Default: "dark" (string)
Sets the color theme ("dark", "light", or custom)

Methods

init(options)
Params: options (object, optional)
Initializes the lightbox instance with optional configuration.
open(index, direction)
Params: index (number), direction (string)
Opens the lightbox at a specific slide index and applies the specified animation direction.
close()
No params
Closes the lightbox and resets internal state and focus.
next()
No params
Navigates to the next slide.
prev()
No params
Navigates to the previous slide.
hideInterface()
No params
Hides navigation controls and overlays when enabled.
showInterface()
No params
Shows UI controls and overlays.
refreshElements()
No params
Re-scans the DOM or provided data array and rebuilds the slide list.
updateOptions(newOptions)
Params: newOptions (object)
Applies updated configuration values at runtime without reinitializing the entire component.
destroy()
No params
Removes all lightbox DOM elements and detaches all associated listeners.