Большой первый элемент с макетом flexbox?

У меня есть макет, состоящий из одного упорядоченного списка, содержащего кучу элементов.

Все элементы имеют одинаковую ширину и высоту, кроме первого элемента, который в 3 раза шире и в 2 раза выше. Это выглядит так:

введите здесь описание изображения

ol {
  padding:0;
  margin:0;
  min-width: 488px;
}
li {
  list-style: none;
  width: 150px;
  padding-bottom: 16.66%;
  border: 5px solid tomato;
  display: inline-block;
}
li:first-child {
  float:left;
  width: 478px;
  border-color: green;
  padding-bottom: 34.25%;
  margin: 0 4px 4px 0;
}
<ol>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ol>

Демонстрация Codepen (измените размер области просмотра, чтобы увидеть эффект)

В настоящее время я использую float и встроенные блоки для создания макета, но я хотел бы использовать flexbox из-за некоторых дополнительных функций, которые предлагает flexbox.

Я сделал пару попыток, но безуспешно -

Попытка 1 – Codepen

ol {
  /* ... */
  display: flex;
  flex-wrap: wrap;
}

Попытка №2 — Codepen

Используйте float перед списком, чтобы выделить место для первого большого элемента списка.

Затем установите абсолютное отображение для первого элемента списка.

В обеих попытках красные прямоугольники в первой строке растягиваются, чтобы заполнить высоту первого элемента.

Это возможно?

(Если нет, то меня бы заинтересовал обходной путь CSS-сетки)


person Danield    schedule 13.07.2016    source источник
comment
Эта страница может быть полезной, если вы изучаете flexbox — css- ricks.com/snippets/css/a-guide-to-flexbox   -  person Andrew    schedule 13.07.2016
comment
Просто чтобы было ясно, я хочу, чтобы первые элементы красного списка переносились на 2 строки, пока они не достигнут высоты первого элемента, а затем продолжают оборачиваться под большим элементом.   -  person Danield    schedule 13.07.2016
comment
@ Эндрю, это лучшая документация / учебник для этого.   -  person vaso123    schedule 13.07.2016
comment
Я не думаю, что это возможно с одним контейнером flexbox. Вот почему мы получим нативную сетку CSS!   -  person fl0cke    schedule 13.07.2016
comment
Нет, это невозможно с одним контейнером. с помощью флексбокса.   -  person Paulie_D    schedule 13.07.2016
comment
Я смотрел на это и создал эту скрипку для вас. Я вижу, как занять ширину строки, например, 3 flex-элемента, но чтобы занять 2 или 3 элемента столбца, я не думаю, что это существует только сейчас: jsfiddle.net/6vq1rvbt может быть лучше добавить это в ваш вопрос   -  person Andrew    schedule 13.07.2016
comment
Вот объяснение, почему это не может работать с flexbox, и возможные альтернативы: stackoverflow.com/a/34481128/3597276   -  person Michael Benjamin    schedule 13.07.2016
comment
Есть несколько похожий вопрос с ответом, в котором рассказывается, как его взломать, но, похоже, он работает только для фиксированных макетов: stackoverflow.com/ а/32173248/4326495   -  person Frank Tan    schedule 13.07.2016
comment
@Michael_B - спасибо за объяснение. Таким образом, кажется, что макеты на основе плавающих элементов еще не умерли.   -  person Danield    schedule 13.07.2016


Ответы (1)


Итак, совершенно ясно, что flexbox не может создать такой макет. Итак, я отвечу на эту часть вопроса:

Если нет, то меня бы заинтересовал обходной путь CSS-сетки.

С помощью модуля CSS Grid Layout сделать это на удивление легко:

В основном соответствующий код сводится к следующему:

Демонстрация Codepen (измените размер, чтобы увидеть эффект)

ul {
  display: grid; /* (1) */
  grid-template-columns: 120px 120px repeat(auto-fill, 120px); /* (2) */
  grid-template-rows: repeat(auto-fill, 150px); /* (3) */
  grid-gap: 1rem; /* (4) */
  justify-content: space-between; /* (5) */
}
li:first-child {
  grid-column: 1 / 4; /* (6) */
  grid-row:  1 / 3; /* (7) */
}

1) Сделайте элемент контейнера контейнером сетки

2) Установите сетку как минимум с 3 столбцами шириной 120 пикселей. (Значение auto-fill используется для адаптивных макетов).

3) Установите сетку со строками высотой 150 пикселей.

4) Установите промежутки/желоба для строк и столбцов сетки - здесь, так как вам нужна компоновка "промежуток" - зазор фактически будет минимальным зазором, потому что он будет увеличиваться по мере необходимости.

5) Аналогично флексбоксу.

6) занимают первые три столбца

7) занимаем первые два ряда

body {
  margin: 0;
}
ul {
  display: grid;
  grid-template-columns: 120px 120px repeat(auto-fill, 120px);
  grid-template-rows: repeat(auto-fill, 150px);
  grid-gap: 1rem;
  justify-content: space-between;
  
  /* boring properties: */
  list-style: none;
  width: 90vw;
  height: 90vh;
  margin: 4vh auto;
  border: 5px solid green;
  padding: 0;
  overflow: auto;
}
li {
  background: tomato;
  min-height: 150px;
}
li:first-child {
  grid-column: 1 / 4;
  grid-row:  1 / 3; 
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
  <li>10</li>
  <li>11</li>
  <li>12</li>
  <li>13</li>
  <li>14</li>
  <li>15</li>
  <li>16</li>
  <li>17</li>
  <li>18</li>
  <li>19</li>
  <li>20</li>
</ul>


Поддержка браузера — Caniuse

В настоящее время поддерживается Chrome (Blink) и Firefox с частичной поддержкой IE и Edge (см. это сообщение Рэйчел Эндрю)

person Danield    schedule 23.03.2017
comment
Отличное объяснение. И классный способ установить минимальное количество столбцов в адаптивном макете. - person Michael Benjamin; 17.04.2017