Flexbox wrapping nested rows without media query - html

I've got four div's in a flexbox grid. I want them to wrap two at a time, like this:
+-----------------------+
| 1 | 2 | 3 | 4 |
+-----------------------+
+-----------+
| 1 | 2 |
+-----------+ THIS IS WHAT I WANT
| 3 | 4 |
+-----------+
+-----+
| 1 |
+-----+
| 2 |
+-----+
| 3 |
+-----+
| 4 |
+-----+
Now, this seems easy enough, just nest them inside new flex containers and apply flex-wrap, and give the cells some min-widths. However, this has the side-effect of making the middle view look like this:
+-----------+
| 1 | 3 |
+-----------+ NOT WHAT I WANT
| 2 | 4 |
+-----------+
Apparently, flexbox wants to first wrap the inner div's instead of considering them rows. In order to keep all of the other wrapping working, setting flex-basis (to e.g. 100%) for the nested div's is not an option. In order to keep everything dynamic (for instance adding a third cell to one of the rows), setting %-widths on the cells is not an option. And in order to avoid hard breakpoints and base wrapping on (dynamic) content width, I'd really like to avoid media queries.
Can this be achieved with flexbox and without media queries?
JSFiddle
div {
box-sizing: border-box;
margin: 2px;
}
.grid {
display: flex;
flex-flow: row wrap;
border: 2px solid blue;
flex: 1;
}
.cell {
flex: 1;
min-width: 100px;
border: 2px solid red;
background: white;
height: 100px;
}
<div class="grid">
<div class="grid">
<div class="cell">1</div>
<div class="cell">2</div>
</div>
<div class="grid">
<div class="cell">3</div>
<div class="cell">4</div>
</div>
</div>
EDIT: I know I can make the inner .grid not wrap at all, but what I really want is for all the cells to wrap below each other if space is super tight. (As in the first illustration.)

You need to tell the children-elements of .grid .grid to flow in a row:
div {
box-sizing: border-box;
margin: 2px;
}
.grid {
display: flex;
flex-flow: row wrap;
border: 2px solid blue;
flex: 1;
}
.grid .grid {
flex-flow: row; /* this is your fix */
}
.cell {
flex: 1;
min-width: 100px;
border: 2px solid red;
background: white;
height: 100px;
}
<div class="grid">
<div class="grid">
<div class="cell">1</div>
<div class="cell">2</div>
</div>
<div class="grid">
<div class="cell">3</div>
<div class="cell">4</div>
</div>
</div>

