- Overview
- Documents
Packery is a JavaScript layout library that uses a bin-packing algorithm. This is a fancy way of saying “it fills empty gaps.” Packery layouts can be intelligently ordered or organically wild. Elements can be stamped in place, fit in an ideal spot, or dragged around.
Source: packery.metafizzy.co
1. INCLUDE CSS AND JS FILES
<link rel="stylesheet" href="css/packery-docs.css" /> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="/path/to/packery.pkgd.min.js"></script>
2. HTML
Packery works on a container element with a group of similar child items.
<div id="container"> <div class="item">...</div> <div class="item w2">...</div> <div class="item">...</div> ... </div>
3. CSS
All sizing of items is handled by your CSS.
.item { width: 25%; } .item.w2 { width: 50%; }
4. JAVASCRIPT
Initialize a Packery instance as a jQuery plugin: $('#container').packery().
var $container = $('#container'); // init $container.packery({ itemSelector: '.item', gutter: 10 });
Initialize a Packery instance with new Packery( element, options ). The Packery constructor accepts two arguments: the container element and an options object.
var container = document.querySelector('#container'); var pckry = new Packery( container, { // options itemSelector: '.item', gutter: 10 });
5. OPTIONS
containerStyle
Type: Object
Default: { position: 'relative' }
CSS styles that are applied to the container element. To disable Packery from setting any CSS to the container element, set containerStyle: null.
columnWidth
Type: Number, Element, or Selector String
The width of a column of a horizontal grid. When set, Packery will align item elements horizontally to this grid.
"columnWidth": 60
If set to an Element or Selector String, Packery will use the width of that element. See Element sizing. Setting columnWidth with element sizing is recommended if you are using percentage widths.
<div id="column-width-demo2"> <div class="grid-sizer"></div> <div class="item"></div> <div class="item"></div> ... </div>
#column-width-demo2 .grid-sizer, #column-width-demo2 .item { width: 20%; } #column-width-demo2 .item.w2 { width: 40%; }
"columnWidth": ".grid-sizer", "itemSelector": ".item"
gutter
Type: Number, Element, or Selector String
The space between item elements, both vertically and horizontally.
"gutter": 10
If set to an Element or Selector String, Packery will use the width of that element.
<div id="gutter-demo2"> <div class="gutter-sizer"></div> <div class="item"></div> <div class="item"></div> ... </div>
#gutter-demo2 .gutter-sizer { width: 3%; }
"columnWidth": ".gutter-sizer", "itemSelector": ".item"
isHorizontal
Type: Boolean
Arranges items horizontally instead of vertically.
"isHorizontal": true
/* containers need height set when horizontal */ .packery.horizontal { height: 200px; }
isInitLayout
Type: Boolean
Default: true
Enables layout on initialization. Set this to false to disable layout on initialization, so you can use methods or add events before the initial layout.
var $container = $('#container').packery({ // disables initial layout isInitLayout: false }); $container.packery( 'on', 'layoutComplete', function() { console.log('layout is complete'); }); // manually trigger initial layout $container.packery();
isOriginLeft
Type: Boolean
Default: true
Controls the horizontal flow of the layout. By default, item elements start positioning at the left. Set to false for right-to-left layouts.
"isOriginLeft": false
isOriginTop
Type: Boolean
Default: true
Controls the vertical flow of the layout. By default, item elements start positioning at the top. Set tofalse for bottom-up layouts. It’s like Tetris!
"isOriginTop": false
isResizeBound
Type: Boolean
Default: true
Binds layout to window resizing.
isResizeBound binds layout only when the Packery instance is first initialized. You can bind and unbind resize layout afterwards with the bindResize and unbindResize methods.
itemSelector
Type: Selector String
Specifies which child elements to be used as item elements. Setting itemSelector is always recommended. itemSelector is useful to exclude sizing elements.
"itemSelector": ".item"
rowHeight
Type: Number, Element, or Selector String
Height of a row of a vertical grid. When set, Packery will align item elements vertically to this grid.
"rowHeight": 60
If set to an Element or Selector String, Packery will use the height of that element.
<div id="row-height-demo2"> <div class="grid-sizer"></div> <div class="item"></div> <div class="item"></div> ... </div>
#row-height-demo2 .grid-sizer { height: 60px; }
"columnWidth": ".grid-sizer", "itemSelector": ".item"
stamp
Type: Element, NodeList, Array of Elements, or Selector String
Specifies which elements are stamped within the layout. These are special layout elements which will not be laid out by Packery. Rather, Packery will layout item elements around stamped elements.
The stamp option stamps elements only when the Packery instance is first initialized. You can stamp additional elements afterwards with the stamp method.
<div id="stamp-opt-demo"> <div class="stamp stamp1"></div> <div class="stamp stamp2"></div> <div class="item"></div> <div class="item"></div> .... </div>
"itemSelector": ".item", "stamp": ".stamp"
/* position stamped elements with CSS */ #stamp-opt-demo { position: relative; } #stamp-opt-demo .stamp { position: absolute; width: 30%; height: 60px; background: red; border: 4px dotted white; } #stamp-opt-demo .stamp1 { left: 20%; top: 10px; } #stamp-opt-demo .stamp2 { right: 10%; top: 80px; }
transitionDuration
Type: String
Default: "0.4s"
The time duration of transitions for item elements.
Element sizing
For the sizing options columnWidth, rowHeight, and gutter, you may set these options to anElement or String, in addition to a Number.
With an Element, Packery will use its width or height to set the value of the related property.
<div id="container"> <div class="grid-sizer"></div> <div class="item"></div> <div class="item"></div> ... </div>
var $container = $('#container').packery({ itemSelector: '.item', columnWidth: $container.find('.grid-sizer')[0] });
With a String, Packery will use the string as a selector to get the first matching element within the container element. The size of that element is then used.
"columnWidth": ".grid-sizer"
This allows you to control the size of the Packery layout just with your CSS. This is useful for responsive layouts, keeping control within CSS so you can rely on media queries.
/* 5 columns by default */ .grid-sizer { width: 20%; } @media screen and (min-width: 720px) { /* 10 columns for larger screens */ .grid-sizer { width: 10%; } }
If you are using element sizing, be sure to set itemSelector as well, so the sizing element does not get used in the layout.
6. METHODS
Methods are actions taken on Packery instances.
If you are using jQuery, methods follow the jQuery UI pattern.
$('#container').packery() .append( elem ) .packery( 'appended', elem ); // no method is same as layout -> .packery('layout') .packery();
jQuery chaining is broken by methods that return values (i.e. getItemElements, getItem, on, andoff).
// chaining works with 'fit' method $container.packery( 'fit', elem ).fadeIn(); // 'on' method breaks jQuery chaining $container.packery( 'on', 'layoutComplete', function() {...} ); $container.fadeIn();
With vanilla JS, methods are on the Packery instance.
var pckry = new Packery('#container'); container.appendChild( elem ); pckry.appended( elem ); pckry.layout();
addItems
$container.packery( 'addItems', elements ) // or with vanilla JS pckry.addItems( elements )
-
elements
Type: Element, NodeList, or Array of Elements
Add item elements to the Packery instance.
appended
$container.packery( 'appended', elements ) // or with vanilla JS pckry.appended( elements )
-
elements
Type: Element, NodeList, or Array of Elements
Add and lay out newly appended item elements.
var $container = $('#container').packery(); $('#append').on( 'click', function() { // create new item elements var elems = []; for ( var i = 0; i < 3; i++ ) { var elem = getItemElement(); elems.push( elem ); } // append elements to container $container.append( elems ); // add and lay out newly appended elements $container.packery( 'appended', elems ); });
bindDraggabillyEvents
$container.packery( 'bindDraggabillyEvents', draggie ) // or with vanilla JS pckry.bindDraggabillyEvents( draggie )
-
draggie
Type: Draggabilly
bindResize
$container.packery('bindResize') // or with vanilla JS pckry.bindResize()
Binds event listener to window resize, so layout is triggered when the browser window is resized.
bindUIDraggableEvents
$container.packery( 'bindDraggabillyEvents', $elements ) // or with vanilla JS pckry.bindUIDraggableEvents( $elements )
-
$element
Type: jQuery
destroy
$container.packery('destroy') // or with vanilla JS pckry.destroy()
Removes the Packery functionality completely. This will return the element back to its pre-initialized state.
var $container = $('#container').packery(); var isActive = true; $('#destroy-button').on( 'click', function() { if ( isActive ) { $container.packery('destroy'); } else { $container.packery(); } isActive = !isActive; });
fit
$container.packery( 'fit', element, x, y ) // or with vanilla JS pckry.fit( element, x, y )
-
element
Type: Element
-
x
Type: Number
Horizontal position of element, optional
-
y
Type: Number
Vertical position of element, optional
Fit an item element within the layout, and have other item elements laid out around it. This method is useful when expanding an element, and keeping it in its same position.
var $container = $('.packery').packery(); $container.on( 'click', '.item', function( event ) { var $target = $( event.target ) var isGigante = $target.hasClass('gigante'); $target.toggleClass('gigante'); if ( isGigante ) { // if shrinking, just layout $container.packery(); } else { $container.packery( 'fit', event.target ); } });
You can optionally set a new position of the element. x and y values are relative to the container.
var $container = $('#container').packery(); $container.on( 'click', '.item', function( event ) { $container.packery( 'fit', event.target, 80, 80 ); });
getItemElements
var elems = $container.packery('getItemElements') // or with vanilla JS var elems = pckry.getItemElements()
-
returns
itemElems
Type: Array
Get an array of elements used as the Packery instance's items.
getItem
var item = $container.packery( 'getItem', element ) // or with vanilla JS var item = pckry.getItem( element )
-
element
Type: Element
-
returns
item
Type: Packery.Item
Get a Packery.Item from an element.
layout
$container.packery() // or with vanilla JS pckry.layout()
Lay out all item elements.
var $container = $('#container').packery(); $container.on( 'click', '.item', function( event ) { // change size of item via class $( event.target ).toggleClass('gigante'); // trigger layout $container.packery(); });
layoutItems
$container.packery( 'layoutItems', items, isStill ) // or with vanilla JS pckry.layoutItems( items, isStill )
-
items
Type: Array of Packery.Items
-
isStill
Type: Boolean
Disables transitions
Lay out specified items.
off
var pckry = $container.packery( 'off', eventName, listener ) // or with vanilla JS pckry.off( eventName, listener )
-
eventName
Type: String
name of a Packery event
-
listener
Type: Function
-
returns
pckry
Type: Packery
Remove an event listener.
on
var pckry = $container.packery( 'on', eventName, listener ) // or with vanilla JS pckry.on( eventName, listener )
-
eventName
Type: String
name of a Packery event
-
listener
Type: Function
-
returns
pckry
Type: Packery
Add an event listener for certain events.
Unlike jQuery's on, Packery's on only works with the specified events. pckry.on( 'click', function() {...}) will not work.
To listen for an event just once, return true in the event listener.
pckry.on( 'layoutComplete', function() { console.log('layout is complete, just once'); return true; });
once
var pckry = $container.packery( 'on', eventName, listener ) // or with vanilla JS pckry.on( eventName, listener )
Add an event listener for certain events, to be triggered once.
$container.packery( 'once', 'layoutComplete', function() { console.log('layout is complete, just once') });
Packery.data
var pckry = Packery.data( element )
-
elements
Type: Element
-
returns
pckry
Type: Packery
Get the Packery instance from an element. Note this method is of Packery, rather than of a Packery instance.
This method is useful to access the Packery instance after it was initialized via HTML.
<div id="container" class="js-packery" data-packery-options='{...}'> <div class="item"></div> <div class="item"></div> ... </div>
var container = document.querySelector('#container'); var pckry = Packery.data( container ); // do stuff with Packery instance pckry.layout();
prepended
$container.packery( 'prepended', elements ) // or with vanilla JS pckry.prepended( elements )
-
elements
Type: Element, NodeList, or Array of Elements
Add and lay out newly prepended item elements at the beginning of layout. Similar to appended.
var $container = $('#container').packery(); $('#prepend-button').on( 'click', function() { // create new item elements var elems = []; for ( var i = 0; i < 3; i++ ) { var elem = getItemElement(); elems.push( elem ); } // append elements to container $container.prepend( elems ); // add and lay out newly appended elements $container.packery( 'prepended', elems ); });
reloadItems
$container.packery('reloadItems') // or with vanilla JS pckry.reloadItems()
Recollect all item elements.
remove
$container.packery( 'remove', elements ) // or with vanilla JS pckry.remove( elements )
-
elements
Type: Element, NodeList, or Array of Elements
Remove elements from the Packery instance, then from the DOM.
var $container = $('#container').packery(); $container.on( 'click', '.item', function( event ) { // remove clicked element $container.packery( 'remove', event.target ); // layout remaining item elements $container.packery(); });
stamp
$container.packery( 'stamp', elements ) // or with vanilla JS pckry.stamp( elements )
-
elements
Type: Element, NodeList, or Array of Elements
Stamp the elements in the layout. Packery will lay out item elements around stamped elements.
var $container = $('#container').packery({ // set itemSelector when using stamp itemSelector: '.item' }); var $stamp = $container.find('.stamp').first(); var isStamped = false; $('#toggle-button').on( 'click', function() { // stamp or unstamp element if ( isStamped ) { $container.packery( 'unstamp', $stamp ); } else { $container.packery( 'stamp', $stamp ); } // trigger layout $container.packery(); isStamped = !isStamped; });
unbindResize
$container.packery('unbindResize') // or with vanilla JS pckry.unbindResize()
Un-bind layout to window resize event.
unstamp
$container.packery( 'unstamp', elements ) // or with vanilla JS pckry.unstamp( elements )
-
elements
Type: Element, NodeList, or Array of Elements
7. EVENTS
Packery is an Event Emitter. You can bind listeners to events with the on, off, and once methods.
var $container = $('#container').packery({...}); function onLayout() { console.log('layout done'); } // bind event listener $container.packery( 'on', 'layoutComplete', onLayout ); // un-bind event listener $container.packery( 'off', 'layoutComplete', onLayout ); // bind event listener to be triggered just once $container.packery( 'once', 'layoutComplete', function() { console.log('layout done, just this one time'); });
dragItemPositioned
$container.packery( 'on', 'dragItemPositioned', function( pckryInstance, draggedItem ) {...} ) // or with vanilla JS pckry.on( 'dragItemPositioned', function( pckryInstance, draggedItem ) {...} )
-
pckryInstance
Type: Packery
the Packery instance
-
draggedItem
Type: Packery.Item
the dragged item that was positioned
Triggered after a drag end, only when an item is positioned, either into a row or column, or into its container element. This event is triggered after the positioning transition has ended.
// set up Packery and Draggabillies // like the bindDraggabillyEvents demo, then... $container.packery( 'on', 'dragItemPositioned', function( pckryInstance, draggedItem ) { notify( 'Packery positioned dragged ' + draggedItem.element.nodeName ); } );
fitComplete
$container.packery( 'on', 'fitComplete', function( pckryInstance, item ) {...} ) // or with vanilla JS pckry.on( 'fitComplete', function( pckryInstance, item ) {...} )
-
pckryInstance
Type: Packery
the Packery instance
-
item
Type: Packery.Item
items that was fit
Triggered after an item element is fit.
$container.packery( 'on', 'fitComplete', function( pckryInstance, item ) { notify( 'fit ' + item.element.className ); } );
layoutComplete
$container.packery( 'on', 'layoutComplete', function( pckryInstance, laidOutItems ) {...} ) // or with vanilla JS pckry.on( 'layoutComplete', function( pckryInstance, laidOutItems ) {...} )
-
pckryInstance
Type: Packery
the Packery instance
-
laidOutItems
Type: Array of Packery.Items
items that were laid out
Triggered after a layout and all positioning transitions have been completed.
$container.packery( 'on', 'layoutComplete', function( pckryInstance, laidOutItems ) { console.log('Packery layout completed on ' + laidOutItems.length + ' items'); } );
removeComplete
pckry.on( 'removeComplete', function( pckryInstance, removedItems ) {...} ) // or with vanilla JS $container.packery( 'on', 'removeComplete', function( pckryInstance, removedItems ) {...} )
Triggered after an item element has been removed.
-
pckryInstance
Type: Packery
the Packery instance
-
removedItems
Type: Array of Packery.Items
items that were removed
$container.packery( 'on', 'removeComplete', function( pckryInstance, removedItems ) { console.log( 'Removed ' + removedItems.length + ' items' ); } );