Can't understand css flexbox in this situation [duplicate] - css

I have three elements I'm trying to align in my layout.
First, I have a div for feedback, and then a search input, and then a div element for suggestions.
I want the first and last element to have a width of 20%, and the search input to have a width of 60%. Using Flexbox I achieve what I want.
But there's a feature that grows all the divs to the highest element. This means that when search results pop up, the feedback and suggestion elements grow in height with the search div resulting in a messed up layout.
Is there a trick to not grow the divs with the highest element? Just make the divs (#feedback and #suggestions) have the height of the content in them?
#container_add_movies {
display: flex;
}
#container_add_movies #feedback {
width: 20%;
background-color: green;
}
#container_add_movies #search {
width: 60%;
background-color: red;
}
#container_add_movies #suggestions {
width: 20%;
background-color: yellow;
}
<div id='container_add_movies'>
<div id='feedback'>
Feedback
</div>
<div id='search'>
Search
<br>Search
<br>Search
<br>Search
<br>Search
<br>Search
<br>Search
<br>Search
<br>Search
<br>Search
<br>
</div>
<div id='suggestions'>
Suggestions
</div>
</div>
http://codepen.io/alucardu/pen/PPjRzY

You're encountering the flex equal height columns feature.
An initial setting of a flex container is align-items: stretch.
This means that flex items automatically expand the full length of the cross axis of the container. In a row-direction container, the cross axis is vertical (height).
The tallest item sets the height for all siblings. As the tallest item expands, its siblings follow along. Hence, equal height for all items.
To override this default setting, add align-items: flex-start to the flex container:
#container_add_movies {
display: flex;
align-items: flex-start;
}
#container_add_movies {
display: flex;
align-items: flex-start; /* NEW */
}
#container_add_movies #feedback {
width: 20%;
background-color: green;
display: block;
}
#container_add_movies #search {
width: 60%;
background-color: red;
}
#container_add_movies #suggestions {
width: 20%;
background-color: yellow;
}
<div id='container_add_movies'>
<div id='feedback'>Feedback</div>
<div id='search'>
Search<br>Search<br>Search<br>Search<br>Search<br> Search
<br>Search<br>Search<br>Search<br>Search<br>
</div>
<div id='suggestions'>Suggestions</div>
</div>
... or align-self: flex-start to the flex items:
#feedback {
align-self: flex-start;
width: 20%;
background-color: green;
}
#suggestions {
align-self: flex-start;
width: 20%;
background-color: yellow;
}
#container_add_movies {
display: flex;
}
#container_add_movies #search {
width: 60%;
background-color: red;
}
#feedback {
align-self: flex-start; /* NEW */
width: 20%;
background-color: green;
}
#suggestions {
align-self: flex-start; /* NEW */
width: 20%;
background-color: yellow;
}
<div id='container_add_movies'>
<div id='feedback'>Feedback</div>
<div id='search'>
Search<br>Search<br>Search<br>Search<br>Search<br> Search
<br>Search<br>Search<br>Search<br>Search<br>
</div>
<div id='suggestions'>Suggestions</div>
</div>
align-items sets the default value of align-self. With align-self you can override the default on individual items.
More details in the spec:
8.3. Cross-axis Alignment: the align-items and align-self
properties
Flex items can be aligned in the cross axis of the current line of the
flex container, similar to justify-content but in the perpendicular
direction.
align-items sets the default alignment for all of the flex
container’s items, including anonymous flex items.
align-self allows this default alignment to be overridden for
individual flex items.
A bit of history
Since the beginnings of CSS, there have been two layout challenges that have regularly frustrated, perplexed, and annoyed front-end developers:
How to center things, especially vertically, and
How to create equal height columns (tables aside)
Today, with the advent of flexbox, these problems are over.
Centering things has never been easier:
#container {
display: flex;
justify-content: center; /* center flex items along the main axis */
align-items: center; /* center flex items along the cross axis */
}
Simple. Easy. Efficient. The craziness is over.
In terms of equal height columns, flexbox also excels: It does this by default.
#container {
display: flex;
flex-direction: row; /* not even necessary; default rule */
align-items: stretch; /* not even necessary; default rule */
}
The align-items: stretch rule tells flex items to expand along the cross-axis as much as possible. Hence, in a row-direction container all items can be equal height. More craziness tamed by flexbox.
From one popular answer for equal height columns:
Give overflow: hidden to the container and large (and equal)
negative margin and positive padding to columns. Note that this
method has some problems, e.g. anchor links won't work within your
layout.
Now that's a hack!
The pendulum is now beginning to swing the other way: Designers are asking how to TURN OFF equal height columns.