Note, there is no specific Flexbox property that replace a media query, and no need either as media queries is perfect for this, better than any other available method or property.
The trick here is to make the inner grid's to wrap before the cell's does. For that to happen they also need a minimum width, which is wider than the sum of the 2 cell's.
The downside with that extra min-width is it will also affect the cell's width on narrower screens
Fiddle demo 1
Stack snippet
div {
box-sizing: border-box;
margin: 2px;
}
.grid-outer {
display: flex;
flex-wrap: wrap;
border: 2px solid blue;
}
.grid-inner {
flex: 1;
display: inline-flex;
flex-wrap: wrap;
border: 2px solid blue;
min-width: 210px;
}
.cell {
flex: 1;
min-width: 100px;
border: 2px solid red;
background: white;
height: 100px;
}
<div class="grid-outer">
<div class="grid-inner">
<div class="cell">1</div>
<div class="cell">2</div>
</div>
<div class="grid-inner">
<div class="cell">3</div>
<div class="cell">4</div>
</div>
</div>
An option is to drop the Flexbox properties on the outer grid and set the inner grid's to inline-flex and let the cells grow with their content.
The downside with this is that the cell's won't fill their parents width
Fiddle demo 2
Stack snippet
div {
box-sizing: border-box;
margin: 2px;
}
.grid-outer {
display: inline-block;
}
.grid-inner {
display: inline-flex;
flex-wrap: wrap;
border: 2px solid blue;
}
.cell {
flex: 1;
min-width: 100px;
border: 2px solid red;
background: white;
height: 100px;
}
<div class="grid-outer">
<div class="grid-inner">
<div class="cell">1</div>
<div class="cell">2</div>
</div>
<div class="grid-inner">
<div class="cell">3</div>
<div class="cell">4</div>
</div>
</div>
The absolute best solution here is a combination of Flexbox and a media query, where one use the query to alter the outer grid's flex direction to column...
Fiddle demo
Stack snippet
div {
box-sizing: border-box;
margin: 2px;
}
.grid-outer {
display: flex;
border: 2px solid blue;
}
.grid-inner {
flex: 1;
display: flex;
border: 2px solid blue;
}
.cell {
flex: 1;
min-width: 100px;
border: 2px solid red;
background: white;
height: 100px;
}
#media (max-width: 600px) {
.grid-outer {
flex-direction: column;
}
}
<div class="grid-outer">
<div class="grid-inner">
<div class="cell">1</div>
<div class="cell">2</div>
</div>
<div class="grid-inner">
<div class="cell">3</div>
<div class="cell">4</div>
</div>
</div>
...or drop the inner grid's all together and change the cell's flex basis
Fiddle demo
Stack snippet
div {
box-sizing: border-box;
margin: 2px;
}
.grid-outer {
display: flex;
flex-wrap: wrap;
border: 2px solid blue;
}
.cell {
flex: 1;
min-width: 100px;
border: 2px solid red;
background: white;
height: 100px;
}
#media (max-width: 600px) {
.cell {
flex-basis: calc(50% - 4px);
}
}
<div class="grid-outer">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell">3</div>
<div class="cell">4</div>
</div>

Having different definitions for the grids does the job. I redefined them as outer and inner grid.
EDIT: Added wrap for .grid-inner to cover width < 200px
div {
box-sizing: border-box;
margin: 2px;
}
.grid-outer {
display: flex;
flex-flow: row wrap;
border: 2px solid blue;
flex: 1;
width: 230px; /* for demo purposes */
}
.grid-inner {
display: flex;
border: 2px solid green;
flex-wrap: wrap;
}
.cell {
flex: 1;
min-width: 100px;
border: 2px solid red;
background: white;
height: 100px;
}
<div class="grid-outer">
<div class="grid-inner">
<div class="cell">1</div>
<div class="cell">2</div>
</div>
<div class="grid-inner">
<div class="cell">3</div>
<div class="cell">4</div>
</div>
</div>

Related

Display divs in 2 columns ordered from above to below

I want to display divs in 2 columns ordered from above to below:
I tried the following solution based on column-count which works nice if the number of divs is even but breaks if it's odd.
.container {
column-count:2;
}
.square {
box-sizing: border-box;
border: 1px solid black;
height: 200px;
padding: 5px;
}
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
</div>
Then I tried a solution based on flex, but I can't seem to find a solution for the order:
.container {
display:flex;
flex-wrap: wrap;
}
.square {
box-sizing: border-box;
border: 1px solid black;
flex: 0 0 50%;
height: 200px;
}
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
</div>
What I want to achieve is smoothing like this:
add display:inline-block;width:100%; to the square element:
.container {
column-count: 2;
}
.square {
border: 1px solid black;
height: 200px;
display:inline-block;
width:100%;
}
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
</div>

Auto fill grid container with one item full width leaving no gaps [duplicate]

