Ease group of blocks horizontally and Vertically

stackOverflow question

by Eric

HTML

<div class="block">
    <h2>I'm block 1</h2>
</div>
<div class="block">
    <h2>I'm block 2</h2>
</div>
<div class="block">
    <h2>I'm block 3</h2>
</div>
<div class="block">
    <h2>I'm block 4</h2>
</div>
<div class="block">
    <h2>I'm block 5</h2>
</div>
<div class="block">
    <h2>I'm block 6</h2>
</div>
<div class="block">
    <h2>I'm block 7</h2>
</div>

CSS

.block {
    width: 200px;
    height: 100px;
    float: left;
    margin: 20px;
    text-align: center;
    line-height: 100px;
    cursor: pointer;
}
.block:nth-child(1) {
    background: green;
}
.block:nth-child(2) {
    background: red;
}
.block:nth-child(3) {
    background: orange;
}
.block:nth-child(4) {
    background: pink;
}
.block:nth-child(5) {
    background: blue;
}
.block:nth-child(6) {
    background: yellow;
}
.block:nth-child(7) {
    background: brown;
}

JavaScript

$('.block').on('click', function() {
    var block = $(this);
    
    // Keep the blocks in line
    makeRows($('body')); // Update: Change parameter to container of the blocks
    
    $('.block').not(this).each(function() {
        
        // If sibling on the same level, horizontal toggle
        // We also want ignore the toggleMethod if it is shown because we might need to reassign
        if (($(this).position().top == block.position().top && (($(this).data('toggle') == -1) || $(this).data('toggle') == null)) || ($(this).data('toggle') != -1 && $(this).data('toggleMethod') == 'side'))
        {
            $(this).data('toggleMethod', 'side');
            
            // Hide block
            if ($(this).data('toggle') == -1 || $(this).data('toggle') == null)
            {
                // Set properties for later use in show block
                $(this).data('overflowBefore', $(this).css('overflow'));
                $(this).css('overflow', 'hidden');
                $(this).data('marginBefore', $(this).css('margin'));
                
                var width = $(this).width();
                $(this).animate({
                    width: 0,
                    margin: 0
                }, function() {
                    $(this).data('toggle', width);
                });
            }
            // Show block
            else
            {
                $(this).css('overflow', $(this).data('overflowBefore'));
                
                $(this).animate({
                    width: $(this).data('toggle'),
                    margin: $(this).data('marginBefore')
                }, function() {
                    $(this).data('toggle', -1);
                });
            }
        }
        // Do a normal vertical toggle
        else 
        {
            $(this).data('toggleMethod', 'top');
            $(this).slideToggle('slow');
        }
    });
    
});

// Make rows to make the blocks in line
function makeRows(container)
{
    // Make...