You can add align-items: flex-start to your #container_add_movies. Here's an example

to have the unequal columns in bootstrap 4, first of all it needs to know how it is making it equal heights of the columns,so the reason is the
align-items: stretch
to remove this property it need to add align-items: flex-start so for this I have added the class="align-items-start" and the issue is fixed,

Setting the child element that was causing the problem to flex:none did the trick for me.

Related

What is difference between justify-self, justify-items and justify-content in CSS grid?

I'm really confused. When looking for online resources and documentation, most of the documentation of these properties seem to reference Flex-box, not grid. And I don't know how applicable the documentation for the equivalent properties in Flex-box is to grid.
So, I've tried referencing https://css-tricks.com/snippets/css/complete-guide-grid/, which defines them as follows:
justify-items - Aligns the content inside a grid item along the row axis
justify-content - This property aligns the grid along the row axis
justify-self - Aligns the content inside a grid item along the row axis
But I still don't understand what the difference between them is. So, I have 3 questions I want to clarify.
Is the justify-items property in Flex-box the same as the
justify-items property in Grid? or are they different somehow?
(In other words, can I reuse Flex-box documentation for Grid)
What do (justify-)content, self and items do?
How are (justify-)content, self and items different?
Any clarification would be greatly appreciated.
Edit: Since everyone keeps giving me Flex-box resources, I am asking about css-grid, NOT flex-box.
To answer your questions:
1
As reiallenramos mentioned, "The justify-self and justify-items properties are not implemented in flexbox. This is due to the one-dimensional nature of flexbox, and that there may be multiple items along the axis, making it impossible to justify a single item. To align items along the main, inline axis in flexbox you use the justify-content property." - MDN
2-3
This screen shot from W3 does an excellent job of showing what they do and the differences between them.
Good To Knows:
For more information and example, I would suggest you check out:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Box_Alignment_in_CSS_Grid_Layout
https://www.smashingmagazine.com/2017/06/building-production-ready-css-grid-layout/
https://www.smashingmagazine.com/2017/12/grid-inspector/
And for some inspiration:
https://www.smashingmagazine.com/2017/10/css-grid-challenge-2017-winners/
Key differences between justify-content, justify-items and justify-self in CSS Grid:
The justify-content property controls the alignment of grid columns. It is set on the grid container. It does not apply to or control the alignment of grid items.
The justify-items property controls the alignment of grid items. It is set on the grid container.
The justify-self property overrides justify-items on individual items. It is set on grid items and inherits the value of justify-items, by default.
Example
Here's a 2x3 grid.
2 columns, each 100px wide
3 rows, each 50px tall
The container is:
500px wide
250px tall
.container {
display: grid;
grid-template-columns: 100px 100px;
grid-template-rows: 50px 50px 50px;
width: 500px;
height: 250px;
grid-template-areas: " one two"
" three four"
" five six ";
}
.box:nth-child(1) { grid-area: one; }
.box:nth-child(2) { grid-area: two; }
.box:nth-child(3) { grid-area: three; }
.box:nth-child(4) { grid-area: four; }
.box:nth-child(5) { grid-area: five; }
.box:nth-child(6) { grid-area: six; }
/* non-essential decorative styles */
body {
display: flex;
justify-content: center;
}
.container {
background-color: #ddd;
border: 1px solid #aaa;
}
.box {
background-color: lightgreen;
border: 1px solid gray;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.2em;
}
<div class="container">
<div class="box"><span>1</span></div>
<div class="box"><span>2</span></div>
<div class="box"><span>3</span></div>
<div class="box"><span>4</span></div>
<div class="box"><span>5</span></div>
<div class="box"><span>6</span></div>
</div>
justify-content
The justify-content property aligns columns within the container.
.container {
justify-content: space-between;
}
.container {
display: grid;
grid-template-columns: 100px 100px;
grid-template-rows: 50px 50px 50px;
width: 500px;
height: 250px;
grid-template-areas: " one two"
" three four"
" five six ";
}
.box:nth-child(1) { grid-area: one; }
.box:nth-child(2) { grid-area: two; }
.box:nth-child(3) { grid-area: three; }
.box:nth-child(4) { grid-area: four; }
.box:nth-child(5) { grid-area: five; }
.box:nth-child(6) { grid-area: six; }
/* non-essential decorative styles */
body {
display: flex;
justify-content: center;
}
.container {
background-color: #ddd;
border: 1px solid #aaa;
}
.box {
background-color: lightgreen;
border: 1px solid gray;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.2em;
}
<div class="container">
<div class="box"><span>1</span></div>
<div class="box"><span>2</span></div>
<div class="box"><span>3</span></div>
<div class="box"><span>4</span></div>
<div class="box"><span>5</span></div>
<div class="box"><span>6</span></div>
</div>
With justify-content: space-between both columns are pinned to the edges. The grid items shift only because they exist inside those columns. They are otherwise unaffected.
Note that this property works only when there is free space in the container. If any of the columns were sized with fr, then all free space would be consumed, and justify-content would have no effect.
justify-items
The justify-items property aligns grid items within their tracks (not the entire container)
.container {
justify-items: center;
}
.container {
display: grid;
grid-template-columns: 100px 100px;
grid-template-rows: 50px 50px 50px;
width: 500px;
height: 250px;
grid-template-areas: " one two"
" three four"
" five six ";
}
.box:nth-child(1) { grid-area: one; }
.box:nth-child(2) { grid-area: two; }
.box:nth-child(3) { grid-area: three; }
.box:nth-child(4) { grid-area: four; }
.box:nth-child(5) { grid-area: five; }
.box:nth-child(6) { grid-area: six; }
/* non-essential decorative styles */
body {
display: flex;
justify-content: center;
}
.container {
background-color: #ddd;
border: 1px solid #aaa;
}
.box {
background-color: lightgreen;
border: 1px solid gray;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.2em;
}
<div class="container">
<div class="box"><span>1</span></div>
<div class="box"><span>2</span></div>
<div class="box"><span>3</span></div>
<div class="box"><span>4</span></div>
<div class="box"><span>5</span></div>
<div class="box"><span>6</span></div>
</div>
With justify-items: center the grid items are centered within their columns.
justify-self
The justify-self property overrides justify-items on individual items.
.container { justify-items: center;}
.box:nth-child(2) { justify-self: start; }
.box:nth-child(3) { justify-self: end; }
.box:nth-child(6) { justify-self: stretch; }
.container {
display: grid;
grid-template-columns: 100px 100px;
grid-template-rows: 50px 50px 50px;
width: 500px;
height: 250px;
grid-template-areas: " one two"
" three four"
" five six ";
}
.box:nth-child(1) { grid-area: one; }
.box:nth-child(2) { grid-area: two; }
.box:nth-child(3) { grid-area: three; }
.box:nth-child(4) { grid-area: four; }
.box:nth-child(5) { grid-area: five; }
.box:nth-child(6) { grid-area: six; }
/* non-essential decorative styles */
body {
display: flex;
justify-content: center;
}
.container {
background-color: #ddd;
border: 1px solid #aaa;
}
.box {
background-color: lightgreen;
border: 1px solid gray;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.2em;
}
<div class="container">
<div class="box"><span>1</span></div>
<div class="box"><span>2</span></div>
<div class="box"><span>3</span></div>
<div class="box"><span>4</span></div>
<div class="box"><span>5</span></div>
<div class="box"><span>6</span></div>
</div>
align-content, align-items and align-self
These properties do the same as their justify-* counterparts, but in the perpendicular direction.
More here: What is the difference between align-items vs. align-content in Grid Layout?
Spec Reference
10.3. Row-axis Alignment: the justify-self and justify-items
properties
Grid items can be aligned in the inline dimension by using the
justify-self property on the grid item or justify-items property
on the grid container.
10.4. Column-axis Alignment: the align-self and align-items
properties
Grid items can also be aligned in the block dimension (perpendicular
to the inline dimension) by using the align-self property on the
grid item or align-items property on the grid container.
10.5. Aligning the Grid: the justify-content and align-content
properties
If the grid’s outer edges do not correspond to the grid container’s
content edges (for example, if no columns are flex-sized), the grid
tracks are aligned within the content box according to the
justify-content and align-content properties on the grid
container.
(emphasis added)
CSS Box Alignment Module
You wrote:
Is the justify-items property in Flex-box the same as the justify-items property in Grid?
Although the Flex and Grid specs provide their own definitions for keyword alignment properties, such as justify-items and align-content, the W3C is in the process of phasing out alignment properties for individual box models and implementing their new Box Alignment Module, which seeks to define a set of alignment properties for use across all box models.
From the flexbox spec:
1.2. Module
interactions
The CSS Box Alignment Module extends and supercedes the definitions of
the alignment properties (justify-content, align-items,
align-self, align-content) introduced here.
There are similar references in the Grid spec.
OK, I think I figured it out thanks to Michael_B. My confusion came from the fact that sometimes different properties would randomly not change anything about the layout of the grid.
justify-content allows you to position the grid within it's grid container. This is why the justify-content property will have no effect if the grid-container is the same size as the grid. (Which is always the case if you use fr units). This is also why it can have the values: space-around, space-between and space-evenly (In addition to start, end, centre and stretch), which will break up the grid and place the grid items within the grid container. This is a property of the grid container.
justify-items allows you to set a default position for content placed in the grid's grid items (A grid item being a box in the grid, as defined in Michael_B's post). This is a property of the grid container.
justify-self allows you to override the default position of content in an individual cell. This will override the position set by justify-items. Hence, if you use justify-self on all children of the container, setting justify-items on the grid container will have no effect. This is a property of the content inside a grid item.
Note: If you make a grid-item a grid itself, (In other words, the content inside a grid item is a grid) then you can position it within the outer grid item using either the justify-self property or the justify-content property on the inner grid's grid container, since the inner-grid's grid container is one of the outer grid's grid items's content.
As you might expect, all of this also applies to the align-* properties.
Please correct me if I got anything wrong
justify-content is used to position the entire grid along the row/inline axis of the grid container when the total size of the grid items is less than the grid container.
justify-items is used on a grid container and is used to determine how grid items are spread out along a row by setting the default justify-self property for all child boxes.
justify-self is used to set how an individual grid item positions itself along the row/inline axis. Grid items inherit the value of the justify-items property on the container by default, so if the justify-self value is set, it would override the inherited justify-items value.
Source: Codecademy CSS Grid cheatsheet

