I was developing a grid system using flexbox's justify-content: space-between;
and I noticed that on certain screen sizes (about every other pixel) a 1 pixel gap appears at the end of certain columns.
If you start to resize your browser with the example below, you can see the 1 pixel space appearing and disappearing.
Example
* {
margin: 0;
padding: 0;
}
.row {
display: flex;
flex-wrap: wrap;
max-width: 550px;
width: 100%;
margin: 0 auto;
border: 2px solid #888;
justify-content: space-between;
}
div[class^="col"] {
border: 2px solid red;
}
.col-12 {
flex-basis: calc(100% - 4px);
}
.col-11 {
flex-basis: calc(11/12*100% - (1.167 - 11/12)*24px);
}
.col-10 {
flex-basis: calc(5/6*100% - (1.167 - 5/6)*24px);
}
.col-9 {
flex-basis: calc(3/4*100% - (1.167 - 3/4)*24px);
}
.col-8 {
flex-basis: calc(2/3*100% - (1.167 - 2/3)*24px);
}
.col-7 {
flex-basis: calc(7/12*100% - (1.167 - 7/12)*24px);
}
.col-6 {
flex-basis: calc(1/2*100% - (1.167 - 1/2)*24px);
}
.col-5 {
flex-basis: calc(5/12*100% - (1.167 - 5/12)*24px);
}
.col-4 {
flex-basis: calc(1/3*100% - (1.167 - 1/3)*24px);
}
.col-3 {
flex-basis: calc(1/4*100% - (1.167 - 1/4)*24px);
}
.col-2 {
flex-basis: calc(1/6*100% - (1.167 - 1/6)*24px);
}
.col-1 {
flex-basis: calc(1/12*100% - (1.167 - 1/12)*24px);
}
<div class="row">
<div class="col-12">col-12</div>
<div class="col-6">col-6</div>
<div class="col-6">col-6</div>
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
<div class="col-3">col-3</div>
<div class="col-3">col-3</div>
<div class="col-6">col-6</div>
<div class="col-3">col-3</div>
<div class="col-3">col-3</div>
<div class="col-3">col-3</div>
<div class="col-3">col-3</div>
<div class="col-4">col-4</div>
<div class="col-8">col-8</div>
<div class="col-7">col-7</div>
<div class="col-5">col-5</div>
<div class="col-6">col-6</div>
<div class="col-4">col-4</div>
<div class="col-2">col-2</div>
</div>
Here is a working Fiddle so you can resize it more easily.
JSFiddle
*Note:
I know that I'm doing some crazy stuff with the calc()
, but even if you just subtract 5px
instead of (1.167 - 1/12)*24px)
the issue still exists.
Is this a bug with flexbox?
What do I need to do in order to remove the gap at the end of these columns?
I played around with this problem a little bit before coming to a solution. The steps as follows:
First I converted everything to use a standard format
calc(a/12 * 100% - (7/6 - a/12) * 24px)
where a = "col number"
Next I began experimenting with the number to see the actual output without units (of course)
Form this we can see three things
x.3333...
x.6666...
Note: 1 and 2 are special cases and are reversed because their output is actually negative. We can assume that their numbers would be positive in the real world and would fall inline with the others
After that pinpointing the actual issue in the equation was easy:
a/12 * 100%
So the rounding issue is your problem - i.e. when you use two or more numbers ending in x.3333...
We would like these rounding errors not to cascade so we have a few options
x.3333...
)Examples:
flex-basis: calc((8/12 - 1/6/100) * 100% - (7/6 - 8/12) * 24px);
flex-basis: calc(8/12 * 100% - (7/6 - 8/12) * 24px);
I went with the first example to give me this repeating code:
* {
margin: 0;
padding: 0;
}
.row {
display: flex;
flex-wrap: wrap;
max-width: 550px;
width: 100%;
margin: 0 auto;
border: 2px solid #888;
justify-content: space-between;
}
div[class^="col"] {
border: 2px solid red;
}
.col-12 {
flex-basis: calc(12/12 * 100% - (7/6 - 12/12) * 24px);
}
.col-11 {
flex-basis: calc((11/12 - 1/6/100) * 100% - (7/6 - 11/12) * 24px);
}
.col-10 {
flex-basis: calc((10/12 + 1/6/100) * 100% - (7/6 - 10/12) * 24px);
}
.col-9 {
flex-basis: calc(9/12 * 100% - (7/6 - 9/12) * 24px);
}
.col-8 {
flex-basis: calc((8/12 - 1/6/100) * 100% - (7/6 - 8/12) * 24px);
}
.col-7 {
flex-basis: calc((7/12 + 1/6/100) * 100% - (7/6 - 7/12) * 24px);
}
.col-6 {
flex-basis: calc(6/12 * 100% - (7/6 - 6/12) * 24px);
}
.col-5 {
flex-basis: calc((5/12 - 1/6/100) * 100% - (7/6 - 5/12) * 24px);
}
.col-4 {
flex-basis: calc((4/12 + 1/6/100) * 100% - (7/6 - 4/12) * 24px);
}
.col-3 {
flex-basis: calc(3/12 * 100% - (7/6 - 3/12) * 24px);
}
.col-2 {
flex-basis: calc((2/12 - 1/6/100) * 100% - (7/6 - 2/12) * 24px);
}
.col-1 {
flex-basis: calc((1/12 + 1/6/100) * 100% - (7/6 - 1/12) * 24px);
}
<div class="row">
<div class="col-12">col-12</div>
<div class="col-6">col-6</div>
<div class="col-6">col-6</div>
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
<div class="col-3">col-3</div>
<div class="col-3">col-3</div>
<div class="col-6">col-6</div>
<div class="col-3">col-3</div>
<div class="col-3">col-3</div>
<div class="col-3">col-3</div>
<div class="col-3">col-3</div>
<div class="col-4">col-4</div>
<div class="col-8">col-8</div>
<div class="col-7">col-7</div>
<div class="col-5">col-5</div>
<div class="col-6">col-6</div>
<div class="col-4">col-4</div>
<div class="col-2">col-2</div>
</div>
This should work in modern and even most older browsers that support non-rounded calc
If you would like to see the second solution just leave a comment and I'll post it.
Note: if you can it would be best to use a language like sass or less to perform these calculations as they after rounding and also functions to keep all this hard work in one place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With