I was under the impression that a margin can be added to flex items/children, and flexbox should automatically take that into account and calculate the correct spacing between the items.
I can't seem to get this working as I would like though.
Fiddle here: https://jsfiddle.net/dba5ehcw/1/
.flex-item{ border: 1px solid blue; box-sizing: border-box; height: 160px; width: 50%; }
So each flex item at the moment is half the width of the container, and they flow nicely next to each other.
I would like to be able to add a margin of say, 1em to the flex-items in order to give them some breathing room, but in doing so, they become larger than the 50% and no longer stack next to each other on the same line because they are too wide.
Is there a way to use margin on the flex-items and have the flexbox container take this into account and adjust (decrease) their widths accordingly?
The percentage is based on the width of the container. margin-right: auto; The auto keyword will give the right side a share of the remaining space. When combined with margin-left: auto , it will center the element, if a fixed width is defined.
It guarantees that the left and right margins will be set to the same size.
There are multiple ways to do this:
Use calc
:
.flex-item { width: calc(50% - 2em); margin: 1em; }
.flex-container { border: 1px solid red; box-sizing: border-box; display: flex; flex-wrap: wrap; width: 320px; } .flex-item { border: 1px solid blue; box-sizing: border-box; height: calc(160px - 2em); width: calc(50% - 2em); margin: 1em; }
<div class="flex-container"> <div class="flex-item"></div> <div class="flex-item"></div> <div class="flex-item"></div> <div class="flex-item"></div> <div class="flex-item"></div> <div class="flex-item"></div> </div>
Use nested boxes:
.flex-item { width: 50%; display: flex; } .flex-item > div { border: 1px solid blue; flex: 1; margin: 1em; }
.flex-container { border: 1px solid red; box-sizing: border-box; display: flex; flex-wrap: wrap; width: 320px; } .flex-item { height: 160px; width: 50%; display: flex; } .flex-item > div { border: 1px solid blue; flex: 1; margin: 1em; }
<div class="flex-container"> <div class="flex-item"><div></div></div> <div class="flex-item"><div></div></div> <div class="flex-item"><div></div></div> <div class="flex-item"><div></div></div> <div class="flex-item"><div></div></div> <div class="flex-item"><div></div></div> </div>
Place each row in a nowrap container, and use a positive flex-shrink factor
.row { display: flex; } .flex-item { width: 50%; margin: 1em; }
.flex-container { border: 1px solid red; width: 320px; } .row { height: 160px; display: flex; } .flex-item { border: 1px solid blue; width: 50%; margin: 1em; }
<div class="flex-container"> <div class="row"> <div class="flex-item"></div> <div class="flex-item"></div> </div> <div class="row"> <div class="flex-item"></div> <div class="flex-item"></div> </div> <div class="row"> <div class="flex-item"></div> <div class="flex-item"></div> </div> </div>
Don't use width
. Instead, force line-breaks at the right places, and use flex: 1
to make the elements grow to fill remaining space.
.flex-item { flex: 1; } .line-break { width: 100% }
.flex-container { border: 1px solid red; box-sizing: border-box; display: flex; flex-wrap: wrap; width: 320px; } .flex-item { border: 1px solid blue; box-sizing: border-box; height: calc(160px - 2em); flex: 1; margin: 1em; } .line-break { width: 100%; }
<div class="flex-container"> <div class="flex-item"></div> <div class="flex-item"></div> <div class="line-break"></div> <div class="flex-item"></div> <div class="flex-item"></div> <div class="line-break"></div> <div class="flex-item"></div> <div class="flex-item"></div> </div>
You need to do it with padding - which, when in border-box
mode does not make the container larger than it's specified width - not margin, and a nested flex
div. This is how all flexbox-based grid systems work. Code below:
.flex-container{ border: 1px solid red; box-sizing: border-box; display: flex; flex-wrap: wrap; width: 320px; } .flex-item{ padding:1em; box-sizing: border-box; height: 160px; width: 50%; display:flex; } .flex-item>div { border: 1px solid blue; flex: 1 1 auto; }
<div class="flex-container"> <div class="flex-item"><div></div></div> <div class="flex-item"><div></div></div> <div class="flex-item"><div></div></div> <div class="flex-item"><div></div></div> <div class="flex-item"><div></div></div> <div class="flex-item"><div></div></div> </div>
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