-1

I have 4 divs which create 4 rows in a page. In each of these rows, are 4 square divs, so essentially we have a 4 x 4 block of (16) square divs.

When a user hovers over a div, the height is dynamically changed to be +40px. Right now, this adjusts the height of the parent container, and thusly pushes the rows below down.

What I want is to be able to push down ONLY the elements directly below the resized element.

Setup

<div class="row">
    <div class="element"></div>
    <div class="element"></div>
    <div class="element"></div>
    <div class="element"></div>
</div>
<div class="row">
    <div class="element"></div>
    <div class="element blue"></div>
    <div class="element"></div>
    <div class="element"></div>
</div>
<div class="row">
    <div class="element"></div>
    <div class="element"></div>
    <div class="element"></div>
    <div class="element"></div>
</div>
<div class="row">
    <div class="element"></div>
    <div class="element"></div>
    <div class="element"></div>
    <div class="element"></div>
</div>

http://jsfiddle.net/zW53T/1/

Desired Affect

And, then when the blue element is resized, the following behavior would happen (hacked with css to demonstrate desired behavior):

http://jsfiddle.net/dYnLn/1/

Is this possible? I thought it might be when using masonry, but I have used masonry very little and would not know where to even begin.

Any advice/pointers would be greatly appreciated.

Barry Chapman
  • 6,438
  • 3
  • 31
  • 55
  • Thats it?? no efforts?? – Milind Anantwar May 20 '14 at 09:20
  • Like I said.. I do not know where to begin. If there is a name for this behavior, I do not know it, and thus do not know what to search for on google. I have tried all the basics, with no luck. – Barry Chapman May 20 '14 at 09:21
  • http://masonry.desandro.com/ – qwetty May 20 '14 at 09:21
  • I could paste the javascript code that I have that invokes the behavior, but it is completely unrelated to what the end result would be. – Barry Chapman May 20 '14 at 09:21
  • @qwetty I already am aware of masonry, as I stated in my question. I just do not know how to use it to accomplish my desired result. – Barry Chapman May 20 '14 at 09:22
  • Not possible with current layout as they are in relatively positioned rows (outer divs). You will need to change to absolute positioning of elements and move around the ones that have the same `index` as the hovered one in subsequent rows. – Gone Coding May 20 '14 at 09:24

2 Answers2

2

You can use Shuffle.js

Sample:

$(document).ready(function() {
  var $grid = $('#grid'),
      $sizer = $grid.find('.shuffle__sizer');

  $grid.shuffle({
    itemSelector: '.picture-item',
    sizer: $sizer
  });
});

Options available with Shuffle:

// Overrideable options
Shuffle.options = {
    group: 'all', // Filter group
    speed: 250, // Transition/animation speed (milliseconds)
    easing: 'ease-out', // css easing function to use
    itemSelector: '', // e.g. '.picture-item'
    sizer: null, // sizer element. Can be anything columnWidth is
    gutterWidth: 0, // a static number or function that tells the plugin how wide the gutters between columns are (in pixels)
    columnWidth: 0, // a static number or function that returns a number which tells the plugin how wide the columns are (in pixels)
    delimeter: null, // if your group is not json, and is comma delimeted, you could set delimeter to ','
    buffer: 0, // useful for percentage based heights when they might not always be exactly the same (in pixels)
    initialSort: null, // Shuffle can be initialized with a sort object. It is the same object given to the sort method
    throttle: $.throttle || null, // By default, shuffle will try to throttle the resize event. This option will change the method it uses
    throttleTime: 300, // How often shuffle can be called on resize (in milliseconds)
    sequentialFadeDelay: 150, // Delay between each item that fades in when adding items
    supported: Modernizr.csstransforms && Modernizr.csstransitions // supports transitions and transforms
};
Chankey Pathak
  • 19,330
  • 10
  • 72
  • 119
1

Sorry I have not got the margins right yet, but you might want to try something like this using absolute positioning, changed on the fly (on a column basis):

JSFiddle: http://jsfiddle.net/TrueBlueAussie/dYnLn/5/

/* layout a single column based on element heights */
function layoutColumn(col) {
    var top = 0;
    $('.row').each(function () {
        var $row = $(this);
        var left = 0;
        var $cell = $row.children().eq(col);
        $cell.css({
                top: top
            });
        top = top + $cell.outerHeight() + ~~$cell.css("margin-top");
    });
}

/* layout the columns horizontal positions */
var top = 0;
$('.row').each(function () {
    var $row = $(this);
    var left = 0;
    /* set the horizontal positions */
    $row.children('.element').each(function () {
        var $cell = $(this);
        $cell.css({
            left: left
        });
        left += $cell.outerWidth() + ~~$cell.css('margin-left');
    });
    top = top + $row.outerHeight();
});

/* Layout all the columns */
for (var col = 0; col < $('.row').first().children().length; col++)
{
    layoutColumn(col);
}

$('.element').on('mouseenter', function(){
    $(this).addClass('blue').addClass('larger');
    layoutColumn($(this).index());
}).on('mouseleave', function(){
    $(this).removeClass('blue').removeClass('larger');
    layoutColumn($(this).index());
});

The layout code can obviously be simplified, but I threw this together quickly as an example of how to layout dynamically with jQuery.

Gone Coding
  • 88,305
  • 23
  • 172
  • 188