Need help with film_roll?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

205 Stars 59 Forks MIT License 97 Commits 11 Opened issues


A lightweight jQuery carousel that centers one item at a time on the page.

Services available


Need anything else?

Contributors list

# 171,477
91 commits
# 723,905
1 commit
# 380,997
1 commit


A lightweight jQuery carousel


FilmRoll is a lightweight jQuery carousel (12 kb minified) that focuses on one item at a time, centering it in the view, regardless of the relative sizes of the carousel items.



  • The minified version of this script may throw errors. I have not been able to isolate this. If this happens to you, please use the non-minified script. If you have time, reproduce it with a jsbin or jsfiddle and open an issue. Thanks! (5/2016)


  • Centers one item at a time in the view
  • Uses css classes for easy styling / transitions
  • Provides previous / next buttons and pagination automatically
  • Defaults to auto scroll with pause on hover
  • Supports full screen usage
  • Swipe movement if TouchSwipe is present
  • Yet to be implemented:

A Note on Performance and GSAP

jQuery's animation tends to cause high cpu load. The best solution for this is to use GreenSock to replace the jQuery animate function.

To do so, include the following minimal markup, unless you are using the complete library:



Download jquery.film_roll.min.js and place it in your scripts directory.

For swipe movement, include TouchSwipe.

Then link it in your web page. E.g:

If you use Bower install with

bower install FilmRoll

TouchSwipe will be included as a dependency:


FilmRoll expects a parent div with children div elements, though it should work with most any child element:


Using non

tags as children works fine. The tag used may require (significant) styling to get it to work like a div.


