How do I get CSS columns to not spread out but instead bunch on the left
What I get
What I want
Example
body {
background-color: #c3dbff;
}
.cols {
columns: 250px; /* want however many 250px columns will fit */
}
.thing {
display: inline-block;
width: 240px;
background: red;
margin-bottom: 10px;
break-inside: avoid-column;
/* below just to make it clear the order of children in the columns */
color: white;
display: inline-grid;
place-content: center;
font-weight: bold;
font-family: sans-serif;
font-size: 50pt;
}
<div >
<div style="height: 200px;">1</div>
<div style="height: 200px;">2</div>
<div style="height: 290px;">3</div>
<div style="height: 280px;">4</div>
<div style="height: 200px;">5</div>
<div style="height: 230px;">6</div>
<div style="height: 260px;">7</div>
<div style="height: 210px;">8</div>
<div style="height: 280px;">9</div>
<div style="height: 230px;">10</div>
<div style="height: 260px;">11</div>
<div style="height: 210px;">12</div>
<div style="height: 200px;">13</div>
<div style="height: 270px;">14</div>
<div style="height: 220px;">15</div>
<div style="height: 260px;">16</div>
<div style="height: 250px;">17</div>
<div style="height: 290px;">18</div>
</div>
CSS only.
Things I tried,
setting
column-width: 250px
. ❌setting the outer container to
display: inline-block;
❌setting the outer container to
margin: 0 auto 0 0
❌setting
column-gap: 10px
❌setting
display: flex; flex-direction: column; flex-wrap: wrap
❌This doesn't work because in order to wrap I'd have to give the flex box a height, otherwise it has no idea it needs to wrap. That's different that
columns
which will figure out height after figuring out how many columns.
One thing that makes it hard to find an answer is most results about columns
are not about the css columns
property but about columns in tables, or grids, or flexbox
PS: No, I'm not trying to do a masonry layout out. I want the items to go down the first column, then flow into the second (vs masonry where they flow to the right first and then fill in the shortest column. not looking for that).
CodePudding user response:
It seems your items has fixed sizes so you can use CSS grid to fix this. The trick is to create as many columns with fixed width as possible and span all of them using grid-column: 1/-1
body {
background-color: #c3dbff;
}
.wrapper {
display:grid;
grid-template-columns:repeat(auto-fit,250px); /* same as column width */
gap:10px; /* same as column gap */
}
.cols {
columns: 250px;
column-gap: 10px;
grid-column:1/-1; /* take all the columns of the grid*/
}
.thing {
display: inline-block;
width: 100%; /* use 100% and rely on the gap */
background: red;
margin-bottom: 10px;
break-inside: avoid-column;
color: white;
display: inline-grid;
place-content: center;
font-weight: bold;
font-family: sans-serif;
font-size: 50pt;
}
<div >
<div >
<div style="height: 200px;">1</div>
<div style="height: 200px;">2</div>
<div style="height: 290px;">3</div>
<div style="height: 280px;">4</div>
<div style="height: 200px;">5</div>
<div style="height: 230px;">6</div>
<div style="height: 260px;">7</div>
<div style="height: 210px;">8</div>
<div style="height: 280px;">9</div>
<div style="height: 230px;">10</div>
<div style="height: 260px;">11</div>
<div style="height: 210px;">12</div>
<div style="height: 200px;">13</div>
<div style="height: 270px;">14</div>
<div style="height: 220px;">15</div>
<div style="height: 260px;">16</div>
<div style="height: 250px;">17</div>
<div style="height: 290px;">18</div>
</div>
</div>
CodePudding user response:
Update:
Actually this solution doesn't work. The problem is just because the column size is N and the outer size is N * 3 does not mean the browser will chose to make 3 columns. For example, if there are only 2 items it will make 2 columns because why make 3? But when it makes 2 it ends up distributing the space. So this isn't a solution AFAICT.
Previous answer:
I did think of one poor solution. If container queries worked then I could make
<div id="outer">
<div id="inner">
<div></div>
<div></div>
<div></div>
</div>
</div>
And then do queries on outer
to force inner to only be multiples of the size I want the columns.
Since I don't have container queries, then I can use media queries. It kind of sucks because I can't use calc and it only works if the out container can be fit to the page.
body {
background-color: #c3dbff;
margin: 0;
}
.cols {
columns: 250px; /* want however many 250px columns will fit */
column-gap: 0px;
}
.thing {
display: inline-block;
width: 240px;
background: red;
margin-bottom: 10px;
break-inside: avoid-column;
/* below just to make it clear the order of children in the columns */
color: white;
display: inline-grid;
place-content: center;
font-weight: bold;
font-family: sans-serif;
font-size: 50pt;
}
@media (max-width: 2249px) { .cols { width: 2000px; } }
@media (max-width: 1999px) { .cols { width: 1750px; } }
@media (max-width: 1749px) { .cols { width: 1500px; } }
@media (max-width: 1499px) { .cols { width: 1250px; } }
@media (max-width: 1249px) { .cols { width: 1000px; } }
@media (max-width: 999px) { .cols { width: 750px; } }
@media (max-width: 749px) { .cols { width: 500px; } }
@media (max-width: 499px) { .cols { width: 250px; margin-right: 10px; } }
<div >
<div style="height: 200px;">1</div>
<div style="height: 200px;">2</div>
<div style="height: 290px;">3</div>
<div style="height: 280px;">4</div>
<div style="height: 200px;">5</div>
<div style="height: 230px;">6</div>
<div style="height: 260px;">7</div>
<div style="height: 210px;">8</div>
<div style="height: 280px;">9</div>
<div style="height: 230px;">10</div>
<div style="height: 260px;">11</div>
<div style="height: 210px;">12</div>
<div style="height: 200px;">13</div>
<div style="height: 270px;">14</div>
<div style="height: 220px;">15</div>
<div style="height: 260px;">16</div>
<div style="height: 250px;">17</div>
<div style="height: 290px;">18</div>
</div>
Apparently, at least in Chrome, when the column goes to a single column the margin-bottom setting is ignored.
CodePudding user response:
try using display flex. set up justify-content to flex-start, align items to the centre and flex-wrap to wrap. and give a justifiable width and avoid using inline styles.
CodePudding user response:
What happens here is defined in the docs of column-width
The actual column width may differ from the specified value: it may be wider when necessary to fill available space
So the priority is to fill the entire container with as many columns as possible, not to keep the column at a certain desired width. If what you want is equal width gutters (but sometimes too wide items), you can set the column-gap to 10px and item width to 100%.