Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 714
JacobTheDev Avatar asked Aug 31 '25 20:08

JacobTheDev


1 Answers

The formula you mentioned works... You can use CSS variables to make a reusable grid system. A buddy and I came up with this:

.flex {
  --cols: 3;
  --gap: 30px;
  display: flex;
  gap: var(--gap);
}

.flex-child {
  flex-basis: calc(100% / var(--cols) - var(--gap) / var(--cols) * (var(--cols) - 1));
}

@media (max-width: 1000px) {
  .flex{
    --cols: 2;
  }
}

@media (max-width: 750px) {
  .flex{
    --cols:1;
  }
}

So then all you need to change are the variables --cols and --gap https://codepen.io/pyledigital/pen/mdWmjQb

like image 167
MrFent Avatar answered Sep 04 '25 10:09

MrFent