Replicating and improving the lightbox module seen on Medium with fluid transitions. View demo here.
Special thanks to the following stellar folks who has helped majorly in making Fluidbox better
Fluidbox was initially a simple personal challenge I set myself, with two simple aims — to replicate the distraction-free, fluid lightbox seen on Medium, and to improve on it such that it will allow linking to a larger-resolution image. The plugin deals with higher resolution, linked images elegantly, such that it only preloads them when users click on the thumbnails, therefore conserving bandwidth usage for your visitors and your server(s).
The plugin is relatively lightweight: 4kb (1.43kb after gzipped) for the minified JS file, and 969b (332b after gzipped) for the minimal stylesheet.
You can read my article on Medium about how I got inspiration for this little project of mine, and the basic mechanisms behind the plugin. Some serious math is involved (nah, not really).
Moreover, you can visit the demo of this plugin on the project page hosted with GitHub. The plugin version 1.22 and onwards (uncompressed, minified and its associated CSS file) is hosted with CDNJS.
Fluidbox has been implemented on other sites in the wild, too — check it out:
- Gemma Busquets by @imgemmabusquets
- Terry Mun by myself
To add your site, write to me at @teddyrised.
Version | Comments |
---|---|
1.2.0 | Official release |
1.2.1 | Minor bug fixes |
1.2.2 |
|
1.2.3 |
|
1.2.4α | Warning: Buggy, alpha-build
|
1.2.5 |
|
1.2.6 |
|
1.2.7 |
|
1.3.0 |
|
1.3.1 |
|
1.3.2 |
|
1.3.3 |
|
1.3.4 |
|
To install Fluidbox, you will have to include the following resources in your page. The JS files should be loaded in the order stipulated below. For the CSS file, you can either incorporate it with your site's stylesheet, or load it externally through the <link>
element in <head>
.
Type | File Name | Description |
---|---|---|
JS | jQuery 1.x | External Dependency: The latest verson of jQuery 1.x library is needed for Fluidbox functionality. |
JS | jquery.fluidbox.js |
Confers the main functionality of Fluidbox. Alternatively, you can load the minified version, jquery.fluidbox.min.js |
CSS | css/fluidbox.css |
Offers styles that are crucial for the correct display of Fluidbox. The appearance will break if this is not included. |
It is rather straightforward to use Fluidbox — simply chain the .fluidbox()
method to a selector of your choice. The plugin will automatically check if the selector is:
- An anchor element
- Contains one and only one child
- The only children is an
<img>
element
In the event that the element that satisfies the selector criteria but failed any one of the above criteria, the element will be ignored and the plugin moves on to the next available element. Therefore, it is important that your Fluidbox element(s) follow the following format. The title
and alt
attributes of the <img>
element is not used by the plugin, but the alt
attribute has to be present for it to be semantically valid.
<a href="...">
<img src="..." alt="" />
</a>
In your JS file, you can simply chain the .fluidbox()
method to your selector on DOM ready:
$(function () {
$('a').fluidbox();
})
The selector can be anything of your choice. Let's say you want to target the <a>
elements specifically in a certain section on your page:
<section id="gallery">
<h1>Title</h1>
<p>Introductory text with an <a href="#">unrelated link</a></p>
<a href="..." rel="lightbox">
<img src="..." alt="" />
</a>
</section>
Then, you can use:
$(function () {
$('#gallery a[rel="lightbox"]').fluidbox();
})
Previously hidden elements
As of v1.3.4, Fluidbox will only work with elements that are visible, i.e. not display: none
, on the page upon DOM ready. This is because dimensions of hidden images (or images in parents who are hidden) are inaccesible to Fluidbox, resulting in an error. You will have to rebind Fluidbox to the newly revealted elements. Given the example below:
// Apply Fluidbox to elements of interest
$('.gallery a').fluidbox();
// User-triggered event to display gallery
$('#show-gallery').click(function () {
$(this).next().show();
});
<button type="button" id="show-gallery">Show Gallery</button>
<div class="gallery" style="display: none">
<a href="...">
<img src="..." alt="" />
</a>
</div>
You will realize that, even after revealing the element, the Fluidbox method is not working for it. That is because non-visible elements, despite satisfying the selector, will not be bound. So, use the following code instead:
// Apply Fluidbox to elements of interest
$('.gallery a').fluidbox();
// User-triggered event to display gallery
$('#show-gallery').click(function () {
$(this)
.next()
.show() // Show gallery
.find('a') // Fluidbox to all elements in gallery
.fluidbox();
});
In order to enable Fluidbox functionality to dynamically-added content, you will have to apply .fluidbox()
to the element of interest after appending it to the DOM. For example, let's say clicking a <button>
triggers the addition of a new image:
$(function() {
$('button').click(function(e) {
e.preventDefault();
// Construct new image
var $newContent = $('<div><p>This is a new image that is dynamically-added to the page.</p><a href="http://placehold.it/500x500" title="" data-fluidbox><img src="http://placehold.it/200x200" alt="Alternate Text" title="Image Title" /></a></div>');
// Insert new content object into DOM, and then apply .fluidbox to it
$(this).after($newContent).next().find('a[data-fluidbox]').fluidbox();
});
));
You are of course welcome to use other ways to manipulate and/or transverse the DOM, but you will have to adjust the search/filter function (using .find()
or other similar jQuery methods) to retrieve the newly inserted content and search for the element of interest where you want Fluidbox to work with.
Fluidbox can be configured according to your needs. The following options are available:
Option | Type | Default value | Description |
---|---|---|---|
viewportFill |
Numerical | 0.95 |
Dictates how much the longest axis of the image should fill the viewport. The default value will make the image fill 95% of the viewport dimension along its longest axis |
overlayColor |
String | rgba(255,255,255,.85) |
Sets the background-color property of Fluidbox overlay. Defaults to white with an opacity of 0.85. |
debounceResize |
Boolean | true |
Dictates if the $(window).resize() event should be debounced for performance reason. This feature leverages the small snippet kindly provided by Paul Irish. |
closeTrigger |
Array | see below | Dictates what event triggers closing of an opened Fluidbox. The default setup binds the click handler to the overlay. |
stackIndex |
Integer | 999 |
Determines how high up the z-index will all Fluildbox elements be. Leave this option as default, unless you have other relatively or absolutely positioned elements on the page that is messing with Fluidbox appearance. |
The default setup will have the effect of binding the click event to the overlay, so that when user click on the overlay, the Fluidbox instance that is opened will be closed:
// Default option
closeTrigger: [
{
selector: '#fluidbox-overlay',
event: 'click'
},
{
selector: 'document',
event: 'keyup',
keyCode: 27
}
]
It is also possible to bind other events to trigger the same effect. For example, if you would want to close the Fluidbox when the viewport is resized, you can do the following:
$(function () {
$('a').fluidbox({
closeTrigger: [
{ selector: '#fluidbox-overlay', event: 'click' },
{ selector: 'window', event: 'resize' }
]
});
});
This will have the effect of doing so (where closeFb
is the internal function in the plugin needed to close any opened Fluidbox):
$(document).on('click', '#fluidbox-overlay', closeFb);
$(window).on('resize', closeFb);
You can even bind event to multiple selectors, and vice versa. The syntax of dictating so is similar to constructing event handler binding using the .on()
method, so if you are familiar with its use, dictating your own closeTrigger should not be too difficult:
$(function () {
$('a').fluidbox({
closeTrigger: [
{ selector: '#fluidbox-overlay', event: 'click' },
{ selector: 'window', event: 'resize scroll' },
{ selector: '#ele1, #ele2', event: 'hover' }
]
});
});
This will have the effect of doing so:
$(document).on('click', '#fluidbox-overlay', closeFb);
$(window).on('resize', closeFb);
$(document).on('hover', '#ele1, #ele2', closeFb)
Fluidbox require the following dependencies in order to function properly — you will have to include them in your page, if you want Fluidbox to work:
- The latest release of jQuery 1.x (minimum requirement: jQuery >1.7), available from Google's jQuery API at
http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
Note that the imagesloaded jQuery plugin is no longer required as of v1.2.8 and above.
Fluidbox allows you to throttle the $(window).resize()
event, and this is only possible with Paul Irish's debounced resize function. The small script has been included in the plugin by default, but I would like to extend my gratitude to Paul for making it available, and for allowing me to include it in this plugin.
Fluidbox may not work properly in the event that you have set your parent container, or content wrapping elements, such as <div id="#content">
and the likes, to hide their overflowing content, i.e. overflow: hidden
. This is because the enlarged image is positioned relatively to its hyperlink, and not absolutely or fixed within the viewport.
When you want an absolutely/fixed-positioned element on the page to not be obscured by the dynamically-generated wrapping element, you should use a z-index of between 1000 to 1010. 1000 is set as the default stackIndex
of Fluidbox, while 10 is set as the default stackIndexDelta
, which is toggled on/off depending on the state of the Fluidbox. These settings can be individually tuned, see Configuration below.
Binding Fluidbox to previously hidden images
As Fluidbox requires access to the final calculation dimensions of the image in question in order to (1) position the ghost element correctly and (2) calculate the correct scale factor and transform values, it will break if you try to bind it to hidden elements that are not visible. Instead, try to bind Fluidbox to visible elements only (or use the :visible
pseudo-class`) and then rebind Fluidbox to freshly revealed elements. This also applies to dynamically-loaded content, see demo for a working example.
As Fluidbox relies on CSS transforms, it only works with thumbnails that share the same aspect ratio with their higher resolution counterparts, otherwise the larger image will be cropped off, i.e. a square thumbnail linking to a landscape photo will cause the landscape photo to appear in a square frame.
-
Fluidbox is not working in my installation. Where should I start?
Start by checking your browser's console log. What error messages do you see? Also, make sure that you are using the latest version of jQuery 1.x (minimum requirement: v1.8 or above) and that the dependencies have been loaded successfully. Also, did you remember reading the precautions segment? You might have encountered a scenario where Fluidbox is not designed to handle. -
Do you plan to implement [insert feature]?
Fluidbox is conceived as a means to simplify lightboxes. Therefore, I plan to keep Fluidbox as simple as it is, without additional features, such as captioning (there are other limitations to this, too) and gallery features. However, you can always fork and modify Fluidbox to your perosnal liking.
This plugin is licensed under the MIT License.