Home > Software design >  Account for gap when calculating flex-basis
Account for gap when calculating flex-basis

Time:05-05

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 >
    <div >
        1
    </div>
    <div >
        2
    </div>
    <div >
        3
    </div>
</div>

<h2>Without gap:</h2>

<div  style="gap:0;">
    <div >
        1
    </div>
    <div >
        2
    </div>
    <div >
        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.

CodePudding user response:

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 >
      <div >1</div>
      <div >2</div>
      <div >3</div>
    </div>

    <h2>Without gap:</h2>

    <div  style="gap: 0">
      <div >1</div>
      <div >2</div>
      <div >3</div>
    </div>

CodePudding user response:

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 >
    <div >
        1
    </div>
    <div >
        2
    </div>
    <div >
        3
    </div>
</div>

<h2>Without gap:</h2>

<div  style="gap:0;">
    <div >
        1
    </div>
    <div >
        2
    </div>
    <div >
        3
    </div>
</div>

  • Related