How to adapt height of div to its content while in flex wrapper [duplicate]

I have three elements I'm trying to align in my layout.
First, I have a div for feedback, and then a search input, and then a div element for suggestions.
I want the first and last element to have a width of 20%, and the search input to have a width of 60%. Using Flexbox I achieve what I want.
But there's a feature that grows all the divs to the highest element. This means that when search results pop up, the feedback and suggestion elements grow in height with the search div resulting in a messed up layout.
Is there a trick to not grow the divs with the highest element? Just make the divs (#feedback and #suggestions) have the height of the content in them?
#container_add_movies {
display: flex;
}
#container_add_movies #feedback {
width: 20%;
background-color: green;
}
#container_add_movies #search {
width: 60%;
background-color: red;
}
#container_add_movies #suggestions {
width: 20%;
background-color: yellow;
}
<div id='container_add_movies'>
<div id='feedback'>
Feedback
</div>
<div id='search'>
Search
<br>Search
<br>Search
<br>Search
<br>Search
<br>Search
<br>Search
<br>Search
<br>Search
<br>Search
<br>
</div>
<div id='suggestions'>
Suggestions
</div>
</div>
http://codepen.io/alucardu/pen/PPjRzY
You're encountering the flex equal height columns feature.
An initial setting of a flex container is align-items: stretch.
This means that flex items automatically expand the full length of the cross axis of the container. In a row-direction container, the cross axis is vertical (height).
The tallest item sets the height for all siblings. As the tallest item expands, its siblings follow along. Hence, equal height for all items.
To override this default setting, add align-items: flex-start to the flex container:
#container_add_movies {
display: flex;
align-items: flex-start;
}
#container_add_movies {
display: flex;
align-items: flex-start; /* NEW */
}
#container_add_movies #feedback {
width: 20%;
background-color: green;
display: block;
}
#container_add_movies #search {
width: 60%;
background-color: red;
}
#container_add_movies #suggestions {
width: 20%;
background-color: yellow;
}
<div id='container_add_movies'>
<div id='feedback'>Feedback</div>
<div id='search'>
Search<br>Search<br>Search<br>Search<br>Search<br> Search
<br>Search<br>Search<br>Search<br>Search<br>
</div>
<div id='suggestions'>Suggestions</div>
</div>
... or align-self: flex-start to the flex items:
#feedback {
align-self: flex-start;
width: 20%;
background-color: green;
}
#suggestions {
align-self: flex-start;
width: 20%;
background-color: yellow;
}
#container_add_movies {
display: flex;
}
#container_add_movies #search {
width: 60%;
background-color: red;
}
#feedback {
align-self: flex-start; /* NEW */
width: 20%;
background-color: green;
}
#suggestions {
align-self: flex-start; /* NEW */
width: 20%;
background-color: yellow;
}
<div id='container_add_movies'>
<div id='feedback'>Feedback</div>
<div id='search'>
Search<br>Search<br>Search<br>Search<br>Search<br> Search
<br>Search<br>Search<br>Search<br>Search<br>
</div>
<div id='suggestions'>Suggestions</div>
</div>
align-items sets the default value of align-self. With align-self you can override the default on individual items.
More details in the spec:
8.3. Cross-axis Alignment: the align-items and align-self
properties
Flex items can be aligned in the cross axis of the current line of the
flex container, similar to justify-content but in the perpendicular
direction.
align-items sets the default alignment for all of the flex
container’s items, including anonymous flex items.
align-self allows this default alignment to be overridden for
individual flex items.
A bit of history
Since the beginnings of CSS, there have been two layout challenges that have regularly frustrated, perplexed, and annoyed front-end developers:
How to center things, especially vertically, and
How to create equal height columns (tables aside)
Today, with the advent of flexbox, these problems are over.
Centering things has never been easier:
#container {
display: flex;
justify-content: center; /* center flex items along the main axis */
align-items: center; /* center flex items along the cross axis */
}
Simple. Easy. Efficient. The craziness is over.
In terms of equal height columns, flexbox also excels: It does this by default.
#container {
display: flex;
flex-direction: row; /* not even necessary; default rule */
align-items: stretch; /* not even necessary; default rule */
}
The align-items: stretch rule tells flex items to expand along the cross-axis as much as possible. Hence, in a row-direction container all items can be equal height. More craziness tamed by flexbox.
From one popular answer for equal height columns:
Give overflow: hidden to the container and large (and equal)
negative margin and positive padding to columns. Note that this
method has some problems, e.g. anchor links won't work within your
layout.
Now that's a hack!
The pendulum is now beginning to swing the other way: Designers are asking how to TURN OFF equal height columns.
You can add align-items: flex-start to your #container_add_movies. Here's an example
to have the unequal columns in bootstrap 4, first of all it needs to know how it is making it equal heights of the columns,so the reason is the
align-items: stretch
to remove this property it need to add align-items: flex-start so for this I have added the class="align-items-start" and the issue is fixed,
Setting the child element that was causing the problem to flex:none did the trick for me.

