1px gap using Isotope Masonry (or Packery) expecialy on Safari - jquery-masonry

i'm sorry for my english.
It's many days that i try to figure out an issue that i see trying to create a responsive fullwidth grid of images. To create this grid I'm using Isotope with Masonry Layout (http://isotope.metafizzy.co/) or Packery (http://packery.metafizzy.co/layout.html). I have tried both and in both i have the same issue. For some resolution of my browser i see a 1px gap between images (as you can see in the images below).
I have read about this problem in many post (for example https://github.com/metafizzy/packery/issues/42) but no solution works for me. Anyone can help me?
At the moment my code is:
jQuery(window).load(function() {
var container = document.querySelector('.grid');
var pckry;
// using imagesLoaded http://desandro.github.io/imagesloaded
imagesLoaded( container, function() {
pckry = new Packery( container, {
itemSelector: '.grid-item',
rowHeight: '.grid-sizer',
percentPosition: true
});
});
});
I attach the final grid that i would like to have:

After many days of work i have been able to solve my issue thanks to DeSando, the plugins's author.
As he explain in this post http://metafizzy.co/blog/beyonce-seamless-fluid-image-masonry/ the gaps occur due to pixel rounding differences between JavaScript and CSS.
In my case i have a grid based on four columns and when the width of the browser wasn't divisible per 4 the gaps were born. So, as DeSandro suggests here, a workaround is to set container of images a little bit more smaller and cover the gaps with images a little bit more bigger. So, in my website:
HTML
<div class="grid">
<div class="grid-item" ><img src="..." title="" class="lazy"></div>
<div class="grid-item grid-item--width2 " ><img src="..." title="" class="lazy"></div>
<div class="grid-item grid-item--width2 "><img src="..." title="" class="lazy"></div>
<div class="grid-item" ><img src="..." title="" class="lazy"></div>
<div class="grid-item" ><img src="..." title="" class="lazy"></div>
...
</div>
CSS
.grid {
margin: 0 auto;
width: 100.4%;
margin-bottom: 0px !important;
}
.grid-sizer,.grid-item {
width: 24.9%;
display: block;
float: left;
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
list-style: none!important;
}
/* 2 columns wide */
.grid-item--width2 {
width: 49.8%;
display: block;
float: left;
}
.grid-item img{
display:block;
width: 100.4%;
max-width: 100.4% !important;
}
JS
// init Packery
var grid = jQuery('.grid').packery({
itemSelector: '.grid-item',
percentPosition: true
});
// layout Packery after each image loads
grid.imagesLoaded().progress( function() {
grid.packery();
});
I'm sorry for my english. I hope this could be useful for many of us.

Related

How to get text in a CSS grid nested in a flexbox to wrap first?

TL;DR: Here's a CodePen.
I have a UI with an image and a grid of text with long lines which looks like this:
I'm using CSS Flexbox with two elements: the image and the text. And then to lay out the text, I'm using CSS Grid. Now, when I view this on a narrow screen for mobile, it correctly wraps everything and stacks the two elements:
But on desktop, with a slightly narrower div, the flex box wraps before the grid text like this:
How can I get the text to wrap while leaving the flex box alone in this case? I fear I may need to use some media queries, but I'm not even sure if I'm using the right CSS components for this.
Here's the code:
index.html:
<div class="media-callout">
<div class="media-thumb">
<img height="170" width="120">
</div>
<div class="media-callout-grid">
<div class="media-callout-key">Authors</div>
<div>Babalola, J & Ogunkola, Babalola</div>
<div class="media-callout-key">Year</div>
<div>2013</div>
<div class="media-callout-key">Title</div>
<div class="media-callout-value">Scientific Literacy: Conceptual Overview, Importance and Strategies for Improvement</div>
<div class="media-callout-key">Journal</div>
<div><em>Journal of Educational and Social Research</em></div>
<div class="media-callout-key">Location</div>
<div>vol. 3, no. 1, pp. 265–274</div>
<div class="media-callout-key">DOI</div>
<div>10.5901/jesr.2013.v3n1p265</div>
</div>
</div>
style.css:
.media-callout {
display: flex;
flex-wrap: wrap;
justify-content: center;
row-gap: 20px;
column-gap: 10px;
padding: 1em;
max-width: max-content;
}
.media-thumb img {
float: left;
height: 175px;
width: auto;
}
.media-callout-grid {
display: grid;
font-size: 12pt;
grid-template-columns: 6em 1fr;
align-content: center;
gap: 0 15px;
}
.media-callout-key {
text-align: right;
font-weight: bold;
}
.media-callout-value {
word-break: break-word;
word-wrap: break-all;
}
A media query does indeed resolve this:
#media screen and (min-width: 600px) {
.media-callout {
flex-wrap: nowrap;
}
}
The query must come AFTER the .media-callout block. I also had to use this approach to prevent the image from being squashed.

Flexbox gap workaround for Safari

I finished my website but I didn't realize that safari doesn't support the flexbox gap. Is there a way around this without having the mess anything up? This is mostly for my media queries.
<div class="social-media">
<a href="https://github.com/">
<img class="social-media__icon" src="img/github.png" alt="Github">
</a>
<a href="https://www.linkedin.com/">
<img class="social-media__icon" src="img/linkedin.png" alt="LinkedIn">
</a>
</div>
.social-media {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
gap: 8rem;
margin-top: 10rem;
padding-bottom: 2rem;
}
.social-media img {
width: 90px;
height: 90px;
}
#media only screen and (max-width: 400px) {
.social-media {
gap: 3rem;
margin-top: 5rem;
}
.social-media img {
width: 62px;
height: 62px;
}
}
Use the Lobotomized owl selector: .parent > * + * {} to add a margin-left that gives you space between the elements that come after another element, this way you eliminate the undesired margin it creates when you put the margin directly to the child's first element (.social-media img{})
.social-media > * + * { margin-left: 8rem;}
Here you can read more about the Lobotomized Owl Selector
Edit: Gap is now supported in safari so you should be able to use it no problem.
Property gap with display: flex is not supported by Safar version < 14 https://caniuse.com/flexbox-gap .
You might want to replace display flex with grid:
display: grid;
grid-gap: 8rem; /* Safari 10-11 */
gap: 8rem; /* Safari 12+ */
because grid's gap is supported in older Safari versions: https://caniuse.com/mdn-css_properties_gap_grid_context
The accepted answer has the problem, that you will have a wrong margin on the first element if when there is only one row. Also centered elements will always be 8rem too far the right.
Better solution that will always work with correct spacings:
.container {
display: flex;
// the trick is to set margins around boxes, but correct the margins around elements that are situated at the border of the container with negative margins
margin: 0 -10px -20px -10px;
}
.box {
min-width: 100px;
height: 100px;
background-color: deeppink;
margin: 0 10px 20px 10px;
}
<div class='container'>
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
<div class='box'>4</div>
</div>
You can remove the gap class and add another one to child elements
<div class="d-flex"> // it was "d-flex gap" previously
<div class="mx-2">
//content
</div>
<div class="mx-2">
//content
</div>
</div>
I think you could make a div container and put justify-content: space-between; then i think it should work

