How to positioning every child in flex/grid/whatever simultaneously with nth-child?

Viewed 127

I have this code:

.parent {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: flex-start;
  align-content: flex-start;
  width: 200px;
  height: 200px;
}

.child,
.child:not(:nth-child(1)) {
  width: 100px;
  height: 100px;
}

.child:last-child:nth-child(1) {
  width: 200px;
  height: 200px;
}

.child:nth-child(1),
.child:last-child:nth-child(2) {
  width: 100px;
  height: 200px;
}

.child:nth-last-child(4) {
  width: 100px;
  height: 100px;
}
Test with 1 children
<div class="parent" style="background-color:yellow;">
  <div class="child" style="background-color:red;">1</div>
</div>
Test with 2 children
<div class="parent" style="background-color:yellow;">
  <div class="child" style="background-color:red;">1</div>
  <div class="child" style="background-color:blue;">2</div>
</div>
Test with 3 children
<div class="parent" style="background-color:yellow;">
  <div class="child" style="background-color:red;">1</div>
  <div class="child" style="background-color:blue;">2</div>
  <div class="child" style="background-color:green;">3</div>
</div>
Test with 4 children
<div class="parent" style="background-color:yellow;">
  <div class="child" style="background-color:red;">1</div>
  <div class="child" style="background-color:blue;">2</div>
  <div class="child" style="background-color:green;">3</div>
  <div class="child" style="background-color:orange;">4</div>
</div>

But I wish the last example had a different order, that is:

1 2
3 4

The important thing is that I cannot add different classes for each of the flex children. The Twitter gallery behaves similarly, but it's more complicated there (it's flex in flex and probably some JS, although it probably works differently). I need all the above-mentioned cases to work simultaneously.

2 Answers

In that case, you need to structure your flex grid like this:

.parent {
  display: flex;
  flex-wrap: wrap;
  width: 200px;
  height: 200px;
}

.child {
  width: 100px;
  height: 100px;
}
Test with 4 children
<div class="parent" style="background-color:yellow;">
  <div class="child" style="background-color:red;">1</div>
  <div class="child" style="background-color:blue;">2</div>
  <div class="child" style="background-color:green;">3</div>
  <div class="child" style="background-color:orange;">4</div>
</div>

Note that instead of using flex-direction: column we use flex-wrap: wrap to push the elements to the next row.

You can achieve this by using grid instead of flex. Take a look at this:

.parent {
  display: grid;
  grid-template-columns: 100px 100px;
  grid-template-rows: 100px 100px;
  width: 200px;
  height: 200px;
}

/* in case there is only one child */
.child:first-child:nth-last-child(1){
  grid-column: 1 / span 2;
  grid-row: 1 / span 2;
}

/* in case there are 2 children */
.child:first-child:nth-last-child(2),
.child:first-child:nth-last-child(2) ~ .child{
  grid-row: 1 / span 2;
}

/* in case there are 3 children, make the first one span 2 rows */
.child:first-child:nth-last-child(3) {
  grid-row: 1 / span 2;
}
Test with 1 children
<div class="parent" style="background-color:yellow;">
  <div class="child" style="background-color:red;">1</div>
</div>
Test with 2 children
<div class="parent" style="background-color:yellow;">
  <div class="child" style="background-color:red;">1</div>
  <div class="child" style="background-color:blue;">2</div>
</div>
Test with 3 children
<div class="parent" style="background-color:yellow;">
  <div class="child" style="background-color:red;">1</div>
  <div class="child" style="background-color:blue;">2</div>
  <div class="child" style="background-color:green;">3</div>
</div>
Test with 4 children
<div class="parent" style="background-color:yellow;">
  <div class="child" style="background-color:red;">1</div>
  <div class="child" style="background-color:blue;">2</div>
  <div class="child" style="background-color:green;">3</div>
  <div class="child" style="background-color:orange;">4</div>
</div>

Related