Responsive arrangement of divs with flexbox [duplicate]

I have 3 divs inside a container. There are no nested divs.
I am using flex and order property.
On mobile, it is ok with order property.
But on larger screens it fails.
I did not use a container div for divs 2 and 3 in order to order them as 2,1,3 on mobile.
HTML FILE
<div class="container">
<div class="orange">1</div>
<div class="blue">2</div>
<div class="green">3</div>
</div>
CSS FILE
/*************** MOBILE *************/
.container
{
display: flex;
flex-wrap: wrap;
}
div.blue
{
order:1;
width: 100%;
}
div.orange
{
order:2;
width: 100%;
}
div.green
{
order:3;
width: 100%;
}
/***************************/
#media screen and (min-width:1200px)
{
.container
{
justify-content: space-between;
}
div.blue
{
order:2;
width: 36%;
}
div.orange
{
order:1;
width: 60%;
}
div.green
{
order:3;
width: 36%;
}
}
In your layout, using row wrap for the desktop view will be difficult, if not impossible, to implement with CSS. At a minimum, things would get overly complex. Why?
Because flexbox is not a grid system. It's a layout system designed to align content by distribution of space in the container.
In flexbox, items in a row wrap container must wrap to new rows. This means that div3 cannot wrap beneath div2. It must wrap beneath div1.
Here's how items wrap in a flex container with row wrap:
If div3 were to wrap under div2, that wouldn't be a row, that would be a grid, and flex items are confined to a straight, unbending row.
Put another way, you can't make a flex item wrap under another item in the same row.
As a result, white space created by items that aren't the tallest in the row is preserved in each column, creating unsightly gaps.
For your desired layout to work in row wrap, flex items would have to exit their row in order to close the gap – maybe with absolute positioning – which flexbox cannot do.
One way to align the items would be to wrap div2 and div3 in their own container. This new container would be a sibling to div1. It can then become a nested flex container with flex-direction: column. Now the gaps are gone and layout looks right.
Except, in this particular case, you need the order property to work (meaning all items must have the same parent), so a nested flex container is out of the question.
What may work is column wrap instead of row wrap:
/*************** MOBILE *************/
.container {
display: flex;
flex-direction: column;
height: 200px; /* necessary so items know where to wrap */
}
div.orange {
background-color: orange;
}
div.blue {
order: -1;
background-color: aqua;
}
div.green {
background-color: lightgreen;
}
.container > div {
width: 100%;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
/***************************/
#media screen and (min-width: 800px) {
.container {
flex-wrap: wrap;
}
div.orange {
flex-basis: 100%;
width: 50%;
}
div.blue {
flex-basis: 50%;
width: 50%;
order: 0;
}
div.green {
flex-basis: 50%;
width: 50%;
}
}
<div class="container">
<div class="orange">1</div>
<div class="blue">2</div>
<div class="green">3</div>
</div>
jsFiddle
Here are two other options:
Desandro Masonry
Masonry is a JavaScript grid layout library. It
works by placing elements in optimal position based on available
vertical space, sort of like a mason fitting stones in a wall.
source: http://masonry.desandro.com/
CSS Grid Layout Module Level 1
This CSS module defines a two-dimensional grid-based layout system, optimized for user interface design. In the grid layout model, the children of a grid container can be positioned into arbitrary slots in a predefined flexible or fixed-size layout grid.
source: https://drafts.csswg.org/css-grid/
Related post: Is it possible for flex items to align tightly to the items above them?