Horizontal align text below flex-items

Image captions are aligned bottom by flexbox within a gallery where images have different heights. How can I achieve that first lines of text (titles) are aligned horizontally?
<style type="text/css">
* {
box-sizing: border-box; }
.flex-container {
display: flex;
flex-wrap: wrap; }
.flex-item {
width: 50%;
padding: 20px;
display: flex;
flex-direction: column; }
.flex-item img {
width: 100%;
height: auto; }
.flex-image {
flex: 1 0 auto; }
</style>
<div class="flex-container">
<div class="flex-item">
<div class="flex-image">
<img src="img-1.jpg" alt="" />
</div>
<p>title</p>
</div>
<div class="flex-item">
<div class="flex-image">
<img src="img-2.jpg" alt="" />
</div>
<p>title<br>Lorem ipsum dolor sit amet.</p>
</div>
</div>
Please check my codepen: https://codepen.io/tinusmile/pen/MoeORG
Many thanks!
With the existing markup, where the images can have different heights, you need to do something like this, where you give the p a height.
As an element's overflow defaults to visible, it will flow out of its boundaries, so I recommend to set the height so it can accommodate 2-3 lines of text.
On smaller screens you might need to add a #media query to adjust that height, as if the text is very long it might overflow any element below itself.
.flex-item p {
height: 50px; }
Updated codepen
Note, using min-height instead would solve the might overflow any element below itself issue, though it will make the first line to not align horizontally if the value does not accommodate all the possible amount of lines.
Another option is to remove the flex-item wrapper and use Flexbox's order property, as I suggested in a previous question of yours, align-horizontally-3-elements-over-3-divs

isotope packery layout ideal item sizes

I am trying to make a nice layout of items in a grid using a bin packing algorithm like packery or masonry. I Already have isotope installed so will use the packery plugin for that.
If you look at the example here http://codepen.io/desandro/pen/vdwmb this is exactly the kind of thing I need, but the problem I think I'm going to face is the content of the items are via a CMS.
<h1>Isotope - packery layout mode</h1>
<div class="grid">
<div class="grid-item grid-item--width2"></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--width2 grid-item--height2"></div>
<div class="grid-item grid-item--width2"></div>
<div class="grid-item grid-item--width2"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item grid-item--width2"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
* { box-sizing: border-box; }
body { font-family: sans-serif; }
/* ---- grid ---- */
.grid {
background: #DDD;
max-width: 1200px;
}
/* clear fix */
.grid:after {
content: '';
display: block;
clear: both;
}
/* ---- .grid-item ---- */
.grid-item {
float: left;
width: 100px;
height: 100px;
background: #0D8;
border: 2px solid #333;
border-color: hsla(0, 0%, 0%, 0.7);
}
.grid-item--width2 { width: 200px; }
.grid-item--height2 { height: 200px; }
$('.grid').isotope({
layoutMode: 'packery',
itemSelector: '.grid-item'
});
Possibly more of a maths question, but Im assuming for packery to work the items all have to be of a size in relation to each other, ie in the example above all the items are multiples of the smallest item.
Is this assumption correct, and is there anything else i need to consider?

