Force div to next column
Asked Answered
J

4

5

I'm creating an image grid using column-count. The issue with using columns is the fact, like text, even images get broken. So the top half of an image can be in one column and the bottom half can be in the second column. I solved this by adding display: inline-block to the items in the columns. That got me to my current problem:
With a column-count of 3 and with 7 items, the items are displayed as [3][3][1].

[item]   [item]   [item]
[item]   [item]
[item]   [item]

I would want the items to be displayed as [3][2][2]. So the question is: Can I force one of the divs to the next column?

HTML

<div id="container">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>

CSS

#container {
    column-count: 3;
    -moz-column-count: 3;
    -webkit-column-count: 3;
    width: 100%;
}
.item {
    background: red;
    /*-webkit-column-break-inside: avoid;
    -moz-column-break-inside:avoid;
    -moz-page-break-inside:avoid;
    page-break-inside: avoid;*/
    display: inline-block;
    height: 250px;
    margin-bottom: 20px;
    width: 100%;
}

jsfiddle

The part that is commented out is a second way of preventing the images to break, but it's less supported than a simple display:inline-block. It does the exact same thing.

I tried variating in height and using clear.

Update
Per requested, a little background information / use case.
The image grid will be used on a simple website for a restaurant. It will be used on several pages with two different functions. Function one is on the front page where eight images, in either portrait or landscape format, will function as links to the different pages. (8 images get divided properly [3][3][2]) The second function of the image grid will be, as an image grid. For example, the restaurant has a rich history and they have images dating back almost 100 years. More images might be added along the way. Using column count instead of three divs makes it easier to add images and it super easy to make responsive. The problem is that with certain amounts of images, like 7, the images don't get divided properly over the columns.

Update 2
I tried using the Masonry framework, but that worked sluggish.

Jovi answered 22/5, 2014 at 7:33 Comment(1)
Could you explain the use-case a bit ? Maybe there is another way to simulate the column layout ?Nero
H
2

If all else fails, you could insert a dummy div, though I feel dirty suggesting it! (and I'm not sure if it is viable for your setup).

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>

#container {
    column-count: 3;
    -moz-column-count: 3;
    -webkit-column-count: 3;
    width: 100%;
}
.item {
    background: red;
}

.item, .dummy {
    display: inline-block;
    height: 250px;
    margin-bottom: 20px;
    width: 100%;
}

</style>
</head>
<body>

<div id="container">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="dummy"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>

</body>
</html>
Hayott answered 22/5, 2014 at 7:43 Comment(3)
At the moment I can use this. Thanks. I'll accept this one if no other (better) answers come along.Jovi
works for me! do you mind putting in WHY you say this is dirty? maybe put in your 2 cents on what would be the 'right' way?Hindenburg
It's "dirty" because adding HTML purely for display purposes is best avoided. These days Grid would be a much better option.Hayott
A
6

I was looking for the solution in 2019 and that what I found. You can jump to next column in a css column-count layout with this trick :

<div id="container">
   <div class="item"></div>
   <div class="item"></div>    
   <div class="item"></div>
   <div class="item"></div>
</div>

#container {
    column-count: 3;
}
.item {
    break-inside: avoid-column;   
}
.item:nth-of-type(2){
    break-after:column;
    display:block;
}

This add a display:block property to the second ".item" element to force a break, the third ".item" will be displayed on top of the next column.

Check out there a working example : http://jsfiddle.net/n3u8vxLe/2/

Just tested it on Chrome 75, IE 11, Firefox 67 and it seems to be OK.

Anjanette answered 25/6, 2019 at 13:56 Comment(1)
Just a note in case any others come looking here. break-after:column does not work in firefox up to and included FF 76. caniuse.com/#search=columnFunkhouser
H
2

If all else fails, you could insert a dummy div, though I feel dirty suggesting it! (and I'm not sure if it is viable for your setup).

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>

#container {
    column-count: 3;
    -moz-column-count: 3;
    -webkit-column-count: 3;
    width: 100%;
}
.item {
    background: red;
}

.item, .dummy {
    display: inline-block;
    height: 250px;
    margin-bottom: 20px;
    width: 100%;
}

</style>
</head>
<body>

<div id="container">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="dummy"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>

</body>
</html>
Hayott answered 22/5, 2014 at 7:43 Comment(3)
At the moment I can use this. Thanks. I'll accept this one if no other (better) answers come along.Jovi
works for me! do you mind putting in WHY you say this is dirty? maybe put in your 2 cents on what would be the 'right' way?Hindenburg
It's "dirty" because adding HTML purely for display purposes is best avoided. These days Grid would be a much better option.Hayott
N
1

Depending on your use-case, if using columns layout is not necessary, you could simulate it with plain display:inline-block; or maybe display:table.

For the display:inline-block alternative, here is a fiddle:

http://jsfiddle.net/A4ZLc/1/

#container {
//    column-count: 3;
//    -moz-column-count: 3;
//    -webkit-column-count: 3;
    width: 100%;
    font-size:0px;
}
.item {
    background: red;
    display: inline-block;
    height: 100px;
    margin-bottom: 20px;
    box-sizing: border-box;
    width: 33%;
    padding-right: 10px;
    background-clip: content-box;
    font-size: 12px;
} 

Using a display:inline-table

http://jsfiddle.net/A4ZLc/2/

#container {
//    column-count: 3;
//    -moz-column-count: 3;
//    -webkit-column-count: 3;
    width: 100%;
    display:inline-table;
}
.item {
    background: red;
    height: 100px;
    box-sizing: border-box;
    width: 33%;
    padding-right: 10px;
    background-clip: content-box;
    float:left;
    margin-bottom: 20px;
}
Nero answered 22/5, 2014 at 8:0 Comment(5)
The problem is the items will be variable in height. Your method will cause gabs between the items that will not look that great.Jovi
Aha, i understood, I got another idea that might work, i will come back with a comment in a few minutes if it does work.Nero
Can't get it to work for 3 columns :( jsfiddle.net/A4ZLc/3 This is as far as I could take it.Nero
I see what you're trying to do. I appreciate the effort and it seems like a lot of effort. I'm all for simple solutions though.Jovi
You're welcome! Btw, if you are open to javascript solutions, this would be easy without using any library.Nero
E
0

Just using column-count: 3 with a width: 100* on children does the job for me:

.cols {
  column-count: 3;
}
.cols > * {
  display: block;
  width: 100%;
}

displays:

[item 1]  [item 5]  [item 9]
[item 2]  [item 6]  [item 10]
[item 3]  [item 7]  
[item 4]  [item 8]  
Escargot answered 19/10, 2020 at 15:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.