CSS Columns Bug - 5 Column Count Only Showing 4 (With Images)

CSS columns bug — 5 column count only showing 4 (with images)

Ok I have an answer, although it is a workaround, not a fix. I changed up the images so that some were 300px in height and others, 370px. Basically I varied the the height of the images and kept the width of all the images the same, 300px. So the answer is to either not use square images, or if you want to use all square images, use column-count:4 instead of 5.

If anyone can provide further insight into why this happens that would be great.

CSS column-count not respected

In your example (jsfiddle), there are 5 elements of equal size to be distributed into 4 columns. Since they won't fit next to each other (they are more than 4) , the first column will contain 2 elements. That defines the height of the container, so the second column will also get 2 elements, and so there's one remaining for the third column and none for the fourth column. There are four columns, but the fourth one is simply empty...

In other words: The height of the container is determined by the minimum height which is needed to fit all elements into the number of columns. Once that is done, the content will be filled into the columns starting from the left, and each column will get as much content as fits into it.

Chrome columns bug when number of columns is less then column-count

Based on how your markup looks like, the break-inside: avoid-column; should fix that, together with usingdisplay: block instead of display: inline-block (and you can drop width: 100%)

.outer {

-webkit-column-count: 3;

-moz-column-count: 3;

column-count: 3;

-webkit-column-gap: 30px;

-moz-column-gap: 30px;

column-gap: 30px;

}

.inner {

position: relative;

display: block;

margin-bottom: 40px;

line-height: 1.3;

break-inside: avoid-column;

}

.inner:nth-child(even) {

background: lightgray;

}
<div class="outer">

<div class="inner">

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.

</div>

<div class="inner">

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.

</div>

</div>

CSS column-count and Chrome bug: how to avoid overflow content being cropped

I'm not sure how you are styling your .onsale so I styled on my own way.

If you use position:relative in .pin and then position:absolute you can achieve what you want.

UPDATE: The issue is the webkit-column-count:1 in Chrome and since having that with 1 or nothing is the same, just remove it and use another technique that will allow you to have the .onsale out of flow by using position:absolute

#columns {



border: 1px solid red;



}

.pin {

width: 100%;

display: inline-block;

padding: 10px;

margin-bottom: 5px;

position: relative

}

.onsale {

min-height: 3.236em;

min-width: 3.236em;

padding: .202em;

font-size: 1em;

font-weight: 700;

position: absolute;

text-align: center;

line-height: 3.236;

top: -.5em;

left: -.5em;

margin: 0;

border-radius: 100%;

background-color: lightgreen;

color: white;

font-size: .857em;

-webkit-font-smoothing: antialiased;

}
<div id="columns">

<div class="pin">

<a href="#">

<span class="onsale">Sale!</span>

<img src="//placehold.it/300x300" />

</a>

<h3>Product 1</h3>

</div>

<div class="pin">

<a href="#">

<span class="onsale">Sale!</span>

<img src="//placehold.it/300x300" />

</a>

<h3>Product 2</h3>

</div>

</div>

Balancing height in column-count CSS columns that contain only images

EDIT:
If you don't need to keep line-height: 0 you would simply use .gallery img {display:block} and remove line-height, it's all you need. That would be the best. table-cell and so on can have some side-effects. For example vertical-align: middle leave a space under the images, and is just a hack.

https://jsfiddle.net/bruLwktv/


Challange accepted, here is the solution: ;)

The algorithm makes sure every images is loaded and then partition them into both coloumns in a way the have about the closest total height possible to create a minimal gap.

Using The greedy algorithm for the Partition problem to create Balanced partitions.

var gallery = document.getElementsByClassName("gallery")[0]

var images = gallery.getElementsByTagName("img")

var notLoaded = 0

window.onload = function() {

for (var i = images.length; i--;) {

if (images[i].width == 0) {

// let the image tell us when its loaded

notLoaded++

images[i].onload = function() {

if (--notLoaded == 0) {

allImgLoaded()

}

}

}

}

// check if all images are already loaded

if (notLoaded == 0) allImgLoaded()

}

function allImgLoaded() {

// Partition images

var imgs = partitionImages(images)

// reorder DOM

for (var i = images.length; i--;) {

gallery.appendChild(imgs[i])

}

}