I want the red box to be on the 2nd row, but then i want the divs that are defined after it, to continue on the first line, so that all the black boxes essentially wrap around the black box. Can this be achieved with flexbox?
It should look like this:
+---+---+---+---+---+
| 1 | 2 | 3 | 5 | 6 |
+---+---+---+---+---+
| 4 |
+---+---+---+---+---+
| 7 | 8 | 9 |10 |11 |
+---+---+---+---+---+
|12 |13 |
+---+---+
* {
box-sizing: border-box;
}
.container {
display: flex;
flex-wrap: wrap;
}
.a {
border: 1px solid black;
height: 50px;
width: 20%;
}
.b {
border: 1px solid red;
height: 50px;
width: 100%;
}
<div class="container">
<div class='a'>1</div>
<div class='a'>2</div>
<div class='a'>3</div>
<div class='b'>4</div>
<div class='a'>5</div>
<div class='a'>6</div>
<div class='a'>7</div>
<div class='a'>8</div>
<div class='a'>9</div>
<div class='a'>10</div>
<div class='a'>11</div>
<div class='a'>12</div>
<div class='a'>13</div>
</div>
See https://codepen.io/anon/pen/OqqeJN
You will have better luck using CSS grid for this task:
* {
box-sizing: border-box;
}
.container {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-auto-flow: dense; /* this will make the elements to flow around*/
}
.a {
border: 1px solid black;
height: 50px;
}
.b {
border: 1px solid red;
height: 50px;
/*full width row*/
grid-column: 1/-1;
}
<div class="container">
<div class='a'>1</div>
<div class='a'>2</div>
<div class='a'>3</div>
<div class='b'>4</div>
<div class='a'>5</div>
<div class='a'>6</div>
<div class='a'>7</div>
<div class='a'>8</div>
<div class='a'>9</div>
<div class='a'>10</div>
<div class='a'>11</div>
<div class='a'>12</div>
<div class='a'>13</div>
</div>
dense
If specified, the auto-placement algorithm uses a “dense” packing algorithm, which attempts to fill in holes earlier in the grid if smaller items come up later. This may cause items to appear out-of-order, when doing so would fill in holes left by larger items.ref
You can use the order property along with the nth-child() pseudo-class.
.container {
display: flex;
flex-wrap: wrap;
}
.a {
flex: 0 0 20%;
border: 1px solid black;
}
.b {
flex: 0 0 100%;
border: 1px solid red;
}
.a:nth-child(1) { order: -5; }
.a:nth-child(2) { order: -4; }
.a:nth-child(3) { order: -3; }
.a:nth-child(5) { order: -2; }
.a:nth-child(6) { order: -1; }
/* the default value all items is 0 */
.container > div {
height: 50px;
}
* {
box-sizing: border-box;
}
<div class="container">
<div class='a'>1</div>
<div class='a'>2</div>
<div class='a'>3</div>
<div class='b'>4</div>
<div class='a'>5</div>
<div class='a'>6</div>
<div class='a'>7</div>
<div class='a'>8</div>
<div class='a'>9</div>
<div class='a'>10</div>
<div class='a'>11</div>
<div class='a'>12</div>
<div class='a'>13</div>
</div>

Make flex item wrap to the next row with following items continuing the flow

