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 div, that is no longer the case. Can someone explain why?
body > div { height: 50px; display: flex; } body > div > div { flex: 1; 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>
You do have to make sure that the padding on the ::after pseudo-element is half that of the padding used on the flex container, because padding is applied all around the pseudo-element. But if you go with padding-left or padding-right , then you can use the same value as the padding on the flex container.
By default, the child elements of a flexbox container will stretch vertically to fill the height of the container. This can be prevented by using the align-self property on the child element that you do not want to stretch.
Padding between flexbox items can be accomplished by setting the 'justify-content' property to 'space-between'. This will cause the items to evenly distribute themselves within the container, with the first item flush with the left side of the container and the last item flush with the right side.
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:
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With