Using margin on flex items
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>
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 useflex: 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>