Using Flex Order Property to Re-Arrange Items For Desktop and Mobile Views

Using flex order property to re-arrange items for desktop and mobile views

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:

Sample Image

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.

Sample Image

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>

CSS FlexBox | Reordering Elements in Mobile

You can consider display:contents (https://caniuse.com/#feat=css-display-contents) on the .box element then you will be able to use order on the inner elements:

.box {  color: white;  font-size: 80px;  text-align: center;  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1);  padding: 10px;  width: 100vw;}body { margin:0;}.container {  display: flex;  height: 100vh;  background:blue;}
.a,.b,.c,.d { height: 50%; border:2px solid;}
@media all and (max-width: 500px) { .container { flex-direction: column; } .box { display:contents; } .b { order:2; }}
<div class="container">  <div class="box box1">    <div class="a">a</div>    <div class="b">b</div>  </div>  <div class="box box2">    <div class="c">c</div>    <div class="d">d</div>  </div></div>

Re-arranging flexbox layout for mobile view

The layout you want is difficult to achieve with flexbox because flexbox is not well-suited for 2-dimensional grids. It excels at 1-dimensional grids (placing flex items in rows or columns), but has limited capacity in 2-dimensional grids (placing flex items in rows and columns).

Being that your desired layout involves items having to cross row and column lines, flex is not your best option. With CSS Grid, your layout is simple and easy.

jsFiddle demo

.box-wrapper {  display: grid;  grid-template-columns: 1fr 1fr 1fr;  /* 3 equal width columns */  grid-template-rows: 1fr 1fr;         /* 2 equal height rows */  height: 70vh;  grid-column-gap: 5px;  grid-row-gap: 5px;  padding: 5px;  grid-template-areas: " first second last "                        " first  third last ";}
.boxa { grid-area: first; background: red; }.boxb { grid-area: second; background: orange; }.boxc { grid-area: third; background: lightgreen; }.boxd { grid-area: last; background: grey; }
@media ( max-width: 700px) { .box-wrapper { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr 1fr; grid-template-areas: " last last " " first second " " first third "; }}
* { margin: 0; padding: 0; }
/* for placing and styling numbers only */.box-wrapper > div { font-size: 1.5em; display: flex; align-items: center; justify-content: center; }
<div class="box-wrapper">  <div class="boxa">1</div>  <div class="boxb">2</div>  <div class="boxc">3</div>  <div class="boxd">4</div></div>

Responsive flexbox and reordering subchildren

You might use multi-column layout for desktop.

And switch to flex (which allows to reorder elements) on mobile using media query.

Run the example below in the Full page mode and try to resize the window:

(I added some text to the blocks to make them more real-world)

* {  box-sizing: border-box;}
body { background-color: #444; color: white; font-family: sans-serif; max-width: 1280px; width: 100%}
.normal { padding: 10px; border: solid 1px #ccc; margin: 20px; columns: 2 200px; column-fill: balance;}
.normal>div { margin: 0 0 10px; padding: 10px; background-color: #333; page-break-inside: avoid;}
@media (max-width:480px) { .normal { display: flex; flex-direction: column } .normal>div:nth-child(1) { order: 1 } .normal>div:nth-child(2) { order: 3 } .normal>div:nth-child(3) { order: 2 } .normal>div:nth-child(4) { order: 4 }}
Desktop<div class="normal">  <div>A<br>Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs.</div>  <div>C<br>The purpose of lorem ipsum is to create a natural looking block of text (sentence, paragraph, page, etc.) that doesn't distract from the layout. A practice not without controversy, laying out pages with meaningless filler text can be very useful    when the focus is meant to be on design, not content.</div>  <div>B<br>It usually begins with:<br>“Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.”</div>  <div>D<br> The passage is attributed to an unknown typesetter in the 15th century who is thought to have scrambled parts of Cicero's De Finibus Bonorum et Malorum for use in a type specimen book.</div></div>

How to change ordering of stacked columns in mobile using css

you can target individual items and change where they appear in the visual order with the order property.

Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Ordering_Flex_Items

DEMO:

.col {
display: flex;
flex-wrap: wrap;
}

.col div {
display: flex;
align-items: center;
justify-content: center;
height: 100px;
width: 200px;
border: 2px solid green;
font-size: 18px;
}


/* Extra small devices (phones, 600px and down) */
@media only screen and (max-width: 600px) {
.col div:nth-child(1) {
order: 1;
}
.col div:nth-child(2) {
order: 2;
}
.col div:nth-child(3) {
order: 4;
}
.col div:nth-child(4) {
order: 3;
}
}
<div class="col">
<div class="text">.text column</div>
<div class="img">.image column</div>
<div class="text">.image column</div>
<div class="img">.text column</div>

</div>

Can we reorder elements when they are present inside different parents?

You can make use of CSS Grid. I played around with a Grid Generator here. Please use full screen mode to view the output.

Note: If anyone can reduce this code, please do since I just dived into CSS Grid.

JSfiddle Demo

.container {  display: grid;  grid-template-columns: 1fr 1fr 1fr 1fr;  grid-template-rows: 1fr 1fr 1fr 1fr;  grid-column-gap: 10px;  grid-row-gap: 10px;  height: 500px;}
.div1 { grid-area: 1 / 1 / 3 / 3; background: #00A2E8;}
.div2 { grid-area: 3 / 1 / 5 / 3; background: #22b14c;}
.div3 { grid-area: 1 / 3 / 5 / 5; background: #ED1C24;}
@media ( max-width: 600px) { .div1 { grid-area: 1 / 1 / 2 / 5; } .div2 { grid-area: 4 / 1 / 5 / 5; } .div3 { grid-area: 2 / 1 / 4 / 5; }}

/* Additional styles */
.container>div { color: #fff; font-size: 2em; display: flex; justify-content: center; align-items: center;}
<div class="container">  <div class="div1">1</div>  <div class="div2">2</div>  <div class="div3">3</div></div>


Related Topics



Leave a reply



Submit