Перенос блоков разной высоты на CSS

кто знает, как сделать, чтобы блоки 5,6,7 (из примера №1) переносились выше, к блокам 1,2,3, как в примере №2. Но чтобы без использования двойных колонок-контейнеров. Как это реализовать на флексах и, отдельно, можно ли такое сделать на флоатах?

* {
  box-sizing: border-box;
  --gap: 1rem;
  --columns: 10;
}

.wrapper1,
.wrapper2 {
  margin: 0 auto;
  max-width: 1280px;
}
.wrapper1 {
  background-color: cyan;
}
.wrapper2 {
  background-color: lime;
}
.row {
  display: flex;
  flex-wrap: wrap;
  align-items: start;
  gap: var(--gap);
}
.item {
  border: 1px solid black;
  height: 100px;
}
.wrapper1 .item {
  flex: 0 1
    calc(
      (100% / var(--columns)) * 2 - var(--gap) + (var(--gap) / var(--columns))
    );
}
.wrapper2 .item {
  flex: 1 1 calc((100% / 3) - 20px);
}
.col-container60 {
  flex: 1 1
    calc(
      (100% / var(--columns)) * 6 - var(--gap) + (var(--gap) / var(--columns))
    );
}
.col-container40 {
  flex: 1 1
    calc(
      (100% / var(--columns)) * 4 - var(--gap) + (var(--gap) / var(--columns))
    );
}
.big {
  height: 200px;
}
.wrapper1 .big {
  flex: 0 1
    calc(
      (100% / var(--columns)) * 4 - var(--gap) + (var(--gap) / var(--columns))
    );
}
.wrapper2 .big {
  flex-basis: 100%;
}
p {
  line-height: 100px;
  margin: 0;
  padding: 0;
  text-align: center;
  font-size: 60px;
}
<div class="wrapper1">
  <h1>Пример №1</h1>
  <div class="row">
    <div class="item">
      <p>1</p>
    </div>
    <div class="item">
      <p>2</p>
    </div>
    <div class="item">
      <p>3</p>
    </div>
    <div class="item big">
      <p>4.1</p>
      <p>4.2</p>
    </div>
    <div class="item">
      <p>5</p>
    </div>
    <div class="item">
      <p>6</p>
    </div>
    <div class="item">
      <p>7</p>
    </div>
  </div>
</div>
<br>
<div class="wrapper2">
  <h1>Пример №2</h1>
  <div class="row">
    <div class="col-container60">
      <div class="row">
        <div class="item">
          <p>1</p>
        </div>
        <div class="item">
          <p>2</p>
        </div>
        <div class="item">
          <p>3</p>
        </div>
      </div>
      <div class="row">
        <div class="item">
          <p>5</p>
        </div>
        <div class="item">
          <p>6</p>
        </div>
        <div class="item">
          <p>7</p>
        </div>
      </div>
    </div>
    <div class="col-container40">
      <div class="row">
        <div class="item big">
          <p>4.1</p>
          <p>4.2</p>
        </div>
      </div>
    </div>
  </div>
</div>


Ответы (1 шт):

Автор решения: Alexey Vladimirov

Flexbox не очень подходит для этой задачи. Если предполагается, что блок 4.1/4.2 имеет заранее понятную высоту, то здесь хорошо помог бы grid-лейаут — он позволяет заполнять такие «дырки» ближайшими подходящими по размеру блоками при помощи свойства grid-auto-flow.

* {
  box-sizing: border-box;
  --gap: 1rem;
  --columns: 5;
}

.row {
  display: grid;
  grid-template-columns: repeat(var(--columns), 1fr);
  grid-auto-flow: row dense;
  justify-content: center;
  align-items: stretch;
  padding: 20px;
  box-sizing: border-box;
  gap: var(--gap);
}

.item {
  border: 1px solid black;
}

.big {
  grid-column-start: span 2;
  grid-row-start: span 2;
}

p {
  line-height: 100px;
  margin: 0;
  padding: 0;
  text-align: center;
  font-size: 60px;
}
<div class="wrapper1">
  <h1>Пример №3</h1>
  <div class="row">
    <div class="item">
      <p>1</p>
    </div>
    <div class="item">
      <p>2</p>
    </div>
    <div class="item">
      <p>3</p>
    </div>
    <div class="item big">
      <p>4.1</p>
      <p>4.2</p>
    </div>
    <div class="item">
      <p>5</p>
    </div>
    <div class="item">
      <p>6</p>
    </div>
    <div class="item">
      <p>7</p>
    </div>
  </div>
</div>

Хуже, если 4.1/4.2 — это какой-нибудь текст непредсказуемой высоты, который нужно вписать в сетку карточек. Тогда может помочь старый топорный способ — display:inline-block для всех элементов и float:right — дополнительно для большого блока. Тогда маленькие карточки будут «обтекать» его слева. Но этот подход может оказаться немного хуже в производительности, если карточек очень много.

* {
  box-sizing: border-box;
}

.row {
  font-size: 0;
}

.item {
  border: 1px solid black;
  height: 100px;
  width: 20%;
  display: inline-block;
}

.big {
  height: 200px;
  float: right;
  display: inline-block;
  width: 40%;
}

p {
  line-height: 100px;
  margin: 0;
  padding: 0;
  text-align: center;
  font-size: 60px;
}
<div class="wrapper1">
  <h1>Пример №4</h1>
  <div class="row">
    <div class="item">
      <p>1</p>
    </div>
    <div class="item">
      <p>2</p>
    </div>
    <div class="item">
      <p>3</p>
    </div>
    <div class="item big">
      <p>4.1</p>
      <p>4.2</p>
    </div>
    <div class="item">
      <p>5</p>
    </div>
    <div class="item">
      <p>6</p>
    </div>
    <div class="item">
      <p>7</p>
    </div>
  </div>
</div>

→ Ссылка