Masonry Tiles being placed with large gaps between them - masonry

Trying to get Masonry to work on a SaaS product for which I have little control over the DOM but full access to the CSS / JS library.
The problem is with the horizontal placement, not vertical (see attached image).
JSFiddle Here: https://jsfiddle.net/ny2texas/0wncosbr/
OR...
Here is what I am using to call masonry:
jQuery('.boxsitepagebody .blog-post-list').masonry({
// options
containerStyle: null,
itemSelector: '.sblog-post',
columnWidth: '.grid-sizer',
percentPosition: true,
gutter: 1
});
The CSS snippet I think is relevant:
.grid-sizer,.sblog-post
{
width: 20%
}
Below, The basic construct of the HTML. Note that the absolute placement ("left:40.1862%") is almost exactly 2x the 20% declared as the columnWidth above. But why is it skipping columns and placing the titles every OTHER column?
<ul id="blog_post_list_blog_blog_posts_list_0_1" class="blog-post-list sblog-post-newlist" style="height: 4301.2px;">
<li class="grid-sizer"></li>
<li class="sblog-post sblog-post-newstyle row1" style="position: absolute; left: 0%; top: 0px;"></li>
<li class="sblog-post sblog-post-newstyle row1" style="position: absolute; left: 40.1826%; top: 0px;"></li>
<li class="sblog-post sblog-post-newstyle row1" style="position: absolute; left: 0%; top: 545px;"></li>
<li class="sblog-post sblog-post-newstyle row1" style="position: absolute; left: 40.1826%; top: 692px;"></li>
...
</ul>

Problem solved.
I had to go into the masonry source code to figure this one out. First thing I had to do was to swap the minified code out for the full source code in GitHub so I could debug the process and placement of each tile.
The width of the tiles (with padding and border) were 179px and the widths of the columns was 175px (856 * 20% I had set in CSS). Since the tile was larger than the column, masonry set colspan to 2 meaning that each post occupied 2 columns (hence the gap). Since masonry has controls to auto pad the positioning of each post it assumes you aren't adding your own padding in CSS. I removed that padding (and the borders) so then 175 = 175px and the tiles placed properly.
To place the horizontal gap in tiling, use the "gutter" call to masonry().

Related

How to make 3 images in a 1x2 form in flexbox with the 2 equaling the height of the first?

So I want to make 3 images over 2 columns. The left image will be 100% of the height of the flexbox and I want to 2 right side images to be stacked top to bottom and their total height to equal the height of the left image or the flexbox height itself. When responsive resizing I want to keep this ratio as well.
The problem I'm having now is that upon resizing the left image shrinks and the combined height of the right 2 gets larger than the left image.
Thanks for trying to understand my jibberish.
I've tried a number of things and nothing working.
Using Flexbox
In order to accomplish what you are describing using flexbox you will need to use two flexboxes which will require making a few changes to the HTML.
The outer flexbox should have flex-direction: row; (this is the default value so it can be omitted). This will flex its children horizontally.
The inner flexbox should have flex-direction: column;. This will flex its children vertically.
The children of the first div should have flex: 1; which will distribute the space using an even ratio amongst the children.
You then just need to set height: 50%; for each of the images in the second flexbox.
Here's an example of what your code could look like:
.container,
body,
html {
width: 100%;
height: 100%;
margin: 0;
}
img {
object-fit: cover;
}
div {
display: flex;
}
img,
div {
flex: 1;
}
.right {
flex-direction: column;
}
.right>img {
height: 50%;
}
<div class="container">
<img src="https://source.unsplash.com/random?mountain">
<div class="right">
<img src="https://source.unsplash.com/random?city">
<img src="https://source.unsplash.com/random?cat">
</div>
</div>

Ag-Grid has zero height in a flexbox layout