I want the red box to be on the 2nd row, but then i want the divs that are defined after it, to continue on the first line, so that all the black boxes essentially wrap around the black box. Can this be achieved with flexbox?
It should look like this:
+---+---+---+---+---+
| 1 | 2 | 3 | 5 | 6 |
+---+---+---+---+---+
| 4 |
+---+---+---+---+---+
| 7 | 8 | 9 |10 |11 |
+---+---+---+---+---+
|12 |13 |
+---+---+
* {
box-sizing: border-box;
}
.container {
display: flex;
flex-wrap: wrap;
}
.a {
border: 1px solid black;
height: 50px;
width: 20%;
}
.b {
border: 1px solid red;
height: 50px;
width: 100%;
}
<div class="container">
<div class='a'>1</div>
<div class='a'>2</div>
<div class='a'>3</div>
<div class='b'>4</div>
<div class='a'>5</div>
<div class='a'>6</div>
<div class='a'>7</div>
<div class='a'>8</div>
<div class='a'>9</div>
<div class='a'>10</div>
<div class='a'>11</div>
<div class='a'>12</div>
<div class='a'>13</div>
</div>
See https://codepen.io/anon/pen/OqqeJN
You will have better luck using CSS grid for this task:
* {
box-sizing: border-box;
}
.container {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-auto-flow: dense; /* this will make the elements to flow around*/
}
.a {
border: 1px solid black;
height: 50px;
}
.b {
border: 1px solid red;
height: 50px;
/*full width row*/
grid-column: 1/-1;
}
<div class="container">
<div class='a'>1</div>
<div class='a'>2</div>
<div class='a'>3</div>
<div class='b'>4</div>
<div class='a'>5</div>
<div class='a'>6</div>
<div class='a'>7</div>
<div class='a'>8</div>
<div class='a'>9</div>
<div class='a'>10</div>
<div class='a'>11</div>
<div class='a'>12</div>
<div class='a'>13</div>
</div>
dense
If specified, the auto-placement algorithm uses a “dense” packing algorithm, which attempts to fill in holes earlier in the grid if smaller items come up later. This may cause items to appear out-of-order, when doing so would fill in holes left by larger items.ref
You can use the order property along with the nth-child() pseudo-class.
.container {
display: flex;
flex-wrap: wrap;
}
.a {
flex: 0 0 20%;
border: 1px solid black;
}
.b {
flex: 0 0 100%;
border: 1px solid red;
}
.a:nth-child(1) { order: -5; }
.a:nth-child(2) { order: -4; }
.a:nth-child(3) { order: -3; }
.a:nth-child(5) { order: -2; }
.a:nth-child(6) { order: -1; }
/* the default value all items is 0 */
.container > div {
height: 50px;
}
* {
box-sizing: border-box;
}
<div class="container">
<div class='a'>1</div>
<div class='a'>2</div>
<div class='a'>3</div>
<div class='b'>4</div>
<div class='a'>5</div>
<div class='a'>6</div>
<div class='a'>7</div>
<div class='a'>8</div>
<div class='a'>9</div>
<div class='a'>10</div>
<div class='a'>11</div>
<div class='a'>12</div>
<div class='a'>13</div>
</div>

Parent of two rotated divs to take width and height of resulting transformed div

