A touchable jQuery lightbox

What is Shinybox ?

Shinybox is a jQuery "lightbox" plugin for desktop, mobile and tablet.

Main Features

  1. Swipe gestures for mobile
  2. Keyboard Navigation for desktop
  3. CSS transitions with jQuery fallback
  4. Retina support for UI icons
  5. Easy CSS customization


Chrome, Safari, Firefox, Opera, IE8+, IOS4+, Android, windows phone.

Try it

Basic Usage


Include jquery and the shinybox script in your head tags or right before your body closing tag.

<script src="lib/jquery-2.0.3.js"></script>
<script src="source/jquery.shinybox.js"></script>


Include the shinybox CSS style in your head tags.

<link rel="stylesheet" href="source/shinybox.css">


Use a specific class for your links and use the title attribute as caption.

<a href="big/image.jpg" class="shinybox" title="My Title" caption="My Caption">
    <img src="small/image.jpg" alt="image">

Fire the plugin

Bind the shinybox behaviour on every link with the "shinybox" class.

<script type="text/javascript">
jQuery(function($) {


Use "rel" Attribute

You can add a rel attribute to your links to seperate galleries.

<!-- Gallery 1 -->
<a rel="gallery-1" href="big/image1.jpg" class="shinybox">
    <img src="small/image1.jpg" alt="image">
<a rel="gallery-1" href="big/image2.jpg" class="shinybox">
    <img src="small/image2.jpg" alt="image">
<!-- Gallery 2 -->
<a rel="gallery-2" href="big/image3.jpg" class="shinybox">
    <img src="small/image3.jpg" alt="image">
<a rel="gallery-2" href="big/image4.jpg" class="shinybox">
    <img src="small/image4.jpg" alt="image">

Video support

Simply paste a youtube or vimeo video URL in your href attribute. The script will automatically check if it's a youtube or vimeo URL and opens the video in the shinybox.

My Video

<a class="shinybox-video" rel="youtube" href="">My Videos</a>

Inline Content support

Paste id of element with # in the href. The script will automatically check if it's inline content and opens it in the shinybox.
Note: You might have to do minor css tweaks to get proper UI inside shinybox.

My Presentation

<a class="shinybox-inline" href="#presentation">My Presentation</a>
    afterMedia: function (element, index) {
            background: '#F0F0F0',
            lineHeight: 1.42,
            textAlign: 'left',
            padding: '20px 15px',

Load slides dynamically

You can set your gallery dynamically by passing an array object to the shinybox.

View gallery

        {href:'big/image1.jpg', title:'My Title', caption: "My Caption" },
        {href:'big/image2.jpg', title:'My Title 2', caption: "My Second Caption"}

Refresh Method

The refresh method allows you to reload the slides if the DOM has changed.

var shinyboxInstance = $(".a:visible").shinybox();

// Use the refresh method after your event is completed

For example, if you use isotope filter.

// Use the shinybox only for  visible elements
var shinyboxInstance = $(".shinybox-isotope:not(.isotope-hidden .shinybox-isotope)").shinybox();

// Callback function that fire the refresh method, once the animation is finished
onAnimationCompleted = function(){

// Isotope stuff
optionFilterLinks = $('#filter').find('a');
optionFilterLinks.attr('href', '#'); function(){
    var selector = $(this).attr('data-filter');
        filter : '.' + selector,
        itemSelector : '.item',
        layoutMode : 'fitRows',
        animationEngine : 'best-available',
    }, onAnimationCompleted); // callback here


    return false;

Check open state

if (shinyboxInstance.ui.isOpen){
    // do stuff


<script type="text/javascript">
    jQuery(function($) {
            id: 'shinybox-overlay', // id of the overlay element
            useCSS: true, // false will force the use of jQuery for animations

            hideCloseButtonOnMobile: false, // hide close button on mobile, you can always use swipe up or down to close the shinybox on mobile
            loopAtEnd: false, // Play images in loop in either directions

            noTitleCaptionBox: false, // Set true if you don't have title caption box

            initialIndexOnArray: 0, // which image index to init when a array is passed
            showNavigationsOnMobile: false, // true to always show navigation icon on mobile
            sort: null, // a sorting function to sort the dom elements before showing in shinybox

            videoMaxWidth: 1140, // videos max width
            autoplayVideos: false, // autoplay video
            vimeoColor: 'CCCCCC', // vimeo color
            queryStringData: {}, // any additional data to pass to youtube or vimeo videos

            beforeOpen: function(){}, // called before opening
            afterClose: function(){}, // called after closing
            afterMedia: function(element, index){}, // called after loading media
            afterSlide: function(element, index){} // called after sliding to image at the index

Download View Source


Photos by Daniele Zedda