Reputation: 1995
I have a flexbox within a flexbox (JSFiddle):
The problem is that the items in the left div start to wrap earlier than necessary (the left div still has room to shrink).
The inner flexbox should only wrap after the outer flexbox has wrapped - as long as there is still space for the outer flexbox, the inner flexbox should not wrap and the outer flexbox should shrink, instead.
I tried to give .b_row
a width of 100%, but that didn't work.
.m {
display: flex;
flex-wrap: wrap;
}
.l_1 {
background-color: red;
flex: 1;
padding: 15px;
margin-left: auto;
margin-right: auto;
}
.r_1 {
background-color: yellow;
flex: 1;
padding: 25px;
margin-left: auto;
margin-right: auto;
}
.b_1 {
padding: 15px;
border-radius: 4px;
}
.b_row {
display: flex;
flex-wrap: wrap;
width: 100%;
}
.b_item {
flex: 1;
}
<div class=m>
<div class=l_1>
<div class=b_1>
Left text
<div class=b_row>
<div class=b_item>Item 1
<br>
<input class=datepicker type=text size=10>
</div>
<div class=b_item>Item 2
<br>
<input class=datepicker type=text size=10>
</div>
</div>
</div>
</div>
<div class=r_1>Right Item</div>
</div>
Upvotes: 11
Views: 4176
Reputation: 64164
You can control the wrapping behaviour using flex-basis in the inner elements.
(Solution without media queries)
.outer {
display: flex;
flex-wrap: wrap;
border: solid 1px red;
padding: 10px;
}
.inner {
display: flex;
flex-wrap: wrap;
border: solid 1px blue;
padding: 10px;
flex-basis: 200px;
flex-grow: 1;
}
.left {
flex-basis: 100px;
flex-grow: 1;
}
#right {
flex-basis: 100px;
flex-grow: 1;
border: solid 1px green;
}
#o1 {
width: 400px;
}
#o2 {
width: 300px;
}
#o3 {
width: 200px;
}
<div class="outer" id="o1">
<div class="inner">
<div class="left">Left 1</div>
<div class="left">Left 2</div>
</div>
<div id="right">Right</div>
</div>
<div class="outer" id="o2">
<div class="inner">
<div class="left">Left 1</div>
<div class="left">Left 2</div>
</div>
<div id="right">Right</div>
</div>
<div class="outer" id="o3">
<div class="inner">
<div class="left">Left 1</div>
<div class="left">Left 2</div>
</div>
<div id="right">Right</div>
</div>
Upvotes: 3
Reputation: 76
using a media query to control the wrapping behavior. Certainly, media queries will give you more control - especially when it comes to spacing elements apart from each other. check the code
body{
box-sizing:border-box;
}
.m {
display: flex;
flex-wrap: wrap;
}
.l_1 {
background-color: red;
flex: 1;
padding: 15px;
margin-left: auto;
margin-right: auto;
}
.r_1 {
background-color: yellow;
flex: 1;
padding: 25px;
margin-left: auto;
margin-right: auto;
}
.b_1 {
padding: 15px;
border-radius: 4px;
}
.b_row {
display: flex;
flex-wrap: wrap;
width: 100%;
}
.b_item {
flex: 1;
}
.b_item .datepicker{
width:calc(100% - 20px);
margin:0px 10px 0 0;
}
.b_item:last-child .datepicker{
margin-right:0;
}
@media screen and (max-width:480px){
.m, .b_row{
flex-direction:column;
}
.b_item .datepicker{
width:100%;
margin:0 0px 10px;
}
.r_1, .l_1{
margin:0;
}
}
<div class=m>
<div class=l_1>
<div class=b_1>
Left text
<div class=b_row>
<div class=b_item>Item 1
<br>
<input class=datepicker type=text size=10>
</div>
<div class=b_item>Item 2
<br>
<input class=datepicker type=text size=10>
</div>
</div>
</div>
</div>
<div class=r_1>Right Item</div>
</div>
Upvotes: 0
Reputation: 419
Certainly media queries will give you more control - especially when it comes to spacing elements apart from each other. I could only take it so far using CSS grid without media queries...
More about that here: https://css-tricks.com/look-ma-no-media-queries-responsive-layouts-using-css-grid/
and the basics: https://css-tricks.com/almanac/properties/g/grid-template-columns/
<div class=m>
<div class=l_1>
<div class=b_1>
Left text
<div class=b_row>
<div class=b_item>Item 1
<br>
<input class=datepicker type=text size=10>
</div>
<div class=b_item>Item 2
<br>
<input class=datepicker type=text size=10>
</div>
</div>
</div>
</div>
<div class=r_1>Right Item</div>
</div>
.m {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-auto-rows: 200px;
margin: 0 auto;
overflow: hidden;
box-sizing: border-box;
border: 1px solid red;
width: 100%;
}
.l_1 {
background-color: #ddd;
padding: 1em;
margin: 0 auto;
border: 1px solid red;
width: 100%;
grid-column: 1/3;
}
.r_1 {
background-color: #eee;
padding: 2em;
margin: 0 auto;
margin-left: 0;
border: 1px solid red;
width: 100vw;
}
.b_1 {
padding: 1em;
/*border-radius: 4px;
background-color: #febb02;
border-color: #e2aa11;
background-color: <? e($_COLORS['emph']);
?>;
border: 1px solid <? e($_COLORS['emph_dark']);
?>;*/
}
.b_row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
margin: 0 auto;
padding-right: 2.2em;
border: 1px solid red;
width: 100%;
}
.b_item {
border: 1px solid red;
max-width: calc(100% - 10px);
}
.b_item input {
width: 90%;
}
https://jsfiddle.net/z8swumkh/1/
Upvotes: 1
Reputation: 371203
Consider using a media query to control the wrapping behavior of the inner flex container.
Instead of this:
.b_row {
display: flex;
flex-wrap: wrap;
width: 100%;
}
Try something along these lines:
.b_row {
display: flex;
/* flex-wrap: wrap; */
width: 100%;
}
@media ( max-width: 300px ) {
.b_row { flex-wrap: wrap; }
}
Upvotes: 0