
Features:
- Content type is inferred from the URL automatically. Images, YouTube links, Vimeo links, iframes, and
#idselectors each trigger the correct display mode. - Supports
.jpg,.png,.gif,.webp,.svg, and.avifimages; YouTube (including Shorts); Vimeo; anyhttps://iframe URL; and cloned inline HTML from the same page. - The overlay uses
role="dialog"andaria-modal="true". Focus traps inside the open dialog, returns to the trigger on close, and ESC key support is built in. - Body scroll is locked while the lightbox is open, then restored on close.
- Respects
prefers-reduced-motionand reduces transition duration to 1ms for users who prefer it. - Six CSS variables cover z-index, duration, easing, border radius, box shadow, and overlay color.
- Works as a
<script>tag, a CommonJSrequire(), or an AMDdefine().
Use Cases:
- Display high-resolution photos in a centered, responsive modal popup.
- Embed YouTube or Vimeo videos with automatic 16:9 aspect ratio handling.
- Clone existing inline HTML forms into a lightbox for user interaction.
- Display external documentation pages within an iframe container.
How To Use It:
1. Load the nanobox.js and nanobox.css files in your HTML document.
<link rel="stylesheet" href="nanobox.css" /> <script src="nanobox.js"></script>
2. Add the data-nanobox attribute to any <a> tag or element with a data-src attribute. NanoBox detects the content type from the URL and opens the correct display mode.
<!-- Open a full-size image from a thumbnail link --> <a href="gallery/sunset-coast.jpg" data-nanobox> <img src="gallery/sunset-coast-thumb.jpg" alt="Sunset over the coast" /> </a> <!-- Open a YouTube video — NanoBox converts the watch URL to an embed automatically --> <a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" data-nanobox>Watch the intro video</a> <!-- Open a Vimeo video --> <a href="https://vimeo.com/148751763" data-nanobox>Watch on Vimeo</a> <!-- Open any iframe URL in a 16:9 container --> <a href="https://maps.google.com/maps?q=Paris&output=embed" data-nanobox>View map</a> <!-- Open inline HTML content cloned from a hidden div on the page --> <a href="#product-details" data-nanobox>View product details</a> <div id="product-details" style="display:none"> <h2>Product Specifications</h2> <p>Weight: 1.4 kg — Dimensions: 30 × 20 × 10 cm</p> </div> <!-- Works on non-anchor elements with data-src --> <button data-src="gallery/team-photo.jpg" data-nanobox>View team photo</button>
3. Call NanoBox.init() once if you need custom options. This replaces the auto-initialized singleton with a configured one.
NanoBox.init({
// Transition duration in ms (default: 280)
animationDuration: 350,
// Click the dark backdrop to close (default: true)
closeOnOverlayClick: true,
// ESC key closes the lightbox (default: true)
escToClose: true,
// Lock body scroll while open (default: true)
scrollLock: true,
// Show loading spinner before content appears (default: true)
showSpinner: true,
// Fires as soon as the lightbox opens (before content loads)
onOpen: function(lb) {
console.log('Lightbox opened', lb);
},
// Fires after the close animation completes
onClose: function(lb) {
console.log('Lightbox closed', lb);
},
// Fires when the content (image, iframe, or cloned element) has fully loaded
onReady: function(lb, el) {
console.log('Content ready:', el);
}
});4. API methods.
// Initialize (or re-initialize) the singleton with options.
// Call once on page load if you need custom configuration.
NanoBox.init({ animationDuration: 200 });
// Open the lightbox programmatically with any supported src string.
// Per-call options override the singleton defaults for that one call.
NanoBox.open('gallery/architecture-print.jpg');
NanoBox.open('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
NanoBox.open('#product-details');
NanoBox.open('gallery/portrait.jpg', {
onReady: function(lb, img) {
console.log('Image dimensions:', img.naturalWidth, 'x', img.naturalHeight);
}
});
// Close the currently open lightbox.
NanoBox.close();
// Remove all event listeners and tear down the singleton.
// Use this before unmounting a SPA route to avoid memory leaks.
NanoBox.destroy();
// Create an independent lightbox instance separate from the singleton.
// Useful when you need two lightboxes with different configurations.
const galleryBox = NanoBox.create({ escToClose: false });
galleryBox.open('gallery/exhibition-01.jpg');
const videoBox = NanoBox.create({ closeOnOverlayClick: false });
videoBox.open('https://www.youtube.com/watch?v=dQw4w9WgXcQ');5. Override the default CSS variables in your own stylesheet to theme NanoBox.
:root {
/* z-index base for overlay and wrap */
--nb-z: 9999;
/* animation duration */
--nb-dur: 280ms;
/* animation easing curve */
--nb-ease: cubic-bezier(0.4, 0, 0.2, 1);
/* border radius of the floating card */
--nb-r: 8px;
/* box shadow on the card */
--nb-shadow: 0 16px 60px rgba(0, 0, 0, 0.8);
/* overlay background color */
--nb-overlay: rgba(6, 6, 10, 0.92);
}Alternatives:
- GLightbox: A more feature-complete lightbox with gallery navigation, captions, slide groups, and touch/swipe support.
- Magnific Popup: A jQuery-based lightbox that has been around for years and covers a wide range of content types.
FAQs:
Q: NanoBox shows “Error 153” for a YouTube video. What’s going on?
A: That error means the video owner has disabled embedding in YouTube Studio. There is no URL parameter or API workaround for this restriction.
Q: My inline content opens but the styles look wrong inside the lightbox. How do I fix it?
A: NanoBox clones the element with cloneNode(true), which copies the node and its children. It does not copy scoped <style> blocks or isolated shadow DOM styles.
Q: Can I use NanoBox with dynamically inserted elements added after page load?
A: Yes. NanoBox uses a delegated listener on document, so any [data-nanobox] element added to the DOM after NanoBox.init() is automatically handled.
Q: I’m running two independent lightboxes with NanoBox.create(). Can I open both at once?
A: Two separate instances can technically both be open, but visually only the one opened last will be on top. There’s no built-in stacking management.
Q: The animationDuration option and the CSS --nb-dur variable don’t match in my setup. The lightbox closes with a flash before the animation finishes.
A: The JS setTimeout in the close() method uses the animationDuration value to time the DOM teardown. The CSS --nb-dur variable controls the actual transition. If they differ, the DOM gets removed before the animation completes. Set both to the same value: NanoBox.init({ animationDuration: 400 }) paired with --nb-dur: 400ms in your CSS.
The post Lightweight Lightbox Library for Images, Videos, iframes & Inline HTML – Nanobox appeared first on CSS Script.
Discover more from RSS Feeds Cloud
Subscribe to get the latest posts sent to your email.
