Skip to content
This repository has been archived by the owner. It is now read-only.
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


A Beautiful Responsive Lightbox.

Fresco comes with thumbnail support, fullscreen zoom, Youtube and Vimeo integration for HTML5 video and a powerful Javascript API.




Download Fresco and include it below the latest 3.x release of jQuery:

<script type="text/javascript" src="/fresco/dist/js/fresco.min.js"></script>
<link rel="stylesheet" type="text/css" href="/fresco/dist/css/fresco.css" />

Alternatively Fresco can be installed using npm or yarn:

npm i @staaky/fresco
yarn add @staaky/fresco

Basic usage

The easiest way to use Fresco is by adding the class fresco to a link.

<a href="image.jpg" class="fresco">Show image</a>

The alternative is using the Javascript API. For more on this see the API docs."image.jpg");
<a href="image.jpg" class="fresco" data-fresco-caption="Caption below the image"

Setting Options

Extra Options and Callbacks can be added using the data-fresco-options attribute.

  data-fresco-caption="Caption on top of the image"
  data-fresco-options="ui: 'inside'"
  >Caption on top</a


Create groups by giving links a data-fresco-group attribute. Each group should have a unique name. Groups can contain multiple types of content, images can be mixed with Youtube videos for example:

  data-fresco-group-options="ui: 'inside'"
  >This group</a
<a href="image2.jpg" class="fresco" data-fresco-group="shared_options"
  >has shared</a
<a href="image3.jpg" class="fresco" data-fresco-group="shared_options"

User Interface

There are two types of user interface settings, outside and inside. outside is the default and will put user interface elements outside of the window.

data-fresco-group-options="ui: 'outside'"

The alternative is inside, it puts the elements inside the window:

data-fresco-group-options="ui: 'inside'"

On small screens Fresco will switch to an alternative UI mode to optimize use of the viewport. This mode uses the entire screen for navigation and doesn't close Fresco when clicking the overlay.

Note: Touch devices will always use ui: 'outside' no matter which ui option is selected.

Important: ui: 'outside' will be forced whenever a group contains more than images. The reason for this is that interaction with content like Youtube videos would be impossible if it had overlapping user interface elements.


Overflow can be used to create a zoom-like effect. By default the overflow options is set to false, which resizes images to fit within the viewport. Using overflow true will allow overflow along the y-axis.

Here's a popular usecase of overflow combined with vertical thumbnails:

  data-fresco-group-options="overflow: true, thumbnails: 'vertical', onClick: 'close'"
<a href="large_image_2.jpg" class="fresco" data-fresco-group="overflow-example"

Note: Overflow is not supported on touch based devices.


Thumbnails are enabled by default and are automatically generated for images and Youtube videos. They can also be disabled by setting the thumbnails option to false:

data-fresco-group-options="thumbnails: false"

By default the thumbnails option is set to horizontal, the alternative is vertical:

data-fresco-group-options="thumbnails: 'vertical'"

Performance, best practices

To improve performance it's recommended to create your own thumbnails. This avoids having to load entire source images to generate them on the fly. Providing thumbnails using the thumbnail option speeds up load times and saves bandwidth, especially noticeable with groups containing large images.

  data-fresco-options="thumbnail: 'thumbnail1.jpg'"
  >Generated Thumbnails</a
  data-fresco-options="thumbnail: 'thumbnail2.jpg'"

Note: The thumbnail generated is set to 240x240px because the maximum dimensions of a thumbnail are 120x120px. Having double the size available will make sure the thumbnails look good on Retina displays.

Media types

Fresco attempts to automatically detect the media type using the given url. The type can also be set to one of the following values using the data-fresco-type attribute: image, youtube or vimeo.


Most of the time setting the type will not be required for images, it will be required in cases where Fresco cannot detect it based on the url:

<a href="/images/?id=1337" class="fresco" data-fresco-type="image">Image</a>


Links to Youtube videos will be embedded using the Youtube <iframe> API.

<a href="" class="fresco">Youtube</a>

Options of the Youtube <iframe> API can be set using the youtube option, see YouTube Embedded Players and Player Parameters for all the available options. Setting the width and height option might also be desired:

      width: 853,
      height: 480,
      youtube: { autoplay: 0 }
  >Youtube - Dimensions and options</a


Vimeo links are embedded using the Vimeo API:

<a href="" class="fresco">Vimeo</a>

Options of the Vimeo Player API can be set using the vimeo option. See Vimeo Player Embedding for all the available options:

     width: 853,
     height: 480,
     vimeo: { autoplay: 0 }
  >Dimensions and options</a