Masonry with Flexbox, dynamic height [duplicate]

I have 3 divs inside a container. There are no nested divs.
I am using flex and order property.
On mobile, it is ok with order property.
But on larger screens it fails.
I did not use a container div for divs 2 and 3 in order to order them as 2,1,3 on mobile.
HTML FILE
<div class="container">
<div class="orange">1</div>
<div class="blue">2</div>
<div class="green">3</div>
</div>
CSS FILE
/*************** MOBILE *************/
.container
{
display: flex;
flex-wrap: wrap;
}
div.blue
{
order:1;
width: 100%;
}
div.orange
{
order:2;
width: 100%;
}
div.green
{
order:3;
width: 100%;
}
/***************************/
#media screen and (min-width:1200px)
{
.container
{
justify-content: space-between;
}
div.blue
{
order:2;
width: 36%;
}
div.orange
{
order:1;
width: 60%;
}
div.green
{
order:3;
width: 36%;
}
}
In your layout, using row wrap for the desktop view will be difficult, if not impossible, to implement with CSS. At a minimum, things would get overly complex. Why?
Because flexbox is not a grid system. It's a layout system designed to align content by distribution of space in the container.
In flexbox, items in a row wrap container must wrap to new rows. This means that div3 cannot wrap beneath div2. It must wrap beneath div1.
Here's how items wrap in a flex container with row wrap:
If div3 were to wrap under div2, that wouldn't be a row, that would be a grid, and flex items are confined to a straight, unbending row.
Put another way, you can't make a flex item wrap under another item in the same row.
As a result, white space created by items that aren't the tallest in the row is preserved in each column, creating unsightly gaps.
For your desired layout to work in row wrap, flex items would have to exit their row in order to close the gap – maybe with absolute positioning – which flexbox cannot do.
One way to align the items would be to wrap div2 and div3 in their own container. This new container would be a sibling to div1. It can then become a nested flex container with flex-direction: column. Now the gaps are gone and layout looks right.
Except, in this particular case, you need the order property to work (meaning all items must have the same parent), so a nested flex container is out of the question.
What may work is column wrap instead of row wrap:
/*************** MOBILE *************/
.container {
display: flex;
flex-direction: column;
height: 200px; /* necessary so items know where to wrap */
}
div.orange {
background-color: orange;
}
div.blue {
order: -1;
background-color: aqua;
}
div.green {
background-color: lightgreen;
}
.container > div {
width: 100%;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
/***************************/
#media screen and (min-width: 800px) {
.container {
flex-wrap: wrap;
}
div.orange {
flex-basis: 100%;
width: 50%;
}
div.blue {
flex-basis: 50%;
width: 50%;
order: 0;
}
div.green {
flex-basis: 50%;
width: 50%;
}
}
<div class="container">
<div class="orange">1</div>
<div class="blue">2</div>
<div class="green">3</div>
</div>
jsFiddle
Here are two other options:
Desandro Masonry
Masonry is a JavaScript grid layout library. It
works by placing elements in optimal position based on available
vertical space, sort of like a mason fitting stones in a wall.
source: http://masonry.desandro.com/
CSS Grid Layout Module Level 1
This CSS module defines a two-dimensional grid-based layout system, optimized for user interface design. In the grid layout model, the children of a grid container can be positioned into arbitrary slots in a predefined flexible or fixed-size layout grid.
source: https://drafts.csswg.org/css-grid/
Related post: Is it possible for flex items to align tightly to the items above them?

