Jan 4, 2013

Creating a Pinterest Like Layout in ASP.NET

Pinterest is currently the world’s fastest growing social networking site and famous for the best functioning visual design. Do you love the look and feel of Pinterest? This post explains how to implement the same masonry dynamic layout with infinite scroll in ASP.NET.

techbrij pinterest

Here are the steps to implement it:

1. Download and add jQuery Masonry plugin. It is a dynamic grid layout plugin which arranges elements vertically, positioning each element in the next open spot in the grid and minimizes vertical gaps between elements of varying height.

2. We are going to display product with description in each tile. Here is the structure of Product and ProductRepository class.

public class Product {
    public string Url { get; set; }
    public string Description { get; set; }

public static class ProductRepository
    static List<Product> objList;
    public static IEnumerable<Product> GetData(int pageIndex, int pageSize)
       int startAt = (pageIndex-1) * pageSize;
        objList =new List<Product>();
        Product obj;
        Random r = new Random();
        int n = r.Next(1, 7);    
        for (int i = startAt; i < startAt + pageSize; i++)
            n = r.Next(1, 7);
            obj = new Product();
            obj.Url = String.Format("http://dummyimage.com/150x{1}/{0}{0}{0}/fff.png&text={2}", n, n * 50,i+1);
            obj.Description = "Description of product " + (i+1).ToString();
        return objList;

In ProductRepository, GetData method takes pageIndex and pageSize parameters and generates dummy data and images of random heights.

HTML Structure:

3. In the aspx page, the head tag structure is as follows:

<head id="Head1" runat="server">
    <title>Pinterest Like Layout</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <!--[if lt IE 9]><script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
    <style type="text/css">
            margin: 5px;
            padding: 10px;
            box-shadow: 0 1px 3px rgba(34, 25, 25, 0.4);
    <script src="Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery.masonry.min.js" type="text/javascript"></script>

4. To display products, we use Repeater control:

 <div id="container" class="transitions-enabled infinite-scroll clearfix">
        <asp:Repeater ID="Repeater1" runat="server">
                <div class="box">
                    <img src="<%# Eval("Url") %>" />
                    <p><%# Eval("Description") %></p>
    <div id="imgLoad">
        <img src="http://i.imgur.com/6RMhx.gif" />

Dynamic Grid Layout:

5. To bind repeater on Page_Load:

        Repeater1.DataSource = ProductRepository.GetData(1, 25); 

Now, the product is displayed in normal order. If there is variance in each tile height then there is unnecessary blank space between rows. For dynamic grid layout, the following javascript code is used:

			var $container = $('#container');

            $container.imagesLoaded(function () {
                    itemSelector: '.box',
                    columnWidth: 100,
                    isAnimated: true

You can see the products are reordered to minimize vertical spacing.

Infinite Scrolling:

6. To implement infinite scrolling, lets create a webmethod on aspx side:

    public static IEnumerable<Product> GetData(int pageNo, int pageSize)
        return ProductRepository.GetData(pageNo, pageSize); 

We call this method using jQuery ajax on scrolling, add products dynamically and reorder products

 var pageNo = 1,pageSize = 25;
  $(window).scroll(function () {
                if ($(window).scrollTop() == $(document).height() - $(window).height() && !($('#imgLoad').is(':visible'))) {

            function loadMore() {
                    type: "POST",
                    url: "Default.aspx/GetData",
                    data: JSON.stringify({ pageNo: pageNo + 1, pageSize: pageSize }),
                    dataType: "json",
                    contentType: "application/json",
                    complete: function (response) {                       
                    success: function (response) {
                        if (response.d.length > 0) {
                            var ctrls = [];
                            for (var i = 0; i < response.d.length; i++) {
                                ctrls.push('<div class="box"> <img src="' + response.d[i].Url + '" /><p>' + response.d[i].Description + '</p></div>');
                            var $newElems = $(ctrls.join(''));
                            $newElems.css({ opacity: 0 });
                            $newElems.imagesLoaded(function () {
                                // show elems now they're ready
                                $newElems.css({ opacity: 1 });
                                $container.masonry('appended', $newElems, true);


Hope, you enjoy it.


  1. i have 2 tab in a page both page have 1-1 repeater control so how can i manage this pinterest layout i tried to apply but not done perfectly so please anyone help me to solve

  2. line 26 ,change $container to $(‘#container’)



    $newElems.css({ opacity: 0 });

    $newElems.imagesLoaded(function () {

    // show elems now they’re ready

    $newElems.css({ opacity: 1 });

    $(‘#container’).masonry(‘appended’, $newElems, true);


    This solution works for me :D

      1. i have change the css to
        .box {
        margin: 5px;
        padding: 10px;
        background-color: #FFFFFF;
        box-shadow: 0 1px 3px rgba(34, 25, 25, 0.4);

        its working now… bt still not as per the demo tutorial

  3. Even i am also not able to use this code images are displaying in row format not like pinterest please help

  4. Great article ..
    it is working perfect..
    but question is only first page Links are tracking by google…
    others which loading with jquery are not tracking by google nor any sitemap generatro
    do u have any idea??
    thanks in advance

  5. HI , I am trying your code but do not work. Server side request sent when scrolling and success response is also got in loadMore() function. This statement $container.masonry(‘appended’, $newElems, true); does not append content in screen. And also images are displayed row by row not pinterest syle.

Leave a Reply

Your email address will not be published. Required fields are marked *