How to get flexbox to include padding in calculations?

HtmlCssFlexbox

Html Problem Overview


Below are two rows.

  • First row is two items at flex 1 and one at flex 2.

  • Second Row is two items at flex 1.

According to the spec 1A + 1B = 2A

But when padding is included in the calculation the sum is incorrect as you can see in the example below.


QUESTION

How to get flex box to include padding into its calculation so the boxes in the example line up correctly?

.Row{
  display:flex;
}
.Item{
  display:flex;
  flex:1;
  flex-direction:column;
  padding:0 10px 10px 0;
}
.Item > div{
  background:#7ae;
}
.Flx2{
  flex:2;
}

<div class="Row">
  <div class="Item">
    <div>1A</div>
  </div>
  <div class="Item">
    <div>1B</div>
  </div>
  <div class="Item Flx2">
    <div>1C</div>
  </div>
</div>

<div class="Row">
  <div class="Item">
    <div>2A</div>
  </div>
  <div class="Item">
    <div>2B</div>
  </div>
</div>

Html Solutions


Solution 1 - Html

The solution:

Set margin on the child element instead of padding on your flex item.

.Row{
  display:flex;
}
.Item{
  display:flex;
  flex:1;
  flex-direction:column;
}
.Item > div{
  background:#7ae;
  margin:0 10px 10px 0;
}
.Flx2{
  flex:2;
}

<div class="Row">
  <div class="Item">
    <div>1A</div>
  </div>
  <div class="Item">
    <div>1B</div>
  </div>
  <div class="Item Flx2">
    <div>1C</div>
  </div>
</div>

<div class="Row">
  <div class="Item">
    <div>2A</div>
  </div>
  <div class="Item">
    <div>2B</div>
  </div>
</div>


The problem:

The calculation is done without padding. So; adding padding to the flex element is not giving you your expected width by the spec.

The specific article

>For example, the available space to a flex item in a floated auto-sized flex container is:

>* the width of the flex container’s containing block minus the flex container’s margin, border, and padding in the horizontal dimension

  • infinite in the vertical dimension

Why is the padding not calculated? That's what the spec wants.

>Determine the available main and cross space for the flex items. For each dimension, if that dimension of the flex container’s content box is a definite size, use that; if that dimension of the flex container is being sized under a min or max-content constraint, the available space in that dimension is that constraint; otherwise, subtract the flex container’s margin, border, and padding from the space available to the flex container in that dimension and use that value. This might result in an infinite value.

If you subtract the padding and margin from the element's size, you get:

1A + 1B = 2A

However, after you did that, the padding was added to the element. The more elements, the more padding. That's not being calculated in the width, causing your statement to be false.

Solution 2 - Html

>How to get flexbox to include padding in calculations?

In your code, padding is included in the calculations.

>According to the spec 1A + 1B = 2A

I don't believe this is correct. Maybe provide a link reference for an explanation.


The flex-grow property

When you apply flex: 1 to an element, you are using the flex shorthand property to say this:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0

flex-grow tells a flex item to consume the free space in the container.

Here is your code:

.Item {
  display: flex;
  flex: 1;
  flex-direction: column;
  padding: 0 10px 10px 0;
}

In the first row, padding-right: 10px is applied to three flex items.

In the second row, padding-right: 10px is applied to two flex items.

Hence, in the first row there is 10px less free space to distribute. This breaks the grid's alignment.

For distributing space (e.g., you want an element to take the remaining height or width of a container), use flex-grow.

For precise sizing of a flex item use flex-basis, width or height.

Here's some more info:

Solution 3 - Html

You can use floated pseudo block elements instead of padding, like this: (In this case 30px right padding)

.Item:after {
  content: '';
  display: block;
  float: right;
  width: 30px;
  height: 100%;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDreamTeKView Question on Stackoverflow
Solution 1 - HtmlRandyView Answer on Stackoverflow
Solution 2 - HtmlMichael BenjaminView Answer on Stackoverflow
Solution 3 - HtmlsoriozView Answer on Stackoverflow