My goal is to use ag-grid in an Angular 5 project and have the grid take up all of the available vertical space in a flexbox layout. The grid seems happy to use "height:100%" when it's contained in a div which has a defined pixel height or when the div has a percentage height but isn't in a flexbox layout. But it always seems to have no height when I try to host it in a flex item.
How can I get my grid to expand to take up the height of its flex item container? Here's a plunker with an example of what I'm seeing and trying: https://embed.plnkr.co/D8YgM6/.
Here's how I am creating my layout:
<div style="height:100%;display:flex;flex-direction:column;">
<div style="height:250px;flex-grow:0;">
<h5>Container div with specified height in pixels, ag-grid with percentage height</h5>
<ag-grid-angular style="width: 100%; height: 80%" class="ag-theme-balham"
[columnDefs]="columnDefs"
[rowData]="rowData"
>
</ag-grid-angular>
</div>
<div style="flex-grow:1;">
<h5 class="red">Container div using flex height, ag-grid with percentage height</h5>
<p>How can I get the grid to be aware of my div's actual height?</p>
<ag-grid-angular style="width: 100%; height: 80%;" class="ag-theme-balham"
[columnDefs]="columnDefs"
[rowData]="rowData"
>
</ag-grid-angular>
</div>
</div>
I want the grid in the second flex item to have an appropriate height. How can I do this?
In your plunker, set the flex-basis of the item containing your grid to 0, this achieves I think what you are after. I've just been wrestling with the same:
.item-1 {
flex-grow: 1;
flex-shrink: 0;
flex-basis: 0;
}
Plunker Screenshot running in Chrome
I'm not sure why this works, maybe someone with more in depth knowledge of ag-grid can comment?
try setting auto height on grid ready event
this.gridApi.setDomLayout('autoHeight');
details: https://www.ag-grid.com/javascript-grid-width-and-height/

Use react-virtualized Window Scroller with frozen header and footer

I am using react-virtualized WindowScroller with CellMeasurer to scroll through a 100 sample records and by itself, it works great.
Now, when I place this component in a content pane with a frozen header and footer (using flex) above and below it, react-virtualized does not bring in additional data beyond the first page.
The structure of my container page is the same as the create-react-app template:
<div className="App">
<div className="App-header" />
<div className="App-intro" />
<div className="App-footer" />
</div>
and here is the CSS I use to freeze the header and footer:
html, body, #root {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.App {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.App-header, .App-footer {
flex-shrink: 0;
}
.App-intro {
flex-grow: 1;
overflow-y: auto;
}
FWIW, the official WindowScroller example accomplishes a frozen header using flex, but try as I might, I am not able to replicate it on my end.
I am at my wit's end after spending a whole entire day on this. I would really really appreciate any pointers to get this flex layout going with a functional window-scroller.
In the CodeSandbox you linked to (codesandbox.io/s/52j0vv936p)- window "scroll" events aren't reaching WindowScroller. That's because the window isn't actually what's scrollable, rather it's the middle "body" part. If that's what you want, you don't need to use WindowScroller at all and should remove it.
The only thing left that's broken is that your AutoSizer isn't getting a valid height because one of its parent <div>s doesn't have a correct height. For Stack Overflow convenience, here's the relevant bit:
Why is my AutoSizer setting a height of 0?
AutoSizer expands to fill its parent but it will not stretch the parent. This is done to prevent problems with flexbox layouts. If AutoSizer is reporting a height (or width) of 0- then it's likely that the parent element (or one of its parents) has a height of 0. One easy way to test this is to add a style property (eg background-color: red;) to the parent to ensure that it is the correct size. (eg You may need to add height: 100% or flex: 1 to the parent.)
Here is a diff to your sandbox that shows what I'm talking about and here is a fixed Code Sandbox demo.

Jquery-Masonry almost always empty spaces