There seems to be a lot of questions regarding the same issue but can't seem to find a satisfactory answer ... I have:
1 container (flex) (green)
2 columns (block) -> left: red, right: orange
in the left column, I have two divs (green) who follow each other 'menu1''menu2'
These two menus are themselves wrapped in a div (black) so that when I rotate it, the two menus are vertical rather than horizontal (rotation by 90 deg)
The goal is to have the top wrapper/container (green) to take on the height of the vertical black wrapper, and the left column wrapper to be no larger than the 'width' of the rotated black wrapper.
What I get is illustrated in the following example:
https://jsfiddle.net/pg373473/
<div id='container' style='display: flex; border: 3px solid green; flex-direction=row'>
<div id='leftbox' style='position: relative; display: block; border: 3px solid red'>
<div id='textwrapper' style='transform-origin: bottom left; transform: translateY(-100%) rotate(90deg); border: 2px solid black;'>
<div style='border: 3px solid green; display: inline-block'>menu 1</div>
<div style='border: 3px solid green; display: inline-block'>menu 2</div>
</div>
</div>
<div id='rightbox' style='position: relative; display: flex; flex: 1 1 auto; border: 3px solid orange';>
xx
</div>
</div>
Is this possible at all?
By default, the rotation seems to be applied after all the width/height for all divs have been calculated. I personally find this behavior to be against what anybody would expect, but maybe someone who knows the specs very well can explain why this is so? But in the end, I am more interested to know if there is a solution to what I try to achieve (thx).
EDIT
Rotate elements in CSS that affect their parents... is asking something about rotations but the explanation is not satisfactory and the problem slightly different since it's only about being sure that the div of the rotated child take into account the height of the rotated child. The questions asked in this post has 3 constraints:
you have 2 divs in a row that are rotated by 90 degrees (or more than 2)
the wrapper container needs to take on:
the width
and the height of children rotated elements
The aforementioned question is only asking about the height and does not solve the width problem. Additionally, the jsfiddle doesn't work either.
The only good part about this other question is the mentioned in the comments of the writing-mode but I haven't managed to make it work with this either. I tried this option and while I can fix the height issue, I can't make it work to fix the width problem...
<div id='container' style='display: flex; border: 3px solid green; flex-direction: row'>
<div style='display: flex; flex-direction: column; border: 3px solid red; flex: 1 1 auto;'>
<div style='flex: 0 0 auto; display: inline-block; flex-direction: row; writing-mode: vertical-rl; border: 3px solid black;'>
<div style='flex: 0 0 auto; border: 1px solid green; display: inline-block'>menu 1</div>
<div style='flex: 0 0 auto; border: 1px solid green; display: inline-block'>menu 2</div>
</div>
</div>
<div id='rightbox' style='display: flex; flex: 1 1 auto; border: 3px solid orange';>
Right Box
</div>
</div>
https://jsfiddle.net/dyae4xru/
For clarity here is what I want:
ANSWER / EDIT 2
There is no solution to this problem at this point in time. CSS/HTML/Browsers doesn't support that out of the box. I fixed the problem by writing a small JS function that gives me the exact width and height of the div when horizontal and used the values to set the width of the div once rotated by 90 degrees (using writing-mode: vertical-rl).
There may be hacky solutions, yet I'd say CSS transforms are not built for something like this.
If the property has a value different than none, a stacking context
will be created. In that case the object will act as a containing
block for position: fixed elements that it contains.
Source: MDN
(See this post for a scaling transform question.)
CSS Writing Mode
I suggest you use the newer CSS writing mode - see here for browser support:
The writing-mode CSS property defines whether lines of text are laid
out horizontally or vertically and the direction in which blocks
progress.
Use writing-mode: vertical-lr on the div - see demo below that works in Chrome:
#container {
display: flex;
border: 1px solid green;
flex-direction: row;
}
#container>div:first-child {
position: relative;
display: block;
border: 1px solid red;
writing-mode: vertical-lr; /* ADDED */
-webkit-writing-mode: vertical-lr;
}
#container>div>div {
/*transform-origin: bottom left;
transform: translateY(-100%) rotate(90deg);*/
border: 2px solid black;
}
#container>div>div>div {
border: 1px solid green;
display: inline-block;
}
#rightbox {
position: relative;
display: flex;
flex: 1 1 auto;
border: 1px solid orange;
}
<div id='container'>
<div>
<div>
<div>menu 1</div>
<div>menu 2</div>
</div>
</div>
<div id='rightbox'>
xx
</div>
</div>
Issue in Firefox
Note that this doesn't work in Firefox, as flex items do not behave well for vertical writing mode - there are open issues:
Writing-mode: vertical; breaks flexbox layout in Firefox
Flex + vertical writing-mode: flex items / text disappear
The above issue for vertical mode in flexboxes was fixed in Firefox 60, and now you can see that the above demo works in both Chrome & Firefox.
I doubt that this task can be solved without JavaScript because transformed elements are drawn on separate "layers" and their visual appearance doesn't affect DOM properties. However since your transformation is fixed - you can calculate resulted visual size of element and update size of parent element accordingly. Moreover you can use mutation observers to update size of your container in a case if its contents will be changed in runtime. This example displays correct container size and reacts on runtime mutations of menu items. Tested into Firefox and Chrome
document.addEventListener('DOMContentLoaded', function () {
const container = document.querySelector('#container .menu-container');
const menu = document.querySelector('#container .menu-items');
let items = [];
const updateItems = () => {
const nodes = document.querySelectorAll('#container .menu-item');
for (let node of nodes) {
if (items.indexOf(node) === -1) {
items.push(node);
new MutationObserver(updateSize).observe(node, {attributes: true, characterData: true, subtree: true});
}
}
updateSize();
}
const updateSize = () => {
container.style.width = menu.offsetHeight + 'px';
container.style.height = menu.offsetWidth + 'px';
}
new MutationObserver(updateSize).observe(menu, {attributes: true, characterData: true});
new MutationObserver(updateItems).observe(menu, {childList: true});
updateItems();
updateSize();
});
#container {
display: flex;
border: 1px solid green;
flex-direction: row;
}
.menu-container {
position: relative;
display: block;
border: 1px solid red;
}
.menu-items {
transform-origin: bottom left;
transform: translateY(-100%) rotate(90deg);
border: 2px solid black;
display: flex;
position: absolute;
}
.menu-item {
border: 1px solid green;
display: inline-block;
white-space: nowrap;
}
#rightbox {
position: relative;
display: flex;
flex: 1 1 auto;
border: 1px solid orange;
}
<div id="container">
<div class="menu-container">
<div class="menu-items">
<div class="menu-item">menu 1</div>
<div class="menu-item">menu 2</div>
</div>
</div>
<div id="rightbox">
xx
</div>
</div>
Here is my approach to the solution:
I use flex on the container as well as the LEFT BOX, then user writing-mode vertical left to right and finally flex direction column so they stack.
*,
*:before,
*:after {
/* So 100% means 100% */
box-sizing: border-box;
margin: 0;
padding: 0;
}
.container {
display: flex;
border: 2px solid tomato;
}
.box-left {
flex: 0 2.5%; // change % value for the size you want it!
}
.box-right {
flex: 1 auto;
border: 2px solid green;
}
.box-left ul {
display: flex;
flex-direction: column;
border: 2px solid blue;
}
.box-left ul li {
list-style: none;
writing-mode: vertical-lr;
margin-bottom: 0.5em;
}
<div class="container">
<div class="box-left">
<ul>
<li>menu01</li>
<li>menu02</li>
</ul>
</div>
<div class="box-right">
box right
</div>
</div>
I modified your code and below is the out of CSS and HTML snippet.
*,
*:before,
*:after {box-sizing: border-box;margin: 0;padding: 0;}
.container {display: flex;border: 2px solid green;}
.left-box {flex: 0 2.5%;}
.right-box {flex: 1 auto;border: 2px solid orange;}
.left-box {flex: 0 5.5%;border: 2px solid red;}
.menu {border: 1.5px solid green;}
.inner-left-box ul {display: flex;flex-direction: column;border: 2px solid black;}
.inner-left-box ul li {list-style: none;writing-mode: vertical-lr;}
<div class="container">
<div class="left-box">
<div class="inner-left-box">
<ul>
<li class="menu">menu 1</li>
<li class="menu">menu 2</li>
</ul>
</div>
</div>
<div class="right-box">Right Box</div>
</div>
The answer is in the question's edited answer for the writing-mode solution actually. The only problem was the flex: 1 1 auto style on the red-border div, removing it solves the width problem.
HTML w/ Style Tag Variant
<div id='container' style='display: flex; border: 3px solid green; flex-direction: row'>
<div style='display: flex; flex-direction: column; border: 3px solid red;'>
<div style='flex: 0 0 auto; display: inline-block; flex-direction: row; writing-mode: vertical-rl; border: 3px solid black;'>
<div style='flex: 0 0 auto; border: 1px solid green; display: inline-block'>
menu 1
</div>
<div style='flex: 0 0 auto; border: 1px solid green; display: inline-block'>
menu 2
</div>
</div>
</div>
<div id='rightbox' style='display: flex; flex: 1 1 auto; border: 3px solid orange';>
Right Box
</div>
</div>
CSS Classes Variant
#container
{
display: flex;
flex-direction: row;
border: 3px solid green;
}
#leftbox
{
display: flex;
flex-direction: column;
border: 3px solid red;
}
#inner-leftbox
{
display: inline-block;
flex-direction: row;
flex: 0 0 auto;
writing-mode: vertical-rl;
border: 3px solid black;
}
#rightbox
{
display: flex;
flex: 1 1 auto;
border: 3px solid orange;
}
.menu
{
display: inline-block;
flex: 0 0 auto;
border: 1px solid green;
}
<div id="container">
<div id="leftbox">
<div id="inner-leftbox">
<div class="menu">menu 1</div>
<div class="menu">menu 2</div>
</div>
</div>
<div id="rightbox">
Right Box
</div>
</div>