Create the FilmRoll instance on dom:ready:

  jQuery(function() {
    var film_roll = new FilmRoll({
        container: '#container_id',

If you need to create FilmRoll on page load, use the

  jQuery(window).load(function() {
    var film_roll = new FilmRoll({
        configure_load: true,
        container: '#container_id',


var filmroll = new FilmRoll({container: '#containerid', OPTIONS})


  • :container (Mandatory): The div that contains all elements that are to be displayed.

Typical Options: - :height: Set the height of the film_roll wrapper (which sits inside the container.) Options are: - Not set (default): The wrapper will be the height of the container (100%), with a min-height of the tallest element. - Integer/string: Set the height directly. Can be an integer (pixels) or a string ('75%'.) - '+Integer': Set the min-height to the highest child plus this integer value. - :interval: The automatic scroll interval. 4 seconds by default. To turn off the automatic scroll, see the scroll option. - :next: The jquery selector for the next button. Creates its own button by default. Use false for nothing. (See prev option.) - :pager: Display pagination dots at the bottom of the carousel. True by default. - :position: The position of the selected item within the container. Either 'left', 'right', or 'center'. Defaults to 'center'. See the offset option for further adjustment. - :prev: The jquery selector for the previous button. Creates its own button by default. Use false for nothing. (See next option.) - :scroll: Automatically scroll the carousel. True by default.

Other Options:

  • :animation: The slide animation duration. 1/4 of interval by default. (See interval option.)
  • :configure_load: Change how widths and hover response is configured. Options are:
    • false (default) Configure widths/hover on the window load event. FilmRoll assumes it has been instantiated on DOM ready (jQuery.ready().)
    • true: Configure widths/hover immediately (use if instantiating FilmRoll with the page load event)
    • function: Call the function instead of
      (use to adjust content before calling
    • integer: Delay the call to
      by the provided number of milliseconds (content may or may not be ready!)
  • :easing:
    by default. jQuery also provides
    . jQueryUI provides more.
  • :force_buttons: Show previous and next buttons even if the carousel is smaller than the container. Defaults to false.
  • :force_rotate: Rotate child elements even if the carousel is smaller than the container. Defaults to false.
  • :hover: If true, pause scroll on hover. If false, ignore hover. If 'scroll', scroll the carousel on hover. True by default.
  • :moveonstart: If false, starting index will not center on load. True by default.
  • :no_css: Do not add default css to page. You will want to include it otherwise.
  • :offset: Offset the selected item position by given pixels. Positive to move right, negative to move left.
  • :resize: Re-center the carousel on window resize. True by default. Set to false to perform your own logic before calling
  • :shuttle_width: The starting shuttle width until the page loads. Defaults to 10000. See troubleshooting.
  • :start_height: A starting height to give the carousel. Use only if you are having content flashes.
  • :start_index: The index of the first element to center
  • :vertical_center: Center children vertically in the container. Requires a browser with :before CSS pseudo class support. This is useful for a full screen carousel.

Note on using a function for configure_load

you can specify a function for configure_load and inside that function call the internal configure function or even configure the elements manually :

    var film_roll = new FilmRoll({
        configure_load: function(){

notice your function will be invoked immediately ,sometimes it's useful to use a setTimeout inside of your function : ```javascript var filmroll = new FilmRoll({ configureload: function(){ // <---pre-configure operations setTimeout((function (_this) { return function () { return _this.configureLoad(); }; })(this), 1000);

    container: '#container_id',
## Examples

View the Project Page

View the project page for working examples.

Click to Center

If you want to center an item when someone clicks on it, try this:

```javascript var film_roll = new FilmRoll({ container: '#container_id', ... }); $('#container_id div.film_roll_child').on('click',function() { film_roll.moveToChild(this); });

External Javascript Links

If you wish to move to a specific child using external javascript, use the

var film_roll = new FilmRoll(...);

$('#some_link_selector').click(function() { film_roll.moveToIndex(3); //or //film_roll.moveToChild($('#some_child_selector')); return false; })

Note that

uses a zero based index. E.g. if you have four items, the last item is 3.

Full Screen usage

To use FilmRoll full screen, do the following:

  • Using CSS, configure your container div to be 100% height (and width if necessary):
#film_roll { height: 100%; }
  • Do not pass a height when you instantiate the FilmRoll.
  • To align the children to vertical center, use the vertical_center option:
var film_roll = new FilmRoll({
    container: '#film_roll',
    vertical_center: true,
  • If you leave the pager enabled, you'll want to bump it back up with CSS:
.film_roll_pager {
    position: relative;
    top: -20px;

See an example here.


FilmRoll takes the following markup:


and wraps all children with two divs, adds the class

and a style element to the children, and adds the 'active' class to the centered child:

Use these classes to apply styling and effects. See the example page.


On load vs. dom:loaded

FilmRoll is written to be called on dom:ready. It inserts all markup before display and configures itself to resize itself once the content is loaded (after the window.load event) because it must have content to center an item on the page.

If, for some reason, you need to call FilmRoll on window.load, or create it using an in page script, pass in the

configure_load: true
option to immediately call the relevant code:
var film_roll = new FilmRoll({
    configure_load: true,
    container: '#container_id',

Responsive Images

FilmRoll must have a specific width for all child elements to center a given item. The question is, if the children have responsive sizes, what size should they be? To answer this question FilmRoll makes an assumption: the size of the child elements before all FilmRoll styling is applied is what they should be in the carousel. It will measure the child element widths, and fix them with inline styling.

You can take advantage of this in a few ways:

  • If you have varying widths, and the heights end up changing in a mobile format, use CSS to force the height of all children.
  • Use one 'banner' child to resize all other children to the same height by calling javascript on the
    callback. See callback examples below.


FilmRoll provides the following callbacks. Unless otherwise noted, all events are triggered on the surrounding container that FilmRoll is initialized with:

  • filmroll:domready: When html content has been inserted but the page has not been loaded.
  • film_roll:moving: When shuttle animation begins.
  • film_roll:moved: When shuttle animation has finished.
  • film_roll:resizing: Before FilmRoll measures the size of all content. The shuttle div is given the class
    during measurement. Called when the page has been loaded and when the page resizes.
  • film_roll:resized: When the FilmRoll has been resized.
  • film_roll:activate: When a child element is activated. Triggered on the child.

Note: The callback name includes the

prefix. E.g. use

Callback Examples

These callbacks are there to let you do most anything. Here are a few examples:

Display a Counter

With the following code, a counter is updated to display the slide per children when each move is finished:

var film_roll = new FilmRoll({container: '#container_id',...});
$('#container_id').on('film_roll:moved', function(event) {
    $('#some_counter_div').html( (film_roll.index+1)+' / '+film_roll.children.length );

Remove CSS early

On the demo page the second carousel uses CSS3 transformations to lean the pictures to the left or right when the class

is added so they look like they are flexing. But it looks really unnatural at the end without some help. To make it look more realistic, I use the
callback to set a timer that removes the class at 550ms instead of 1000ms:
    $('#film_roll_2').on('film_roll:moving', function() {
      setTimeout(function() {
        $('#film_roll_2 div.film_roll_shuttle').removeClass('moving_left moving_right');
      }, 550);

Responsive images

You can use

to cause the carousel to be more responsive.
happens before the size of all children are set so you can prepare the children for display. This is a coffeescript function, and it configures the carousel to resizes the height of all
images to match the height of the
image, which is designed to be full width:
  configureCarouselSecondaryImages: ->
    $carousel = $ 'div.carousel'
    $banner = $carousel.find('img.banner')
    if $banner
      $carousel.on 'film_roll:resizing', ->
        $carousel.find('img.resize').height('').height $banner.height()


is called when the page loads and when the page resizes, this forces all images to be the same height as the banner image, no matter what their relative sizes. The banner image can adjust itself to the window of the device (using CSS and
max-width: 100%
), and the rest of the images can adjust to it. Google for responsive images to learn more about it.

Default CSS

Unless you specify no_css, FilmRoll adds the following css to the page header:

.film_roll_wrapper {
   display: block;
   text-align: center;
   float: none;
   position: relative;
   top: auto;
   right: auto;
   bottom: auto;
   left: auto;
   z-index: auto;
   width: 100%;
   margin: 0 !important;
   padding: 0 !important;
   overflow: hidden;
   width: 100%;
.film_roll_shuttle {
   text-align: left;
   float: none;
   position: relative;
   top: 0;
   left: 0;
   right: auto;
   bottom: auto;
   margin: 0 !important;
   padding: 0 !important;
   z-index: auto;
 .film_roll_shuttle.vertical_center:before {
   content: '';
   display: inline-block;
   height: 100%;
   vertical-align: middle;
   margin-right: -0.25em;
.film_roll_child {
  position: relative;
  display: inline-block;
.film_roll_prev, .film_roll_next {
   position: absolute;
   top: 48%;
   left: 15px;
   width: 40px;
   height: 40px;
   margin: -20px 0 0 0;
   padding: 0;
   font-size: 60px;
   font-weight: 100;
   line-height: 30px;
   color: white;
   text-align: center;
   background: #222;
   border: 3px solid white;
   border-radius: 23px;
   opacity: 0.5;
.film_roll_prev:hover, .film_roll_next:hover {
   color: white;
   text-decoration: none;
   opacity: 0.9;
.film_roll_next {
   left: auto;
   right: 15px;
.film_roll_pager {
   text-align: center;
.film_roll_pager a {
   width: 5px;
   height: 5px;
   border: 2px solid #333;
   border-radius: 5px;
   display: inline-block;
   margin: 0 5px 0 0;
   transition: all 1s ease;
.film_roll_pager a:hover {
   background: #666;
.film_roll_pager {
   background: #333;
.film_roll_pager span {
   display: none;
 .film_roll_pager a, a.film_roll_prev, a.film_roll_next {
   -webkit-box-sizing: content-box;
   -moz-box-sizing: content-box;
   box-sizing: content-box;

Add it to your own css and disable with

no_css: true
when calling FilmRoll to improve performance.


Loading Failure (e.g. on iOS 8)

FilmRoll needs to measure the size of all elements to function. As a result, it is not completely configured until page load. If any other script fails or times out it could cause FilmRoll to fail. iOS 8 in particular is brittle in this regard. (In one instance Vimeo failed to load and caused FilmRoll to fail.) Use developer tools to watch your resources loading. Look for any failures.

You can delay

with a timeout by passing in an integer to the configure_load option:
var film_roll = new FilmRoll({
  container: '#container_id',
  configure_load: 50

This will call

50 milliseconds after the film roll is instantiated. This may or may not mean the assets are ready!

Large images or slow loading pages

If you have a heavy set of images, the gallery can look empty while it loads. You can either style the child element to have an appropriate background (e.g. a gradient) while it is waiting, or you can use javascript to load high res pics later. E.g. populate your gallery with placeholder images and use jQuery Lazyload to load the images after the page loads.

Items aren't centering

If items aren't centering correctly, it is probably because you don't have child div's in side the parent div. For instance, calling FilmRoll on an unordered list has mixed results. Usually the centering will not work. You'll have to strip all normal css styling to get it to work. It will probably be easier to convert it to div > div format.

If you do have divs inside a parent div, try temporarily giving a border to the child div to see what is going on. The child div may be centered, but its content may not be.

If you think you have found a bug, report an issue.

Images disappear at the front or back

FilmRoll is really designed for content wider than the container. When you get to the end of a list of children, it rotates content ahead of time so there are no blank spaces during the subsequent animation. If your list is just wider than your container, or if your children are very wide compared to the width of the whole, you may see children disappear from one side before they appear on the other. This is expected behavior.

Eventually I will have a fix for this. In the meantime, repeat the children to fill out the list. It will still look like the smaller list rotating, and you will not have 'disappearances.'

Double rows on start (shuttle width)

FilmRoll sets the shuttle (the the div that holds all elements and slides back and forth) to 10000 pixels wide until the page loads. When the page loads, the content is used to determine the appropriate width. If 10000 pixels is not enough for the content you will get two rows of children during page load. Try setting

to a higher value.

Box shadow is cut off

jQuery does not measure the box shadow when it measures the height of child elements. If you want FilmRoll to adjust the height dynamically but also make the box shadow visible, set the FilmRoll height with a "+height" string. The integer should be the same as your box shadow height. So if your box shadow is

, use
height: "+10"
. FilmRoll will add 10 pixels to the minimum height of the wrapper.


  • 0.1.17: (1/13/16) moveonstart option, recompile for issues
  • 0.1.16: (4/13/15) Position/offset, slide but no rotate for less than visible width, handle duplicate instances, forcebuttons & forcerotate options
  • 0.1.15: (3/15/15) Prevent TouchSwipe link block
  • 0.1.14: (12/16/14) Millisecond delay option for configureLoad
  • 0.1.13: (12/15/14) Allow no prev/next buttons
  • 0.1.12: (7/18/14) Bower support
  • 0.1.11: (7/18/14) Swipe movement, height padding
  • 0.1.10: (7/18/14) Fix $.width change
  • 0.1.9: (4/17/14) Cache child widths, transit.js support
  • 0.1.8: (2/25/14) Options for hover, easing, and configure_load function
  • 0.1.7: (10/27/13) Full height screen support, better events, classes for CSS animations
  • 0.1.6: (10/27/13) Full screen support, height no longer required
  • 0.1.5: (10/22/13) Fix moveToIndex, add moveToChild, fix non scrolling usage
  • 0.1.4: (9/30/13) IE7 fix - still doesn't center right
  • 0.1.3: (9/13/13) Always use outerWidth
  • 0.1.2: (8/27/13) Added events
  • 0.1.1: (8/26/13) Fixes for load/reload mouse issues. Child margins.
  • 0.1.0: (8/21/13) Initial release


Fork the project on github, edit away, and pull.

FilmRoll is written in CoffeeScript. To automatically compile to javascript, use the following command in the film_roll directory:

coffee -wc -o js/ coffee/*.coffee

Authors, License and Stuff

Code by Noel Peden and released under MIT license.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.