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.
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
withpadding-right: calc(100%/4 - 20px);
. - Now need each time last two elements to align right, so I just set
.item-wrapper
toposition:relative
and than set both last to child withposition:asbolute
and set second last totop:0
and last on tobottom: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>