Note: Vimeo videos don't have a thumbnail by default, this can be set using the thumbnail option.

Javascript API

The API allows Fresco to be used with just Javascript, as an alternative to using the fresco class on links. The most common use of the API is opening multiple items from a single link.


A single item can be shown by giving a url:

<a href="#" id="example-1">Show Image</a>

<script type="text/javascript">
  $(document).ready(function () {
    $("#example-1").on("click", function (event) {
      // the page will scroll up without this

      // Fresco API code goes here"image.jpg");

Add a caption by using an object instead:{
  url: "image.jpg",
  caption: "Caption below the image",

This object also accepts options to customize Fresco:{
  url: "",
  options: {
    width: 853,
    height: 480,
    youtube: { autoplay: 0 },


Groups can be shown by giving an array with multiple items:

// use urls["image1.jpg", "image2.jpg"]);

// or objects[
  { url: "image1.jpg", caption: "Caption for this image" },
  { url: "image2.jpg", caption: "Another caption" },

Options for the entire group can be set using the second argument:["image1.jpg", "image2.jpg"], {
  thumbnails: false,


Open Fresco at a specific position by setting a number as the last argument:["image1.jpg", "image2.jpg"], 2);


Links that use the fresco class can also be opened by passing an element:$("#elementid")[0]);


Close Fresco at any time by calling Fresco.hide():



Disables Fresco. When disabled, links using the fresco class will no longer open Fresco but work as regular links. Calls to will use a fallback to make them behave like regular links.


Use Fresco.fallback(false) should you need to disable this fallback as well:



Enable Fresco if it was previously disabled.



When Fresco is disabled it will fallback to making calls open as regular links. By disabling this fallback API calls will do nothing at all.



Sets the name of the default skin, this skin will be used when no skin option is provided.



Options can be set using the data-fresco-options attribute.

<a href="image.jpg" class="fresco" data-fresco-options="ui: 'inside'"
  >Show Image</a

Or when used with groups, the data-fresco-group-options attribute.

  data-fresco-group-options="thumbnails: false, ui: 'inside'"
  >Image 1</a
<a href="image2.jpg" class="fresco" data-fresco-group="options_example"
  >Image 2</a
<a href="image3.jpg" class="fresco" data-fresco-group="options_example"
  >Image 3</a

When using the Javascript API these would translate to:{ url: "image.jpg", options: { ui: "inside" } });["image1.jpg", "image2.jpg", "image3.jpg"], {
  thumbnails: false,
  ui: "inside",


Sets the duration ofindividual effects, or disables them when set to false.

effects: false

These are all the available options:

effects: {
  content: { show: 0, hide: 0 },
  spinner: { show: 150, hide: 150 },
  window: { show: 440, hide: 300 },
  thumbnail: { show: 300, delay: 150 },
  thumbnails: { slide: 0 }


This option only affects youtube content, for everything else this option will translate to maxHeight.

height: 720


Initial options for different types, available types are image, vimeo and youtube. This option is there for use within skins where it can help to adjust defaults and avoid code repetition.

initialTypeOptions: {
  'image': { },
  'vimeo': {
    width: 1280
  'youtube': {
    width: 1280,
    height: 720


Enable or disable individual keyboard buttons or all of them when set to false. Useful for when the content requires keyboard interaction.

keyboard: false

Use an object to toggle individual buttons:

keyboard: {
  left: true,
  right: true,
  esc: false

Note: The keys left and right are only enabled when using the image type. Any other type of content might require these keys.


Sets the method used to decide when an image is loaded. The default is naturalWidth, which starts showing the image as soon as dimensions are known.

The alternative is using onload, which shows the image as soon as onload fires. This can give the image more time to render, but is slower.

loadedMethod: 'onload'


When set to true a group becomes a continuous loop, keeping navigation buttons enabled at all times:

loop: true


Sets a maximum height for the content.

maxHeight: 500


Sets a maximum width for the content.

maxWidth: 500


Sets overflow along the y-axis, creating a zoom like effect whenever an image overflows.

See the documentation on overflow for examples on using this option.

overflow: true

Note: Overflow is not supported on touch based devices.


Options of the overlay, setting close: false will prevents clicks on the overlay from closing the window.

overlay: { close: false }


What to do when clicking the area overlapping an image. Available options are: 'previous-next' or 'close'


Shows a position indicator when set to true, or hides it when set to false.

position: false


Sets the items to preload before and after the current item, or disables preloading when set to false.

preload: [1, 2] // preload 1 before and 2 after
preload: false // disables preloading


Disables the loading icon when set to false.

spinner: false


Sets the skin, the options of this skin will be applied as a starting point for other options. Available skins are: fresco and any added custom skins.

skin: 'fresco'

Note: See documentation on Skins for instructions on creating and customizing skins.


Hides the current item while showing the next one when set to true (the default). Setting it to false will hide the current item before showing the next one.

sync: false


This option can be used to set an alternative thumbnail image, it will be based on the source if this option isn't set.

thumbnail: 'thumbnail.jpg'

Note: See the documentation on performance more information on optimizing thumbnails for performance.


Enabled or disables the thumbnails below the content.

thumbnails: false

Note: Thumbnails aren't used on touch based devices for performance reasons.


Sets position of user interface elements. The default is outside which positions everything outside of the content, inside puts the elements on top of the content:

ui: 'inside'

On small screens Fresco will switch to an alternative UI mode to optimize use of the viewport. This mode uses the entire screen for navigation and doesn't close Fresco when clicking the overlay.


The duration in miliseconds to wait before hiding UI elements that can be toggled on mouseover:

uiDelay: 3000


Sets the player parameters of a Vimeo video, available options can be found in the Vimeo documentation: Vimeo Player Embedding.

vimeo: {
  autoplay: 1,
  title: 1,
  byline: 1,
  portrait: 0,
  loop: 0


This option only affects youtube content, for everything else this option will translate to maxWidth.

width: 1280


Sets the player parameters of a Youtube video, available options can be found in the Youtube documentation: YouTube Embedded Players and Player Parameters.

youtube: {
  autohide: 1,
  autoplay: 1,
  controls: 1,
  enablejsapi: 1,
  hd: 1,
  iv_load_policy: 3,
  loop: 0,
  modestbranding: 1,
  rel: 0,
  vq: 'hd1080'


Callbacks can be used alongside other Options.



A function to call after the position changes. The first argument is the current position within the loaded group.

afterPosition: function(position) {
  alert("You've reached position " + position);


A function to call when Fresco hides.

afterHide: function() {
  alert('Fresco is no longer visible');


A function to call when Fresco comes into view.

onShow: function() {
  alert('Fresco is visible');


Skins are a combination of Javascript Options, CSS and an SVG/PNG sprite. To use a skin the only option required is the skin option. Options of the selected skin are then applied as a starting point. Additional options will overwrite what's defined on the skin:

skin: 'fresco', ui: 'inside'

When creating your own skins it's highly recommended to place all custom Javascript and CSS in separate files included below the Fresco files. This will allow upgrading without losing any of your custom skins. Here's an example:


<script type="text/javascript" src="/fresco/custom-skin.js"></script>
<link rel="stylesheet" type="text/css" href="/fresco/custom-skin.css" />

<script type="text/javascript">
  // make a custom skin the new default

Adding a new skin

A custom skin requires Javascript, CSS and sprite images. Let's start with the Javascript.

All skins inherit their options from a base skin defined in Fresco.skins. Because of this inheritance the only Options that have to be defined are those different from the base skin. A custom skin is created by extending the Fresco.Skins object, here's how it could be defined:

$.extend(Fresco.Skins, {
  custom: {
    ui: "inside",

After the skin has been created it can be applied using the skin option:

<a href="image.jpg" class="fresco" data-fresco-options="skin: 'custom'"
  >Custom skin</a

When using groups the best way to apply the skin is using the data-fresco-group-options:

  data-fresco-group-options="skin: 'custom'"
<a href="image2.jpg" class="fresco" data-fresco-group="example">Skin</a>

Custom CSS

Once the Javascript for a skin is in place a skin will need CSS and sprites for styling. To help with styling Fresco adds the name of the skin to certain classnames:


It is recommended to copy the fresco skin defined in fresco.css as a starting point for new skins. To do this copy all the definitions of the fresco skin into to a separate css file.

This means all definitions starting with .fr-window-fresco, .fr-overlay-fresco and .fr-spinner-fresco. Rename those to match your new skin. For example, if your skin is named custom the CSS rules would start with:


Changing the default skin

To avoid having to set the skin option all the time the default skin can be changed using Fresco.setDefaultSkin(). It should be called after the file that defines custom skins, for example:

<script type="text/javascript" src="/js/fresco/fresco.js"></script>
<link rel="stylesheet" type="text/css" href="/css/fresco/fresco.css" />

<script type="text/javascript" src="/js/fresco/fresco-custom-skins.js"></script>

<script type="text/javascript">
  // make a custom skin the new default

Fresco has been open-sourced under the Creative Commons BY 4.0 license as of oct. 26 2019.