Flexbox wrapping issues [duplicate]

I have 3 divs inside a container. There are no nested divs.
I am using flex and order property.
On mobile, it is ok with order property.
But on larger screens it fails.
I did not use a container div for divs 2 and 3 in order to order them as 2,1,3 on mobile.
HTML FILE
<div class="container">
<div class="orange">1</div>
<div class="blue">2</div>
<div class="green">3</div>
</div>
CSS FILE
/*************** MOBILE *************/
.container
{
display: flex;
flex-wrap: wrap;
}
div.blue
{
order:1;
width: 100%;
}
div.orange
{
order:2;
width: 100%;
}
div.green
{
order:3;
width: 100%;
}
/***************************/
#media screen and (min-width:1200px)
{
.container
{
justify-content: space-between;
}
div.blue
{
order:2;
width: 36%;
}
div.orange
{
order:1;
width: 60%;
}
div.green
{
order:3;
width: 36%;
}
}
In your layout, using row wrap for the desktop view will be difficult, if not impossible, to implement with CSS. At a minimum, things would get overly complex. Why?
Because flexbox is not a grid system. It's a layout system designed to align content by distribution of space in the container.
In flexbox, items in a row wrap container must wrap to new rows. This means that div3 cannot wrap beneath div2. It must wrap beneath div1.
Here's how items wrap in a flex container with row wrap:
If div3 were to wrap under div2, that wouldn't be a row, that would be a grid, and flex items are confined to a straight, unbending row.
Put another way, you can't make a flex item wrap under another item in the same row.
As a result, white space created by items that aren't the tallest in the row is preserved in each column, creating unsightly gaps.
For your desired layout to work in row wrap, flex items would have to exit their row in order to close the gap – maybe with absolute positioning – which flexbox cannot do.
One way to align the items would be to wrap div2 and div3 in their own container. This new container would be a sibling to div1. It can then become a nested flex container with flex-direction: column. Now the gaps are gone and layout looks right.
Except, in this particular case, you need the order property to work (meaning all items must have the same parent), so a nested flex container is out of the question.
What may work is column wrap instead of row wrap:
/*************** MOBILE *************/
.container {
display: flex;
flex-direction: column;
height: 200px; /* necessary so items know where to wrap */
}
div.orange {
background-color: orange;
}
div.blue {
order: -1;
background-color: aqua;
}
div.green {
background-color: lightgreen;
}
.container > div {
width: 100%;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
/***************************/
#media screen and (min-width: 800px) {
.container {
flex-wrap: wrap;
}
div.orange {
flex-basis: 100%;
width: 50%;
}
div.blue {
flex-basis: 50%;
width: 50%;
order: 0;
}
div.green {
flex-basis: 50%;
width: 50%;
}
}
<div class="container">
<div class="orange">1</div>
<div class="blue">2</div>
<div class="green">3</div>
</div>
jsFiddle
Here are two other options:
Desandro Masonry
Masonry is a JavaScript grid layout library. It
works by placing elements in optimal position based on available
vertical space, sort of like a mason fitting stones in a wall.
source: http://masonry.desandro.com/
CSS Grid Layout Module Level 1
This CSS module defines a two-dimensional grid-based layout system, optimized for user interface design. In the grid layout model, the children of a grid container can be positioned into arbitrary slots in a predefined flexible or fixed-size layout grid.
source: https://drafts.csswg.org/css-grid/
Related post: Is it possible for flex items to align tightly to the items above them?

Resources