Flexslider Slide Width Issue

I have a strange issue using flexslider. The Slide LIs don't get the correct width so that all slides are shown. This only occurs on first page load. As soon as I switch to another tab and switch back everything looks fine. Maybe a JS Loading Problem?!
Screenshot: here
flexslider.css
.flexslider {margin: 0; padding: 0;}
.flexslider .slides > li {text-align: center; display: none; -webkit-backface-visibility: hidden;} /* Hide the slides before the JS is loaded. Avoids image jumping */
.flexslider .slides li.flex-active-slide img {text-align:center; width: auto; -webkit-border-radius: 6px; -moz-border-radius: 6px; -o-border-radius: 6px; border-radius: 6px; box-shadow: 0 1px 4px rgba(0,0,0,.2); -webkit-box-shadow: 0 1px 4px rgba(0,0,0,.2); -moz-box-shadow: 0 1px 4px rgba(0,0,0,.2); -o-box-shadow: 0 1px 4px rgba(0,0,0,.2); }
JS
$(window).load(function() {
$('.flexslider').flexslider({
controlNav: true,
directionNav: true
});
});
I've tried it with $(document).ready(function() too, but still the same problem.
Any ideas?
Well, Werner.
I ended up with your solution. Unfortunately.
This is otherwise another way to do it.
/* SLIDERS in content */
$('.flexslider').flexslider({
animation: "slide",
start: function(slider){
$('.flexslider').resize();
}
});
The reason I chose not to use the above code is that there was a delay and made a little jump when the slides updated to the correct width.
If anyone has a cleaner solution - please tell me. I am using the latest flexslider there is - and this issue only seems to occur sometimes. But when it does... arghhh.
I had the same problem.
At first load in a session, Flexslider get the width of the slider container which, if it is not explicit, has value 0px.
Then slides have width 0px and you can't see them.
To avoid this problem is sufficient to fix a width in slider container, in my case 604px:
<div class="flexslider" style="width: 604px">
<ul class="slides">
<li>
<img id="slide1" />
</li>
<li>
<img id="slide2" />
</li>
</ul>
</div>
I faced the same issue with flexi slider.
Tried above mentioned solutions, but it didn't work for me.
I tried to updated css with following code as turn-around for this issue.
.flexslider .slides {
zoom: 1.1 !important;
}
It fixed the problem. You can try this code and let me know if it worked for you or not.
This code/order below may help; well at least I have had success with it.
<script src="js/jquery-1.8.3.min.js"></script>
<script src="js/jquery.easing.js"></script>
<script defer src="js/jquery.flexslider-min.js"></script>
<script>
$(document).ready(function(){
$('.flexslider').flexslider({
controlNav: true,
directionNav: true,
});
});
</script>
I resolved this issue by removing minItems in my flexslider call. Seems to work with maxItems though.
I found out why it was doing this, and it is pretty simple.
It is because of CSS!!! on the ul in the slider.
take off the paddings and the margins on the ul.slides
.slides{
padding:0;
margin:0;
}
after i did THIS the resizing worked perfect every time on all browsers and mobile.
For me, the problem was the markup. I had this:
<div class='carousel-slides'>
<div class='carousel-slide'></div>
<div class='carousel-slide'></div>
</div>
$('.carousel-slides', context).flexslider({
selector: '.carousel-slide'
});
... but it seemed that it needed to be applied to an inner div on each slide, which is ridiculous.
<div class='carousel-slides'>
<div class='carousel-slide'>
<div class='carousel-slide-inner'></div>
</div>
<div class='carousel-slide'>
<div class='carousel-slide-inner'></div>
</div>
</div>
$('.carousel-slides', context).flexslider({
selector: '.carousel-slide > .carousel-slide-inner'
});
Maybe it's a bit late for another answer, but after trying all the answers here and in other forums, I ended up with my own solution, similar to others, but at least I find it pretty coherent and clean.
I had the problem in mobile environment, where the slider is inside a tab that is opened as soon one clicks on the title. The content was in display:none, and this causes the problem to flexslider (v. 2.5), that is not able to determine the correct width of the contained slides.
So i corrected my css and put the container hidden by playng with visibility and opacity.
Html sampl
<dd class="tab-container with-slider">
<div class="flexslider">
<ul class="slides">
<li>whatever </li>
</ul>
</div>
</dd>
Css:
/*all other containers behave well with display none/block so I leave them with normal behavior*/
.parent dd.tab-container {
display: none; position: relative;
}
/*container with flexslider inside uses visibility and opacity to be hidden*/
.parent dd.tab-container.with-slider{
display: block;
height: 0px;
visibility: hidden;
opacity: 0;
}
.parent.accordion-open dd.tab-container.with-slider{
height: auto;
visibility: visible;
opacity: 1;
}
Js is straighforward from the basic example, nothing more.
$j('.myTabOpener').click(function () {
var mySlider = $j(this).find('.flexslider');
mySlider.flexslider({
animation: "slide",
animationLoop: false,
itemWidth: 210,
itemMargin: 5,
minItems: getGridSize(),
maxItems: getGridSize()
});
});

Resources