Reputation: 21684
I'm using the Masonry jQuery plugin to align a grid of items.
How can I achieve this effect? I've tried various options but nothing works.
Here's my HTML for each box:
<div class="sa-visual-grid-item" id="sa-visual-grid-item-<?=$id?>">
<div class="sa-selected-box"></div>
<input type="hidden" name="selected[<?=$id?>]" value="1" />
<img class="sa-img" src="<?=$img_url?>" />
<div class="sa-desc">
<div class="sa-name"><?=$name?></div>
<div class="sa-price"><?=$price?></div>
</div>
</div>
And CSS:
.sa-visual-grid {
height: auto;
margin: 0 auto;
text-align: center;
}
.sa-visual-grid-item {
background: white;
float: left;
width: 250px;
padding: 15px;
margin: 10px 15px;
border: 1px solid #bbb;
box-shadow: 0px 5px 15px 0px #efefef;
cursor:pointer;
text-align: center;
}
.sa-selected-box {
display: none;
position:absolute;
z-index:100;
border: 8px solid #00aa00;
width:254px;
padding:15px;
margin-top:-25px;
margin-left:-25px;
}
Upvotes: 3
Views: 4017
Reputation: 46
Old post, I know, but this might be helpful for others:
$('.grid').masonry({
horizontalOrder: true
});
After adding this to my JS file, the grid-items were all left justified.
Example:
$('.grid').masonry({
itemSelector: '.grid-item',
columnWidth: 160,
horizontalOrder: true
});
* { box-sizing: border-box; }
body { font-family: sans-serif; }
/* ---- grid ---- */
.grid {
background: #EEE;
max-width: 1200px;
counter-reset: grid-item;
}
/* clearfix */
.grid:after {
content: '';
display: block;
clear: both;
}
/* ---- grid-item ---- */
.grid-item {
width: 160px;
height: 120px;
float: left;
background: #D26;
border: 2px solid #333;
border-color: hsla(0, 0%, 0%, 0.5);
border-radius: 5px;
}
.grid-item--width2 { width: 320px; }
.grid-item--width3 { width: 480px; }
.grid-item--width4 { width: 720px; }
.grid-item--height2 { height: 200px; }
.grid-item--height3 { height: 260px; }
.grid-item--height4 { height: 360px; }
.grid-item:before {
counter-increment: grid-item;
content: counter(grid-item);
display: block;
color: white;
padding-top: 0.2em;
text-align: center;
font-size: 1.4rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.js"></script>
<h1>Masonry - horizontalOrder</h1>
<div class="grid">
<div class="grid-item grid-item--height2"></div>
<div class="grid-item grid-item--height3"></div>
<div class="grid-item"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item grid-item--height3"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item grid-item--height3"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
Upvotes: 3
Reputation: 31
I know this is old but I ran into the same problem and came across this post in my googling. I was able to solve this problem by slightly modifying the library. Modify the Masonry.prototype._getItemLayoutPosition function as follows (don't overlook the changes under //position the brick, and //apply setHeight) :
Masonry.prototype._getItemLayoutPosition = function( item, count ) {
item.getSize();
// how many columns does this brick span
var remainder = item.size.outerWidth % this.columnWidth;
var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
// round if off by 1 pixel, otherwise use ceil
var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
colSpan = Math.min( colSpan, this.cols );
var colGroup = this._getColGroup( colSpan );
// get the minimum Y value from the columns
var minimumY = Math.min.apply( Math, colGroup );
var shortColIndex;
if (this._getOption('alignLTR') == true)
{
shortColIndex = count - ((Math.floor(count / colGroup.length) * colGroup.length));
}
else {
shortColIndex = colGroup.indexOf(minimumY);
}
// position the brick
var position = {
x: this.columnWidth * shortColIndex,
y: colGroup[shortColIndex]
};
// apply setHeight to necessary columns
var setHeight = colGroup[shortColIndex] + item.size.outerHeight;
var setSpan = this.cols + 1 - colGroup.length;
for ( var i = 0; i < setSpan; i++ ) {
this.colYs[ shortColIndex + i ] = setHeight;
}
return position;
};
You'll also have to modify the loop that calls this function to pass in the count for each item as you loop through them.
proto._layoutItems = function( items, isInstant ) {
this._emitCompleteOnItems( 'layout', items );
if ( !items || !items.length ) {
// no items, emit event with empty array
return;
}
var queue = [];
var itemCount = 0;
items.forEach( function( item, itemCount ) {
// get x/y object from method
var position = this._getItemLayoutPosition( item, itemCount );
itemCount++;
// enqueue
position.item = item;
position.isInstant = isInstant || item.isLayoutInstant;
queue.push( position );
}, this );
this._processLayoutQueue( queue );
};
Finally, you'll have to set your new option 'alignLTR' to true when creating your grid.
var $grid = $('#myGrid').masonry({
isAnimated: true,
itemSelector: '.my-item',
alignLTR: true
});
Upvotes: 0
Reputation: 12582
You can't. It's an algorithm to pack bins most efficient. It's not designed to look good. Maybe you can try the wookmark plugin. There is also many others.
Upvotes: 2