eiriklv / react-masonry-component

A React.js component for using @desandro's Masonry
MIT License
1.44k stars 145 forks source link

If first item is wide enough, no positioning on whole list will work anymore #77

Open rodrigohgpontes opened 7 years ago

rodrigohgpontes commented 7 years ago

Hi, first of all, congrats and thanks for the component! It was a breeze to implement and worked as a charm to do exactly what I wanted, except... in this case when my first item is large enough.

I use the component as a <ul> and each <li> is resizable with an onclick that changes its state, which then changes its CSS class, which then alternate the CSS width between: 31%, 62%, and 97%.

When the first <li> is at width: 31%, everything works perfectly. But at the moment I change it to width: 62% all the positioning stops working, with one <li> per line (although the animation continues).

Here is the relevant code:

<Mansory elementType={'ul'} className={'board-area'}>
{ this.props.currentUser ? this.renderTasks() : ' ' }                 
</Mansory>   

renderTasks() returns a <li> with a lot of stuff inside, but nothing that matters I guess.

There is no big deal in the CSS too:

.priority-low {
width: 31%;
background: #282F3B;
}
.priority-medium {
width: 62%;
background: #0F1727;
}
.priority-high {
width: 97.3%;
background: #000010;
}

Comparing screenshots below so you can see the end result. Red border on the <ul> component, each square with a scrollbar is a <li>. The first screenshot has the first <li> on 31% and everything is fine. The second one has the first <li> on 62% and no positioning happens anymore (note that not in the first row, where should have space for one more <li>, not in the next rows).

The only change I make is in the width (and background color), but couldn't fix it.

The package is in production, so you can check it directly on my web app too: www.dediddo.com

Thanks!

screenshots

LittleMonsterAK commented 7 years ago

i have the same problem , can anyone help?

hurrtz commented 7 years ago

Oh dear god, and I thought I was the only one! I can absolutely back this up: If the first item (A) of a new row exceeds a certain width then the next item (B) will be moved to a new row, even if B would absolutely fit next to A on the same row.

The problem starts (at least in my case) when A exceeds width 31.7%.

By the way: This seems to be related to #68 but his solution (giving columnWidth the width of the smallest item) did not help in my case.

P.S: I tried to create a sample via webpackbin but everytime I try to use react-masonry-component I get a "module not found" error (other modules work, though). If anyone has a working example on webpackbin...?

hurrtz commented 7 years ago

Ok, here's a way to fix this: You have make sure that are items are of a magnitude of a base size.

Example: You have items that are 1/3 of the screen size wide, 1/2 and 2/3. The 1/2 will not fit because they are not of a magnitude of the 1/3 (which is why 2/3 will work).

Solution: Create a virtual grid that all items can work with. In my example that grid would be 1/12. So I created an element for columnWidth that had 1/12 of the size and voila: all my items suddenly positioned themselves correctly.

petertenhoor commented 7 years ago

@hurrtz My situation is exactly like your example. I have three items; one has 50% width and two have 25% width. And yet they are not aligning next to each other. The third item goes to a new row.

To which value did you set the columnWidth to fix this?

Edit: nevermind I found it. Just give the smallest element in your masonry a class and use that as the column-width like this:

const masonryOptions = { transitionDuration: 100, columnWidth: '.masonry-sizer' };

rntgspr commented 7 years ago

I have a similar problem here, I am still closing the points.

But on this line it's clear that uses masonry-layout and we can deal more with columnWidth here .

And it says:

We recommend setting columnWidth. If columnWidth is not set, Masonry will use the outer width of the first item.

econavi commented 4 years ago

Set option { columnWidth: 1 }
That is working for me)