Luca Reghellin
Luca Reghellin

Reputation: 8103

How can I reverse the CSS grid columns order?

I want to be able to reverse the order of columns (the two small ones to the left, and the big one to the right). I've tried several solutions, but I didn't find one that works.

Enter image description here

Here's the code:

.images-block-box{

    display: grid;
    grid-gap: 16px;
    grid-template-columns: 708fr 340fr;

    & > div:first-child{
      grid-row: span 2;
    }

    &.reverse{
      grid-template-columns: 340fr 708fr;

      & > div:first-child{
         order: 2; // This doesn't work (I want to place the first item at the end of the 3)
      }
    } // reverse

} // images-block-box

Note that I really want to reverse the order of the columns themselves, not just their dimensions.

Upvotes: 6

Views: 26240

Answers (4)

Luca Reghellin
Luca Reghellin

Reputation: 8103

Here is a sum-up. The working techniques pointed out till now are:

  • grid-auto-flow: dense (container) + grid-column: 2 (first-child)
  • grid-auto-flow: column (container) + grid-column-end: -1 (first-child)

The rest of the code remains the same. Please take a look at the related answers.

Both are currently working well (at least in major/modern browsers).

Upvotes: 3

kukkuz
kukkuz

Reputation: 42352

Another option is to place the big box to the last column by using grid-column-end: -1. See the demo below:

.images-block-box {
  display: grid;
  grid-gap: 16px;
  grid-template-columns: 708fr 340fr;
  grid-template-rows: 100px 100px;
  grid-auto-flow: column;
}

.images-block-box>div {
  border: 1px solid;
}

.images-block-box>div:first-child {
  grid-row: span 2;
}

.images-block-box.reverse {
  grid-template-columns: 340fr 708fr;
}

.images-block-box.reverse>div:first-child {
  grid-column-end: -1;
}
<div class="images-block-box">
  <div></div>
  <div></div>
  <div></div>
</div>
<br/>
<div class="images-block-box reverse">
  <div></div>
  <div></div>
  <div></div>
</div>

grid-column-end

<integer> && <custom-ident>?

Contributes the nth grid line to the grid item’s placement. If a negative integer is given, it instead counts in reverse, starting from the end edge of the explicit grid.

Upvotes: 2

Temani Afif
Temani Afif

Reputation: 272842

Simply adjust grid-column and consider grid-auto-flow:dense; to allow the next elements to be placed before:

.grid {
  display: grid;
  grid-gap: 16px;
  grid-template-columns: 2fr 1fr;
  grid-auto-flow:dense;
  margin:5px;
}

.grid div {
  min-height: 50px;
  border: 1px solid;
}

.grid div:first-child {
  grid-row: span 2;
}

.grid.reverse {
  grid-template-columns: 1fr 2fr;
}

.grid.reverse div:first-child {
  grid-column:2;
}
<div class="grid">
  <div></div>
  <div></div>
  <div></div>
</div>

<div class="grid reverse">
  <div></div>
  <div></div>
  <div></div>
</div>

dense

If specified, the auto-placement algorithm uses a “dense” packing algorithm, which attempts to fill in holes earlier in the grid if smaller items come up later. This may cause items to appear out-of-order, when doing so would fill in holes left by larger items.ref

Upvotes: 9

Gaurav Bhardwaj
Gaurav Bhardwaj

Reputation: 338

Then maybe you can use a different approach:

.grid {
    display: grid;
    grid-template-columns: 5fr 2fr;
    grid-template-rows: 1fr 1fr;
    height: 500px;
    grid-gap: 2rem;
}

.one {
    background-color: red;
    grid-row: 1 / 3;
}

.two {
    background-color: green;
}

.three {
    background-color: blue;
}

.reverse > .one {
    grid-column: 2 / 3;
    grid-row: 2 / 3;
}

.reverse > .three {
    grid-column: 1 / 2;
    grid-row: 1 / 3;
}
<h1>Without Reverse</h1>

<div class="grid">
    <div class="one"></div>
    <div class="two"></div>
    <div class="three"></div>
</div>

<h1>With Reverse</h1>


<div class="grid reverse">
    <div class="one"></div>
    <div class="two"></div>
    <div class="three"></div>
</div>

Upvotes: 0

Related Questions