Make flex item wrap to the next row with following items continuing the flow
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>
Flexbox item wrap to a new line
If you look at this great answer you'll notice that the only cross-browser way (without 2 line break limit) is inserting 100%
-width empty blocks ("line-breaks"). So for similar markup this will look like
.flex {
display: flex;
flex-wrap: wrap;
border: 2px solid red;
}
.item {
width: 50px;
height: 50px;
margin: 5px;
border: 2px solid blue;
}
.line-break {
width: 100%;
}
<div class="flex">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="line-break"></div>
<div class="item"></div>
<div class="item"></div>
<div class="line-break"></div>
<div class="item"></div>
<div class="line-break"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
CSS: How can I ensure flex items wrap to the next line--after the first item--at a certain screen width?
Use the media query to apply flex-wrap:wrap
on the flex container and flex:0 0 100%
on the first child.
This way you don't need additional HTML markup, and no need to change anything on your code but the media query.
@media (max-width: 800px) {
.cart-cb{
flex-wrap:wrap;
}
.cart-cb div{
flex: 0 0 100%;
text-align:right;
}
}
https://jsfiddle.net/378b4yLy/
CSS: Push flex container item to next row on overflow
you could add to .box-2
min-width: fit-content;
.container {
max-width: 300px;
}
.wrappable {
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
-webkit-justify-content: space-between;
justify-content: space-between;
-webkit-align-items: center;
align-items: center;
margin-right: -0.625rem;
margin-bottom: -0.625rem;
}
.box-2 {
min-width: fit-content;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="wrappable">
<div class="box-1 wrappable-flex border rounded item-1">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, incididunt ut labore et
</div>
<div class="box-2 col-sm-12 col-md-6 col-lg-3 border rounded text-nowrap">
some other text I want to put in the same row
</div>
</div>
</div>
Make flex items wrap to existing lines, not new lines
When flex items wrap they create new lines.
In other words, a flex item won't wrap to an existing line.
That's why the second row of items gets pushed to a third row when the top row starts wrapping.
From the spec:
6. Flex Lines
A multi-line flex container (i.e. one with
flex-wrap: wrap
or
flex-wrap: wrap-reverse
) breaks its flex items across multiple
lines, similar to how text is broken onto a new line when it
gets too wide to fit on the existing line.
The quickest and easiest solution would be to put all flex items in the same container. (I understand you can't alter the HTML.)
How to specify line breaks in a multi-line flexbox layout?
The simplest and most reliable solution is inserting flex items at the right places. If they are wide enough (width: 100%
), they will force a line break.
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
align-content: space-between;
justify-content: space-between;
}
.item {
width: 100px;
background: gold;
height: 100px;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px
}
.item:nth-child(4n - 1) {
background: silver;
}
.line-break {
width: 100%;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="line-break"></div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="line-break"></div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="line-break"></div>
<div class="item">10</div>
</div>
Targeting flex items on the last or specific row
Unfortunately, in the current iteration of flexbox (Level 1), there is no clean way to solve the last-row alignment problem. It's a common problem.
It would be useful to have a flex property along the lines of:
last-row
last-column
only-child-in-a-row
alone-in-a-column
This problem does appear to be a high priority for Flexbox Level 2:
- CSS Working Group Wiki - Specification Issues and Planning
- https://lists.w3.org/Archives/Public/www-style/2015Jan/0150.html
Although this behavior is difficult to achieve in flexbox, it's simple and easy in CSS Grid Layout:
- Equal width flex items even after they wrap
In case Grid is not an option, here's a list of similar questions containing various flexbox hacks:
- Properly sizing and aligning the flex item(s) on the last row
- Flex-box: Align last row to grid
- Flexbox wrap - different alignment for last row
- How can a flex item keep the same dimensions when it is forced to a new row?
- Selector for an element alone in a row?
- Aligning elements in last flexbox row
- How can I allow flex-items to grow while keeping the same size?
- Left-align last row of flexbox using space-between and margins
- Inconsistent margin between flex items on last row
- How to keep wrapped flex-items the same width as the elements on the previous row?
- How to align left last row/line in multiple line flexbox
- Last children of grid get giant gutter cause of flexbox space-between
- Managing justify-content: space-between on last row
- Flexbox space between behavior combined with wrap
- Possible to use CSS Flexbox to stretch elements on every row while maintaining consistent widths?
Prevent next row taking up height of tallest item in previous row with flexbox?
Flexbox can't do that by itself in a flexible way.
As you mentioned yourself, CSS Grid can do this, though since you didn't want that, this suggestion is based on the assumption that you at narrower screens want the b
to be at the bottom.
By simply initially use float
, and then at a certain break point, swap between float
and display: flex
, it is very easy to take advantage of both.
Additionally, using Flexbox's order
property, one can easily position the elements in any desired order, and with this avoid script and get a reasonable level of browser support.
Updated codepen
Stack snippet
* {
box-sizing: border-box;
}
.cont {
background: gold;
overflow: hidden;
}
.a,
.b,
.c {
width: 45%;
padding: 10px;
float: left;
}
.a {
background: red;
}
.b {
background: blue;
color: white;
float: right;
}
.c {
background: orange;
}
@media (max-width: 500px) {
.a,
.b,
.c {
width: auto;
float: none;
}
.b {
order: 1;
}
.cont {
display: flex;
flex-direction: column;
}
}
<div class="cont">
<div class="a">
A
</div>
<div class="b">
B
<br>
More B
</div>
<div class="c">C</div>
</div>
CSS flex-wrap how to make the height do not stretch
The default direction of flex is row, and when you use flex-wrap: wrap
push overflowed element downed to another row, and the row height will default always equal to the highest element of that row, that why you seeing the element having that gap.
This can be done if you change the flex direction to column and give the wrap element a fixed height so it push overflowed element to it right, from top to bottom.
.wrap {
/*Added these*/
height: 300px;
flex-direction: column;
/*-----------*/
display: flex;
align-items: baseline;
align-content: space-around;
flex-wrap: wrap;
background-color: lightblue;
}
.box {
display: flex;
background-color: tomato;
box-sizing: border-box;
border: 1px solid #C4C4C4;
height: 100px;
width: 45%;
margin-top: 15px;
}
.box1, .box5 {
height: 20px;
}
<div class="wrap">
<div class="box box1">box1</div>
<div class="box box2">box2</div>
<div class="box box3">box3</div>
<div class="box box4">box4</div>
<div class="box box5">box5</div>
<div class="box box6">box6</div>
</div>
Related Topics
Why Does Width Apply to a Button with Display Inline
How to Make Last Cell of a Row in a Table Occupy All Remaining Width
How to Make Responsive Website for All Devices
If an HTML Form Has Two <Input Type="Submit"> Buttons, How to Know Which Got Clicked
Why Is "" Being Injected into My HTML
How to Use the Same Meta Tag for Opengraph and Schema.Org
Any Way of Using Frames in HTML5
100% Width Minus Margin and Padding
Flexbox with Fixed Header and Footer and Scrollable Content
How to Move an Element That's on the Top to the Bottom in Responsive Design
How to Change the Font-Size of an <Option> Element Within <Select>
Get Input Type=Text to Look Like Type=Password
How to Add Background Image for Input Type="Button"
Possible to Style the CSS3 Resize Function