'Account for gap when calculating flex-basis
I'm trying to use gap to specify gaps between flexed items within my grid system, but running in to a major drawback. It seems that when you're using flex-grow: 0;/flex-shrink: 0; in conjunction with gap and flex-basis values that fill the entire available width (i.e. three columns with flex: 0 0 33.3333%;), the columns overflow their parent container as the gap doesn't account for the fixed width as specified with flex: 0 0 33.3333%.
Similar to box-sizing: border-box;, is there some way to instruct the rendering engine that the gap should be subtracted when determining the width of these columns?
Demonstration:
.row {
display: flex;
gap: 30px;
border: 2px solid red;
}
.col {
flex: 0 0 33.3333%;
background: teal;
border: 2px solid #004D4D;
color: white;
font-weight: 700;
padding: 50px;
text-align: center;
}
:root {
font-family: sans-serif;
}
* {
box-sizing: border-box;
}
<h2>With gap:</h2>
<div class="row">
<div class="col">
1
</div>
<div class="col">
2
</div>
<div class="col">
3
</div>
</div>
<h2>Without gap:</h2>
<div class="row" style="gap:0;">
<div class="col">
1
</div>
<div class="col">
2
</div>
<div class="col">
3
</div>
</div>
Note: I could account for this with a formula like flex-basis: calc($width - ($gap / ($number-of-columns / 2));, but as this is for a reusable grid system, I can't practically account for every possible scenario.
Solution 1:[1]
When you add a padding-right: calc(var(--gap-space) * 2); to parent container. Parent container width will calculte before child containers use 100% which is parent container width. You need to change parent containers width before using its width inside child container.
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
min-height: 100vh;
text-rendering: optimizeSpeed;
line-height: 1.5;
margin: 0;
background-color: bisque;
display: grid;
place-content: center;
}
:root{
--gap-space:30px;
font-family: sans-serif;
}
.row-1 {
display: flex;
gap: var(--gap-space);
border: 2px solid red;
padding-right: calc(var(--gap-space) * 2);
}
.row-1 .col{
background: teal;
border: 2px solid #004D4D;
color: white;
font-weight: 700;
padding: 50px;
text-align: center;
flex: 0 0 calc(100% / 3);
}
.row-2{
display: flex;
flex-direction: row;
border: 2px solid red;
}
.row-2 .col{
background: teal;
border: 2px solid #004D4D;
color: white;
font-weight: 700;
padding: 50px;
text-align: center;
flex: 0 0 calc(100% / 3);
}
<h2>With gap:</h2>
<div class="row-1">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
<h2>Without gap:</h2>
<div class="row-2" style="gap: 0">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
Solution 2:[2]
What's wrong with using only width?
.col {
width: 33.3333%;
...
}
.row {
display: flex;
gap: 30px;
border: 2px solid red;
}
.col {
width: 33.3333%;
background: teal;
border: 2px solid #004D4D;
color: white;
font-weight: 700;
padding: 50px;
text-align: center;
}
:root {
font-family: sans-serif;
}
* {
box-sizing: border-box;
}
<h2>With gap:</h2>
<div class="row">
<div class="col">
1
</div>
<div class="col">
2
</div>
<div class="col">
3
</div>
</div>
<h2>Without gap:</h2>
<div class="row" style="gap:0;">
<div class="col">
1
</div>
<div class="col">
2
</div>
<div class="col">
3
</div>
</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Maik Lowrey |
