The column layout is a bit tricky. If you read the specification related to column-width
you can find:
describes the optimal column width. The actual column width may be wider (to fill the available space), or narrower (only if the available space is smaller than the specified column width). ref
Remove the width from the elements and resize the container to notice this:
.flex-container {
width: 400px;
border: 1px solid blue;
columns: 120px;
padding: 10px;
overflow:hidden;
resize:horizontal;
}
.flex-item {
background: OliveDrab;
padding: 5px;
height: 100px;
line-height: 100px;
color: white;
text-align: center;
break-inside: avoid-column;
}
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
</div>
You will notice that the gap is indeed fixed but the width of columns is changing.
You can find more details around the algorithm here: https://drafts.csswg.org/css-multicol-1/#pseudo-algorithm
A solution is to consider the use of CSS grid having fixed column width. The trick is to define the width of the grid column to be equal to the gap+width of column and you make you container fill all the columns (its width will be a multiplier of gap+width of column)
Resize the screen to see the result:
.container {
display:grid;
grid-template-columns:repeat(auto-fit,140px); /* 120 + 20 */
overflow: hidden;
resize: horizontal;
border: 1px solid blue;
}
.flex-container {
grid-column:1/-1;
column-width: 120px;
column-gap: 20px;
padding: 10px;
}
.flex-item {
background: OliveDrab;
padding: 5px;
height: 100px;
line-height: 100px;
color: white;
text-align: center;
break-inside: avoid-column;
}
<div class="container">
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
<div class="flex-item">8</div>
<div class="flex-item">9</div>
<div class="flex-item">10</div>
</div>
</div>