how to replicate pinterest.com's absolute div stacking layout

JqueryCssLayout

Jquery Problem Overview


I am looking to replicate Pinterest.com's div layout, specifically how the number of columns adjusts to fit more/less on browser resize and the vertical stacking is not dependent on adjacent column heights. The source code shows that each div is position absolute. A co-founder has answered a Quora post stating it is done with custom jQuery and CSS. I would like the results sorted left to right. Any direction you could provide to make it myself would be greatly appreciated.

Jquery Solutions


Solution 1 - Jquery

I wrote the Pinterest script. The ID's are unrelated to the layout, and are used for other interaction-related JS. Here's the base of how it works:

Beforehand:

  • Absolutely position the pin containers
  • Determine column width
  • Determine margin between columns (the gutter)

Setup an array:

  • Get the width of the parent container; calculate the # of columns that will fit
  • Create an empty array, with a length equaling the # of columns. Use this array to store the height of each column as you build the layout, e.g. the height of column 1 is stored as array[0]

Loop through each pin:

  • Put each pin in the shortest column at the moment it is added
  • "left:" === the column # (index array) times the column width + margin
  • "top:" === The value in the array (height) for the shortest column at that time
  • Finally, add the height of the pin to the column height (array value)

The result is lightweight. In Chrome, laying out a full page of 50+ pins takes <10ms.

Solution 2 - Jquery

You could also check on the jQuery Plug-in Masonry, for this kind of functionality.

Solution 3 - Jquery

We released a jQuery plugin because we got the same question several times for Wookmark. It creates exactly this type of layout. View it here - Wookmark jQuery plugin

Solution 4 - Jquery

Having looked at all options, I ended up implementing the layout similar to Pinterest in this way:

All DIVs are:

div.tile {
    display: inline-block;
    vertical-align: top;
}

This makes them position in rows better than when they are floated.

Then when the page is loaded, I iterate all DIVs in JavaScript to remove gaps between them. It works acceptably well when:

  1. DIVs are not very different in height.
  2. You don't mind some minor violations of ordering (some elements that were below can be pulled up above).
  3. You don't mind the bottom line being of different height.

The benefit of this approach - your HTML make sense for search engines, can work with JavaScript disabled/blocked by firewall, the sequence of elements in HTML matches the logical sequence (the newer items before older)

Solution 5 - Jquery

They split entities by columns with ids (bad solution... better use class names) and then calculate positions by column groups

Solution 6 - Jquery

You could use floats and size your div widths using percentages together with min-width to force divs to automatically fall of once minimum width is reached? Its the way we got it working on http://www.goldtree.co.za/work

Solution 7 - Jquery

Why dont you try this, simple js stuff

http://vanilla-masonry.desandro.com/index.html

Or even this with jQuery and having scroll loading as well.

http://masonry.desandro.com/index.html

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionchricksoView Question on Stackoverflow
Solution 1 - JqueryEvan SharpView Answer on Stackoverflow
Solution 2 - JqueryBob.View Answer on Stackoverflow
Solution 3 - JqueryGBKSView Answer on Stackoverflow
Solution 4 - JqueryespView Answer on Stackoverflow
Solution 5 - Jqueryant_TiView Answer on Stackoverflow
Solution 6 - JqueryI Am GoldtreeView Answer on Stackoverflow
Solution 7 - JqueryA Bright WorkerView Answer on Stackoverflow