CSS Flexbox Wrap First of Line

I'm struggling with the wrapping option of the css flexbox in combination with margins between the items.
What I'm trying to archieve is: Have a flexcontainer with wrapping enabled and a number of items with variable with and minimum width. Between these items I want to have a small gap (margin) but I don't want a margin between the item and the container on the left or right side.
Right now I'm using the first-child and last-child pseudo class but this approach doesn't work unfortunatly when the container wraps the content. See JsFiddle for a minimalistic demo.
HTML
<div class="container">
<div class="item">A</div>
<div class="item">B</div>
<div class="item">C</div>
<div class="item">D</div>
<div class="item">E</div>
</div>
CSS
.container {
display: flex;
flex-wrap: wrap;
border: 1px solid red;
}
.item {
min-width: 100px;
flex: 1;
border: 1px solid black;
margin-left: 20px;
margin-right: 20px;
}
.item:first-child {
margin-left: 0px;
}
.item:last-child {
margin-right: 0px;
}
Any suggestions?
flexbox has some specific properties, so in your case this is what needs to be fixed:
instead of min-width use flex-basis
use justify-content: space-between
to apply margin on items there's a special hack (check out the
example -to fix border coherency apply a wrapper);
.container-bg {
width:100%;
border: 1px solid green;
overflow:hidden;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
/* border: 1px solid red;*/
margin: 0 -20px;
}
.item {
/*min-width: 100px;*/
flex: 1 0 100px;/*if you want to set 100px as min-width you'll have to set flex-shrink to 0*/
border: 1px solid black;
margin: 0 20px;
}
/*.item:first-child {
margin-left: 0px;
}
.item:last-child {
margin-right: 0px;
}*/
<p>resize the window for wrapping</p>
<div class="container-bg"><div class="container">
<div class="item">A</div>
<div class="item">B</div>
<div class="item">C</div>
<div class="item">D</div>
<div class="item">E</div>
</div></div>
EDIT :
set flex-shrink to 0 is don't want to go below a certain width..
If you add another wrapper around your items, you can use this dirty hack: https://jsfiddle.net/xw5uo2j1/13/
You set your main container to be 100% of the width, then your "sub" container to be 100% plus the amount of space between you're going to add. Then add the same amount of margin-right to the items.
.maincontainer {
width:100%;
border: 1px solid red;
}
.container {
display: flex;
flex-flow: row wrap;
justify-content:space-between;
align-content:space-between;
width:calc(100% + 5px);
}
.item {
min-width: 100px;
flex: 1;
border: 1px solid black;
margin-right:5px;
}
<p>resize the window for wrapping</p>
<div class="maincontainer">
<div class="container">
<div class="item">A</div>
<div class="item">B</div>
<div class="item">C</div>
<div class="item">D</div>
<div class="item">E</div>
</div>
</div>
UPDATED, with more than 5 items
Use calc and jusify-content: space-between;
* {
box-sizing: border-box;
margin: 0;
}
.container {
border: thin solid red;
display: -webkit-flex;
display: flex;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
margin: 0 -10px;
}
.item {
border: thin solid black;
-webkit-flex: 1 1 calc(20% - 20px);
flex: 1 1 calc(20% - 20px);
margin: 0 10px;
padding: 20px;
position: relative;
}
<div class="container">
<div class="item">A</div>
<div class="item">B</div>
<div class="item">C</div>
<div class="item">D</div>
<div class="item">E</div>
</div>