function partitionImages(images) {

var groupA = [], totalA = 0

var groupB = [], totalB = 0

// new array width img and height

var imgs = []

for (var i = images.length; i--;) {

imgs.push([images[i], images[i].height])

}

// sort asc

imgs.sort(function(a, b) {

return b[1] - a[1]

});

// reverse loop

for (var i = imgs.length; i--;) {

if (totalA < totalB) {

groupA.push(imgs[i][0])

totalA += imgs[i][1]

} else {

groupB.push(imgs[i][0])

totalB += imgs[i][1]

}

}

return groupA.concat(groupB)

}
section {

background: magenta;

/* So you can see the area I don't want to appear */

}

.gallery {

width: 100%;

line-height: 0;

-webkit-column-count: 2;

-webkit-column-gap: 0;

-moz-column-count: 2;

-moz-column-gap: 0;

column-count: 2;

column-gap: 0;

}
<section class="gallery">

<div><img src="http://lorempixel.com/800/1000/"></div>

<div><img src="http://lorempixel.com/800/600/"></div>

<div><img src="http://lorempixel.com/800/200/"></div>

<div><img src="http://lorempixel.com/800/700/"></div>

<div><img src="http://lorempixel.com/800/900/"></div>

<div><img src="http://lorempixel.com/800/400/"></div>

<div><img src="http://lorempixel.com/800/200/"></div>

<div><img src="http://lorempixel.com/800/600/"></div>

<div><img src="http://lorempixel.com/800/700/"></div>

<div><img src="http://lorempixel.com/800/600/"></div>

<div><img src="http://lorempixel.com/800/550/"></div>

<div><img src="http://lorempixel.com/800/700/"></div>

<div><img src="http://lorempixel.com/800/600/"></div>

<div><img src="http://lorempixel.com/800/1000/"></div>

<div><img src="http://lorempixel.com/800/700/"></div>

</section>

CSS column layout has an incorrect column-count

Balancing columns

Here's the behavior I observed in FF, Chrome, and Opera:

1 element:    1 0 0
2 elements: 1 1 0
3 elements: 1 1 1

4 elements: 2 2 0 (expected: 2 1 1)
5 elements: 2 2 1
6 elements: 2 2 2

7 elements: 3 3 1 (expected: 3 2 2)
8 elements: 3 3 2
9 elements: 3 3 3

With 4 and 7 elements, the browser is choosing to balance the first 2 columns, rather than spreading the elements out over as many columns as possible.

Order of the elements

The columns are filled sequentially when they're balanced. In other words, if 8 elements are added to 3 columns, the columns will be filled as shown below:

1    4    7 
2 5 8
3 6

...rather than like this:

1    2    3 
4 5 6
7 8

Demo (tested in FF, Chrome, Opera)

css columns: last column is not filled

In your example, there are 9 elements of equal size to be distributed into 4 columns. Since they won't fit into 4 columns when the first column contains 2 elements (which would add up to a maximum of 8), the first column will contain 3 elements. That defines the height of the container, so the second column will also get 3 elements, and so there's also 3 remaining for the third column and none for the fourth column. There are four columns, but the fourth one is simply empty...

In other words: The height of the container is determined by the minimum height which is needed to fit all elements into the number of columns. Once that is done, the content will be filled into the columns starting from the left, and each column will get as much content as fits into it.

ADDITION AFTER COMMENT:

To get a distribution of elements as you want it, you have to insert empty DIVs - there is no other way (reason: read above):

.columns {

-webkit-column-count: 4;

/* Chrome, Safari, Opera */

-moz-column-count: 4;

/* Firefox */

column-count: 4;

}

.item {

display: inline-block;

width: 100%;

border: 1px solid red;

}

.empty {

display: inline-block;

}
<div class="columns">

<div class="item">Lorem ipsum dolor sit amet 1</div>

<div class="item">Lorem ipsum dolor sit amet 2</div>

<div class="item">Lorem ipsum dolor sit amet 3</div>

<div class="item">Lorem ipsum dolor sit amet 4</div>

<div class="item">Lorem ipsum dolor sit amet 5</div>

<div class="empty"></div>

<div class="item">Lorem ipsum dolor sit amet 6</div>

<div class="item">Lorem ipsum dolor sit amet 7</div>

<div class="empty"></div>

<div class="item">Lorem ipsum dolor sit amet 8</div>

<div class="item">Lorem ipsum dolor sit amet 8</div>

</div>

CSS columns styling only works on one column in Chrome

Someone mentioned here that they managed to fix this by adding transform: translateZ(0) to the grid item to enable hardware acceleration, in this case:

.grid-cell-container {
transform: translateZ(0)
}


Related Topics



Leave a reply



Submit