CSS Flex: first child stretch, other children wrap

469 Views Asked by At

I'm trying to achieve this result, using css only: I have a container with a bunch of children inside. I would like the first child to stretch vertically and having the other children to wrap beside the first child.

expected result

this is the code:

.container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  align-content: center;
  width: 350px;
  border: 1px solid;
}

.container div {
  min-height: 30px;
  width: 100px;
  background: green;
  margin: 3px;
}

.container div:first-child {
  background: red;
  align-self: stretch;
}
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

this is how it looks

But apparently it is not possible with flexbox. Is there any other solutions? I know I can achieve this by taking the first child out of the container and treat it separately. But I was wondering if I could do it without changing the markup?

Thank you all!

1

There are 1 best solutions below

2
Temani Afif On

You need CSS grid for this. Resize the container to see the result:

.container {
  display: grid;
  grid-template-columns: repeat(auto-fit,100px); /* width of your element */
  width: 350px;
  border: 1px solid;
  /* resize the container*/
  overflow: auto;
  resize: horizontal;
}

.container div {
  min-height: 30px;
  background: green;
  margin: 3px;
}

.container div:first-child {
  background: red;
  grid-area:1/1/span 200; /* 1s row/1st column/ take many rows (stretch)*/
}
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

position: absolute can also do the job since the width is fixed:

.container {
  display: flex;
  flex-wrap: wrap;
  padding-left: 106px;
  width: 350px;
  border: 1px solid;
  position: relative;
  /* resize the container*/
  overflow: auto;
  resize: horizontal;
}

.container div {
  min-height: 30px;
  width: 100px;
  background: green;
  margin: 3px;
}

.container div:first-child {
  background: red;
  position: absolute;
  inset: 0 auto 0 0;
}
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>