Warning: Use of undefined constant ENABLE_CACHE - assumed 'ENABLE_CACHE' (this will throw an Error in a future version of PHP) in /nfs/c04/h02/mnt/66302/domains/zackgrossbart.com/html/hackito/wp-config.php on line 79
Create Your Own Sliding Resizable Grid

Create Your Own Sliding Resizable Grid

by Zack Grossbart on August 12, 2009

Fork me on GitHub

I’ve focused on web programming for a while now, but I still miss GridBagLayout. GridBag is a Java layout manager and one of the best form layout managers I’ve used in any language. It makes it possible to create forms where any screen size is the perfect size.

There are a few different layout managers you can use with JavaScript, but they are mostly simple. I tend to skip them and just do the layout by hand using CSS. That’s why I was so excited when I saw the website for the English design firm Zaum & Brown. If you follow the link resize your browser window after the page loads.

See it
in Action

Your browser window is always the perfect size for the Zaum & Brown website. I really liked the effect so I’ve created an improved and simplified version of a sliding resizable grid and released it under the Apache License 2.0.

The HTML

The HTML for this grid is very simple. It uses three classes, slidegrid, cell, and bigcell. Check it out:

<div class="slidegrid">
    <div class="cell bigcell">Big Cell 1</div>
    <div class="cell">Cell 2</div>
    <div class="cell">Cell 3</div>
    <div class="cell">Cell 4</div>
    ...

The grid starts with the slidegrid class. This class is just a marker for the JavaScript code in slidegrid.js. After it finds slidegrid the JavaScript looks for cell classes underneath the slidegrid. I made mine div tags, but they could contain any other content.

slidegrid and cell would be enough for something simple, but I wanted to get a little fancy so I added the bigcell class. Every big cell is twice as large as a normal cell.

The JavaScript

Get the
source code

The JavaScript for this code is also relatively simple, and much of the credit for that goes to JQuery. The most important function here is alignGrid. It does all the heavy lifting of iterating through the div tags and lining them up in the grid.

Here’s a simplified version of the function. There is some extra handling in the real code for big cells, but I’ll let you find that on your own.

jQuery(".slidegrid").each(function() {
        
    var cols = Math.floor($(window).width() / ((cellWidth + padding) * 
        getComputedEm(jQuery(this))));
    
    jQuery(this).css("position", "relative");
    
    var children = jQuery(this).children("div");
    
    for (var i = 0; i < children.length; i++) {
        
        styleCell(children.eq(i), x, y, cellWidth, cellHeight, hasDrawn);
    }
    
    if ((count % cols) == 0) {
        
        /* 
         * This means it is time to bump down to the next row
         */
         
        curCol = 0;
        curRow++;
        x = 0;
        y += cellHeight + padding;
    } else {
        x += cellWidth + padding;
        curCol++;
    }
    
    count++;
});

When you resize the page we’re using an animation effect to show the cells moving. The animation is defined in the styleCell function. JQuery makes custom animation effects very easy so this function is very small.

function styleCell(cell, x, y, cellWidth, cellHeight, /*boolean*/animate) {
    if (animate) {
        /*
         * We only want to do the animation when the resize happens.
         */
        cell.animate({ 
            left: x + "em",
            top: y + "em"
            }, 500, "swing" );
    } else {
        cell.css({
            width: cellWidth + "em",
            height: cellHeight + "em",
            position: "absolute",
            left: x + "em",
            top: y + "em"
        });
    }
}

The last step is to make sure we redo the layout of the grid when the window is resized. For that we add a little bit of code to the document’s ready function.

$(document).ready(function() {
    alignGrid(10, 10, 1);
    
    /*
     * Redraw the grid when the page size changes
     */
    $(window).bind("resize", resizeWindow);
    function resizeWindow(e) {
        var newWindowHeight = $(window).height();
        alignGrid(10, 10, 1);
    }
});

This makes sure we align the grid the first time and then change it whenever the window is resized. That is really all it takes.

Get Creative

This is a simple mechanism, but it is powerful. The div tags are flexible enough to add almost any content. Please make use of this code and post a comment if you do so we can all check it out.

…and maybe one day I’ll feel ambitious enough to try to write GridBagLayout for JavaScript.