Simon Jensen
Simon Jensen

Reputation: 309

CSS Change the order of content between columns

Question goes beyond CSS and have therefore been closed.


I have several areas with content which I want in another order according to the viewport used.

On large screens, I want two columns and on small screens, I want one column - with the content in another order and vice versa.

I have tried to show in below image the layout. Written in a text is the layout on large viewports and the order of the boxes.

I would really like to keep the flex-columns if possible. I have tried with the setting the order-property without success.

I have updated below code so it clearly shows what I am trying to do. Resizing below should be selfexplaining but I need things in two columns on larger viewports and things in another order on smaller viewports.

See JSFiddle here

@media only screen and (min-width: 601px) {
  p {
    margin: 0;
  }
  .container {
    width: 100%;
    min-height: 100%;
    background: yellow;
    align-content: flex-start;
    display: flex;
    display: -webkit-flex;
    flex-flow: row wrap;
    -webkit-flex-flow: row wrap;
  }
  .flexcolumntop {
    flex: 50%;
    max-width: 50%;
    margin: 0;
  }
  .flexcolumnbottom {
    flex: 50%;
    max-width: 50%;
    margin: 0;
  }
  .red {
    background: red;
    width: 150px;
    height: 150px;
    text-align: center;
  }
  .blue {
    background: blue;
    width: 150px;
    height: 150px;
    text-align: center;
  }
  .green {
    background: green;
    width: 150px;
    height: 150px;
    text-align: center;
  }
  .lime {
    background: lime;
    width: 150px;
    height: 150px;
    text-align: center;
  }
  .pink {
    background: pink;
    width: 150px;
    height: 150px;
    text-align: center;
  }
  .gray {
    background: gray;
    width: 150px;
    height: 150px;
    text-align: center;
  }
}

@media only screen and (max-width: 600px) {
  p {
    margin: 0;
  }
  .container {
    width: 100%;
    min-height: 100%;
    background: yellow;
    align-content: flex-start;
    display: flex;
    display: -webkit-flex;
    flex-flow: row wrap;
    -webkit-flex-flow: row wrap;
  }
  .flexcolumntop {
    flex: 100%;
    max-width: 100%;
    margin: 0 auto;
  }
  .flexcolumnbottom {
    flex: 100%;
    max-width: 100%;
    margin: 0 auto;
  }
  .red p::before {
    content: "Order: 2";
  }
  .red {
    background: red;
    width: 150px;
    height: 150px;
    text-align: center;
  }
  .blue p::before {
    content: "Order 5: ";
  }
  .blue {
    background: blue;
    width: 150px;
    height: 150px;
    text-align: center;
  }
  .green p::before {
    content: "Order: 1";
  }
  .green {
    background: green;
    width: 150px;
    height: 150px;
    text-align: center;
  }
  .lime p::before {
    content: "Order: 4";
  }
  .lime {
    background: lime;
    width: 150px;
    height: 150px;
    text-align: center;
  }
  .pink p::before {
    content: "Order: 6";
  }
  .pink {
    background: pink;
    width: 150px;
    height: 150px;
    text-align: center;
  }
  .gray p::before {
    content: "Order: 3";
  }
  .gray {
    background: gray;
    width: 150px;
    height: 150px;
    text-align: center;
  }
}
<div class="container">
  <div class="flexcolumntop">
    <div class="red">
      <p>
        Red
      </p>
    </div>
    <div class="blue">
      <p>
        Blue
      </p>
    </div>
    <div class="pink">
      <p>
        Pink
      </p>
    </div>
  </div>
  <div class="flexcolumnbottom">
    <div class="green">
      <p>
        Green
      </p>
    </div>
    <div class="gray">
      <p>
        Gray
      </p>
    </div>
    <div class="lime">
      <p>
        Lime
      </p>
    </div>
  </div>
</div>

Upvotes: 0

Views: 130

Answers (2)

vicbyte
vicbyte

Reputation: 3790

This is easily solvable using flexbox and order, althrough you would have to get rid of grouping with flex-columns like you currently have (you can reorder only the columns inside the same parent, so it wouldn't be possible to do for ex. green -> red -> gray if they wouldn't have the same parent).

Cleaned up the css a bit and added .morder classes that just setup the order for mobile version. Also did minor html changes (each of the color elems now have a .flexcol parent and the items are ordered differently - but that could be avoided using order property on desktop as well if needed) :)

p {
  margin: 0;
}
.container {
  width: 100%;
  min-height: 100%;
  background: yellow;
  align-content: flex-start;
  display: flex;
  display: -webkit-flex;
  flex-flow: row wrap;
  -webkit-flex-flow: row wrap;
}
.flexcol {
  flex: 50%;
  margin: 0;
}
.red, .blue, .green, .lime, .pink, .gray {
  width: 150px;
  height: 150px;
  text-align: center;
}
.red {
  background: red;
}
.blue {
  background: blue;
}
.green {
  background: green;
}
.lime {
  background: lime;
}
.pink {
  background: pink;
}
.gray {
  background: gray;
}
  
@media only screen and (max-width: 600px) {
  .flexcol {
    flex: 100%;
  }
  .morder-1 {
    order: 1;
  }
  .morder-2 {
    order: 2;
  }
  .morder-3 {
    order: 3;
  }
  .morder-4 {
    order: 4;
  }
  .morder-5 {
    order: 5;
  }
  .morder-6{
    order: 6;
  }
}
<div class="container">
  <div class="flexcol morder-2">
    <div class="red">
      <p>
        Red
      </p>
    </div>
  </div>
  <div class="flexcol morder-1">
    <div class="green">
      <p>
        Green
      </p>
    </div>
  </div>
  <div class="flexcol morder-5">
    <div class="blue">
      <p>
        Blue
      </p>
    </div>
  </div>
  <div class="flexcol morder-3">
    <div class="gray">
      <p>
        Gray
      </p>
    </div>
  </div>
  <div class="flexcol morder-6">
    <div class="pink">
      <p>
        Pink
      </p>
    </div>
  </div>
  <div class="flexcol morder-4">
    <div class="lime">
      <p>
        Lime
      </p>
    </div>
  </div>
</div>

Upvotes: 2

Yves Kipondo
Yves Kipondo

Reputation: 5633

With Grid layout you can define the template which define the way you sub element will be layout, when you specifie the grid-template-areas you define the way you sub elements will be position under the grid layout. And when It come to modifie the order of elements on certain viewport you will have just to change the grid-template-areas and on each subelement define the grid-area to specify where this element will be

.container {
    width: 100%;
    min-height: 100%;
    background: yellow;
    align-content: flex-start;
    display: grid;
    grid-template-areas: "topblue topred"
                         "bottomgray bottomgreen";
}

.red {
    grid-area: topred;
    background: red;
    text-align: center;
}

.blue {
    grid-area: topblue;
    background: blue;
    text-align: center;
}

.green {
    grid-area: bottomgreen;
    background: green;
    text-align: center;
}

.gray {
    grid-area: bottomgray;
    background: gray;
    text-align: center;
}

@media all and (max-width: 600px) {
    .container {
        grid-template-areas: "topred"
                         "topblue"
                         "bottomgreen"
                         "bottomgray";
    }
}
<div class="container">
    <div class="red">
      Red <br /><br /> Column 2, Top
    </div>
    <div class="blue">
      Blue <br /><br /> Column 1, Top
    </div>
    <div class="green">
      Green <br /><br /> Column 2, Bottom
    </div>
    <div class="gray">
      Gray <br /><br /> Column 1, Bottom
    </div>
</div>

Also, be aware of browser support of css grid

Upvotes: 0

Related Questions