Home > Blockchain >  How to make last two flex element flow in reverse direction?
How to make last two flex element flow in reverse direction?

Time:09-16

I've a dynamic list of elements generated by an external library which I do not have any control.

.item-wrapper {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: flex-start;
  position: relative;
}

.item {
  background-color: red;
}

.item:nth-last-child(2),
.item:last-child {
  position: absolute;
  right: 0;
}

.item:last-child {
  top: 57px;
}
<div >
  <div >1
  </div>
  <div >2
  </div>
  <div >3
  </div>
  <div >4
  </div>
  <div >5
  </div>
  <div >6
  </div>
</div>

And I need to generate a layout where the last two elements always need to wrap and align to right side as below.

enter image description here

enter image description here

I tried using flexbox to achieve the desired layout and here's a bit of snippet I've written.

With the above css, the second last element of top row always overlaps to the last element of top row. I've aware that whenever absolute positioning is used, it takes the element out of the flow and absolutely position them.

However, I do not have much knowledge on how to achieve the layout as given above. I'm really flexible with other css approach if it's not possible with flexbox.

CodePudding user response:

  • So, For your output what I did is I wrap all the items in flexbox layout.
  • Main logic for this layout is we need all row 3 child. and same space to last 2 child to align them at right.
  • To get that space I have added .item-wrapper with padding-right: calc(100%/4 - 20px);.
  • Now need each time last two elements to align right, so I just set .item-wrapper to position:relative and than set both last to child with position:asbolute and set second last to top:0 and last on to bottom:0.
  • to fulfil the desired width I just divided height for second last by 4 and removed that height from 100% for last child.

* {
  box-sizing: border-box;
}

.item-wrapper {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  padding-right: calc(100%/4 - 20px);
  position: relative;
}

.item {
  flex: 1 0 calc(100%/3 - 20px);
  padding: 20px;
  background-color: gray;
}

.item:nth-last-child(2),
.item:last-child {
  position: absolute;
  right: 0;
  width: calc(100%/4 - 25px);
  height: calc(50% - 2px);
}

.item:nth-last-child(2) {
  top: 0;
  height: calc(100%/4 - 5px);
}

.item:last-child {
  bottom: 0;
  right: 0;
  height: calc(100% - 100%/4);
}
<div >
  <div >1
  </div>
  <div >2
  </div>
  <div >3
  </div>
  <div >4
  </div>
  <div >5
  </div>
  <div >6
  </div>
  <div >7
  </div>
  <div >8
  </div>
  <div >9
  </div>
  <div >10
  </div>
  <div >11
  </div>
  <div >12
  </div>
</div>

CodePudding user response:

This may look a bit simpler as a grid.

Each item is placed in its desired column, the last two being special and the grid flow set to dense so the second to last element can start back at the top.

.item-wrapper {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-flow: dense;
}

.item:nth-child(3n 1) {
  grid-column: 1;
}

.item:nth-child(3n 2) {
  grid-column: 2;
}

.item:nth-child(3n) {
  grid-column: 3;
}

.item:nth-last-child(2),
.item:last-child {
  grid-column: 4;
}
<div >
  <div >1</div>
  <div >2</div>
  <div >3</div>
  <div >4</div>
  <div >5</div>
  <div >6</div>
  <div >7</div>
  <div >8</div>
</div>

  • Related