I've been trying Masonry but can't get it to work exactly as I wanted. The elements I use vary in width and height, but all fit in a grid (4 different sizes, all multiple of smallest+margins). I've also calculated a distribution of elements (7 of the smallest, 4 of all the others) that can fit precisely.
However it's rare that masonry manages to fit them neatly, sometimes there's one lurking at the bottom, sometimes several are misplaced. It's always so that in one view I can see what items need to be moved for it to fit.
Is there a way to make masonry more aggressive in moving elements? Or have it go over two times to make sure there are no empty spaces?
You should probably look at masonry's "big brother" Isotope here. Mind you, if you have elements that are sorted in a certain order or fixed in a certain order - and that are wider than a single column width - they can "block" a column at narrow browser widths.
EDIT Maybe this fiddle explains it a bit better. If you look at that one and - while observing the numbers in the divs - you see that the next masonry element up (the red element 5) can not possibly fit in the white square as it must come after element 4; so where it must end up means, that, with only three rows fitting, one gets a white gap. Maybe you can use Isotope's shuffle and/or reLayout methods and sacrifice ordering your elements in a strict order? Best would be a jsfiddle with your issue.
<article>
<div class="tile blue"><p>1</p></div>
<div class="tile black"><p>2</p></div>
<div class="tile tall yellow"><p>3</p></div>
<div class="tile grey"><p>4</p></div>
<div class="tile wide red"><p>5</p></div>
<div class="tile green"><p>6</p></div>
<div class="tile grey"><p>7</p></div>
<div class="tile blue"><p>8</p></div>
<div class="tile green"><p>9</p></div>
</article>
$('article').isotope({
itemSelector : '.tile',
masonry: {
columnWidth: 100
}
});
article .tile {
display: block;
float: left;
box-sizing: border-box;
width: 100px;
height: 100px;
font-size: 3em;
font-weight: 700;
padding: 0 6px;
color: #fff;
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
border:1px dotted black;
}
article .tile.wide {
width: 200px;
}
article .tile.tall {
height: 200px;
}
.tile.yellow { background: yellow; }
.tile.red { background: red; }
.tile.blue { background: blue; }
.tile.black { background: black; }
.tile.grey { background: grey; }
.tile.green { background: green; }
To expand on Dan's answer, having just had this problem myself, it seems that Packery is a more up to date; much more maintained version of Masonry - from the same author. It's not clear to me why both projects exist as separate entities, with only typos fixed in the latter.
The good news is - it's almost totally a drop-in replacement. The only change I had to make (other than names masonry->packery where used) was to remove an option, because it is the default and only option in Packery.
That was isFitWidth: true, my feeble attempt to make Masonry pack things something close to how nicely Packery does without any options at all.
Another nice change with Packery is that gutter: x applies to vertical as well as horizontal gutters. In Masonry, this was horizontal only - though trivial with margin-bottom in CSS, this felt like a needless hack.

CSS: Positioning components using margins

In the image below, you can see i have two tabs help and Instructions, i want to place these two tabs next to each other where the Help tab currently is. When i use the margin-left: property, only the help button moves to the left and the instructions button stays in the same place.
The css i am using to configure this:
.v-csslayout-topbarapplicant .v-button,
.v-csslayout-topbarapplicant .v-nativebutton,
.v-csslayout-topbarapplicant-invert .v-button,
.v-csslayout-topbarapplicant-invert .v-nativebutton {
float: right;
display: inline;
margin-right:0px;
margin-left: 268px;
margin-top: -18px;
padding: 0 3px 2px 0;
line-height: 11px;
}
How can i change the spacing so that both tabs (vaadin components) move together?
You need to make sure both items are wrapped with a div. Then you set the margin-left to that div, not only one of the items.
There's no way of telling in the CSS that you posted which items are being manipulated. If both of these items, "help" and "Instructions", are in the CSS you posted, then you to need to change it so that both items exist as one, meaning in one div. If only one of these items exist in your CSS that you posted, then you have only one of them being manipulated with the CSS, and that one is floating right. Ensure both items are floated in the same direction and they are wrapped. Apply the margin to this wrapper div.
The general structure should look like this:
CSS:
#help, #instructions {
float: right;
}
div#wrapper {
margin-left: 268px;
] /* wrapper containing both items, "help" and "Instructions" */
HTML:
<div id="wrapper">
<div id="help"></div>
<div id="instructions"></div>
</div>
I think that you are having some inheritance problems.
I would suggest first checking what inheritance this property is following, and if you still have problems I would then create separate divs for Help and Instructions, where instructions has a different right margin. I hope this helps! This type of problems are stubborn.

Resources