user2986959
user2986959

Reputation: 135

Order cols in two different rows with Flexbox

I need to order cols that is placed in two different rows with Flexbox CSS, but I can only do it for one row. I need to have a mixed order between the two rows.

Right now I have to order and show the cols in row1 and the order and show the cols in row2, but I want to mix them and order them. (The order is OK in desktop view but I need this for mobile view. That's why I need a complete reorder from two rows).

HTML:

<div class="container">
    <div class="row mobile-order">
        <div class="col-md-4 box6">1</div>
        <div class="col-md-4 box5">2</div>
        <div class="col-md-4 box4">3</div>
    </div>
    <div class="row mobile-order">
        <div class="col-md-4 box1">4</div>
        <div class="col-md-4 box2">5</div>
        <div class="col-md-4 box3">6</div>
    </div>
</div>

CSS:

/* CSS used here will be applied after bootstrap.css */
.mobile-order {
    display: flex;
    flex-direction: column;  
}
.test1 {
    order: 1;
}
.test2 {
    order: 2;
    background: #ccc;
}
.box1 {
    order: 1;
}
.box2 {
    order: 3;
}
.box3 {
    order: 5;
}
.box4 {
    order: 6;
}
.box5 {
    order: 4;
}
.box6 {
    order: 2;
}

Bootply test page

This is how I need it for desktop and mobile:

Desktop:

Row1<br><div class="col-md-4 box6">1</div>  |   <div class="col-md-4 box5">2</div>   |   <div class="col-md-4 box4">3</div><br><br>

Row2<br>
<div class="col-md-4 box1">4</div>    |   <div class="col-md-4 box2">5</div>   |   <div class="col-md-4 box3">6</div>

Mobile:

<div class="col-md-4 box1">4</div><br>
<div class="col-md-4 box6">1</div><br>
<div class="col-md-4 box2">5</div><br>
<div class="col-md-4 box5">2</div><br>
<div class="col-md-4 box3">6</div><br>
<div class="col-md-4 box4">3</div>

Upvotes: 2

Views: 1274

Answers (2)

Paulie_D
Paulie_D

Reputation: 115310

If using a single row is an option, basic flexbox with wrapping will take care of this with a media query.

[class*="box"] {
  border: 1px solid grey;
}
.mobile-order {
  display: flex;
  flex-wrap: wrap;
}
@media screen and (max-width: 992px) {
  .mobile-order {
    display: flex;
    flex-direction: column;
  }
  .test1 {
    order: 1;
  }
  .test2 {
    order: 2;
    background: #ccc;
  }
  .box1 {
    order: 1;
  }
  .box2 {
    order: 3;
  }
  .box3 {
    order: 5;
  }
  .box4 {
    order: 6;
  }
  .box5 {
    order: 4;
  }
  .box6 {
    order: 2;
  }
}
<div class="container">
  <div class="row mobile-order">
    <div class="col-md-4 box6">1</div>
    <div class="col-md-4 box5">2</div>
    <div class="col-md-4 box4">3</div>
    <div class="col-md-4 box1">4</div>
    <div class="col-md-4 box2">5</div>
    <div class="col-md-4 box3">6</div>
  </div>
</div>

Codepen.io Demo

Upvotes: 0

Oriol
Oriol

Reputation: 288620

The CSS Display Module Level 3 introduces display: contents:

The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced with its children and pseudo-elements in the document tree.

You can use it to "ignore" the rows and display the inner flex items as if they belonged the same flex container. Then you are able to mix them as you want.

.mobile-order {
  display: flex;
  flex-direction: column;
}
.row {
  display: contents;
}
.test2 > div {
  background: #ccc;
}
.box1 { order: 1; }
.box2 { order: 2; }
.box3 { order: 3; }
.box4 { order: 4; }
.box5 { order: 5; }
.box6 { order: 6; }
<div class="container mobile-order">
  <div class="row test2 mobile-order">
    <div class="col-md-4 box1">1 (row 1)</div>
    <div class="col-md-4 box5">5 (row 1)</div>
    <div class="col-md-4 box2">2 (row 1)</div>
  </div>
  <div class="row test1 mobile-order">
    <div class="col-md-4 box3">3 (row 2)</div>
    <div class="col-md-4 box6">6 (row 2)</div>
    <div class="col-md-4 box4">4 (row 2)</div>
  </div>
</div>

It's not widely supported yet, though.

Upvotes: 1

Related Questions