Растянуть элемент, чтобы заполнить оставшуюся часть его контейнера, одновременно нажимая следующие элементы для переноса? - PullRequest
1 голос
/ 05 июня 2019

Я пытаюсь создать макет, в котором определенный вид элемента будет растягиваться до конца его контейнера и «проталкивать» остальные элементы для переноса. Вот изображение того, как будет выглядеть конечный результат:

enter image description here

Синие прямоугольники и зеленый контейнер имеют определенную ширину, а фиолетовые - нет. HTML будет просто что-то вроде этого:

.green_container{
  padding:10px;
  width:350px;
  border:1px solid green;
  display:flex;
  flex-wrap:wrap;
}

.blue_box{
  min-width:50px;
  height:50px;
  border:1px solid blue;
  margin:5px;
  flex-grow:0;
}

.purple_box{
  min-width:50px;
  height:50px;
  border:1px solid purple;
   margin:5px;
  flex-grow:1;
}
<div class="green_container">
   <div class="blue_box"></div>
   <div class="blue_box"></div>
   <div class="purple_box"></div>
   <div class="blue_box"></div>
   <div class="purple_box"></div>
   <div class="blue_box"></div>
   <div class="blue_box"></div>
   <div class="blue_box"></div>
   <div class="purple_box"></div>
</div>

Использование flex не является обязательным, если элементы способны оборачиваться естественным образом. Возможно ли достичь этого в CSS? Синие прямоугольники являются интерактивными и могут быть изменены и перемещены (обработаны в javascript) пользователями на лету, поэтому я стараюсь избегать пересчета ширины ВСЕХ блоков в контейнере или добавления дополнительных элементов. В идеале фиолетовая коробка естественным образом вытеснит оставшийся контент.

Ответы [ 2 ]

1 голос
/ 05 июня 2019

Хорошо. Я, наверное, обманываю. Близко, как я могу получить ...

Самое сложное правило здесь:

В идеале, фиолетовая коробка естественным образом вытеснит оставшийся контент вниз.

Это означает, что в виртуальном ряду может быть любое количество и ширина синих прямоугольников, и фиолетовое поле для этого виртуального ряда должно компенсировать провисание. Это создает проблему, когда в виртуальной строке остается достаточно места для добавления еще одного синего блока, поскольку следующий синий блок хочет перейти на одну строку вверх с решением на основе flex: 1.

Визуальная хитрость вокруг min-width: 100% для фиолетовых коробок позволяет фиолетовой коробке справиться со слабостью, просто взяв весь ряд. Проблема в том, что он оставляет неявный пробел, когда синие прямоугольники изменяют размеры настолько, чтобы вытеснить другие голубые рамки, разрешенные в этом ряду. Может быть, есть другое правило, ограничивающее max-width синих прямоугольников, поэтому все синие прямоугольники в строке должны оставаться в этом ряду?

Я только что заметил, что ничего не сделал, чтобы учесть другое хитрое требование:

Синие прямоугольники являются интерактивными и могут быть изменены, а перемещены на лету пользователями

Это решение обрабатывает resize, но не draggable ...

.green_container {
  display: flex;
  width: 450px;
  flex-wrap: wrap;
  border: 2px solid green;
  padding: 20px 10px 10px 20px;
}

.blue_box {
  width: 100px;
  height: 50px;
  background-color: blue;
  border-right: 10px solid white;
  border-bottom: 10px solid white;
  resize: horizontal;
  overflow: auto;
  position: relative;
  z-index: 20;
  cursor: move;
  -webkit-user-drag: element;
}

.purple_box {
  height: 50px;
  margin: -60px 0 0 0;
  background-color: purple;
  border-right: 10px solid white;
  min-width: 100%;
  position: relative;
  z-index: 10;
  box-sizing: border-box;
}
<div class="green_container">
  <div class="blue_box" draggable="true"></div>
  <div class="blue_box" draggable="true"></div>
  <div class="purple_box"></div>
  <div class="blue_box" draggable="true"></div>
  <div class="purple_box"></div>
  <div class="blue_box" draggable="true"></div>
  <div class="blue_box" draggable="true"></div>
  <div class="blue_box" draggable="true"></div>
  <div class="purple_box"></div>
</div>
0 голосов
/ 05 июня 2019

Использование CSS-сетки вместо flexbox может быть хорошим выбором.Вы можете использовать, например, grid-column: 3 / -1; для первой фиолетовой рамки и 2 / -1 для второй фиолетовой рамки и так далее.Столбцы сетки CSS (и строки в этом отношении) всегда учитываются в порядке возрастания слева направо (или сверху вниз), начиная с 1, и в порядке убывания справа налево (или снизу вверх), начиная с -1.

Я знаю, судя по caniuse.com - flexbox и caniuse.com - grid , поддержка grid немного хуже, но это может стоить этого компромисса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...