Why is padding expanding a flex item?

后端 未结 2 2046
感情败类
感情败类 2020-12-06 15:50

In the snippet below, the first row has two divs with flex-grow: 1. As expected, each div takes up 50% of the screen.

When adding padding to the left di

相关标签:
2条回答
  • 2020-12-06 16:34

    That's the correct behaviour as far as I am aware.

    flex:1 is, of course, shorthand for:

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

    This allows the div to grow if necessary which, in this case, it does. It's not automatically going to maintain the flex-items as all the same size if they are, in fact, different.

    0 讨论(0)
  • 2020-12-06 16:46

    The calculations are defined in the spec.

    A flex item's size with padding and flex-grow is determined by calculations in the flexbox spec.

    These calculations are similar to the sizing of flex items with padding and flex-shrink.

    Frankly, the math is quite technical and not the easiest thing in the world to understand.

    But if you want to get into it, here are the details:

    • 9.7. Resolving Flexible Lengths
    • How does flex-shrink factor in padding and border-box?

    Examples

    Below are examples that hopefully make the behavior more clear.

    NOTE: Keep in mind that flex-grow is not a tool for directly establishing the length of a flex item. It's a tool for distributing space in the container among flex items. The flex-basis property sets the initial main size of a flex item. If flex-grow is used with flex-basis, the problem in the question is resolved (see example #4 below).

    Example #1

    In a block container, where you have box-sizing: border-box, the boxes in your code will render evenly regardless of padding.

    body > div {
      height: 50px;
      /* display: flex; */
      font-size: 0; /* remove inline block whitespace */
    }
    body > div > div {
      /* flex: 1; */
      box-sizing: border-box;
      height: 50px;
      display: inline-block;
      width: 50%;
    }
    #a {
      background-color: red;
    }
    #b {
      background-color: green;
    }
    #c {
      padding: 10px;
      background-color: blue;
    }
    #d {
      background-color: yellow;
    <div>
      <div id="a"></div>
      <div id="b"></div>
    </div>
    <div>
      <div id="c"></div>
      <div id="d"></div>
    </div>

    jsFiddle demo


    Example #2

    In a flex container, where you have box-sizing: border-box, and the width or flex-basis is used to calculate length, the boxes will render evenly regardless of padding.

    body > div {
      height: 50px;
      display: flex;
      }
    
    body > div > div {
      flex-basis: 50%;
      /* width: 50%; this works, as well */
      box-sizing: border-box;
    }
    
    #a {
      background-color: red;
    }
    #b {
      background-color: green;
    }
    #c {
      padding: 10px;
      background-color: blue;
    }
    #d {
      background-color: yellow;
    <div>
      <div id="a"></div>
      <div id="b"></div>
    </div>
    <div>
      <div id="c"></div>
      <div id="d"></div>
    </div>

    jsFiddle demo


    Example #3

    In a flex container, where you have box-sizing: border-box and flex-grow, it will appear that box-sizing doesn't work...

    body > div {
      height: 50px;
      display: flex;
      }
    
    body > div > div {
      flex: 1;
      /* flex-basis: 50%; */
      /* width: 50%; this works, as well */
      box-sizing: border-box;
    }
    
    #a {
      background-color: red;
    }
    #b {
      background-color: green;
    }
    #c {
      padding: 10px;
      background-color: blue;
    }
    #d {
      background-color: yellow;
    <div>
      <div id="a"></div>
      <div id="b"></div>
    </div>
    <div>
      <div id="c"></div>
      <div id="d"></div>
    </div>

    jsFiddle demo

    but that's not really correct...


    Example #4

    flex-grow expands the width of a flex item based on available space in the flex container. In other words, it ignores padding (and borders).

    However, if you simply specify flex-grow along with flex-basis, the border-box will work:

    flex: 1 1 50%; /* flex-grow, flex-shrink, flex-basis */
    

    body > div {
      height: 50px;
      display: flex;
      }
    
    body > div > div {
      flex: 1 1 50%; /* flex-grow, flex-shrink, flex-basis */
      /* flex-basis: 50%; */
      /* width: 50%; this works, as well */
      box-sizing: border-box;
    }
    
    #a {
      background-color: red;
    }
    #b {
      background-color: green;
    }
    #c {
      padding: 10px;
      background-color: blue;
    }
    #d {
      background-color: yellow;
    <div>
      <div id="a"></div>
      <div id="b"></div>
    </div>
    <div>
      <div id="c"></div>
      <div id="d"></div>
    </div>

    jsFiddle demo

    0 讨论(0)
提交回复
热议问题