Как заставить элемент flex привязываться к своему собрату по вертикали (без группировки)?

#html #css #flexbox

#HTML #css #flexbox

Вопрос:

У меня есть три гибких элемента со следующей разметкой:

 <div class='container'>
  <div id="red">red</div>
  <div id="green">green</div>
  <div id="blue">blue</div>
</div>
  

и несколько своеобразный порядок:

 .container { display: flex; flex-wrap: wrap }

#red { background: red; height: 500px }
#green { background: green; height: 200px }
#blue { background: blue; height: 100px }

/* mobile */
@media screen and (max-width: 699px) {
  #red, #green, #blue { width: 100% }
  #red, #blue { order: 1 }
}

/* desktop */
@media screen and (min-width: 700px) {
  #red { width: 33.33333% }
  #green, #blue { width: 66.66666% }
}
  

Вот ссылка на JSBin для предварительного просмотра.

Это отлично работает на мобильных устройствах:

 |‾‾‾‾‾‾‾|
| green |
|_______|
|       |
| red   |
|       |
|       |
|       |
|       |
|_______|
| blue  |
 ‾‾‾‾‾‾‾
  

Но на рабочем столе я получаю следующее:

 |‾‾‾‾‾|‾‾‾‾‾‾‾‾‾‾‾|
| red | green     |
|     |___________|
|     |
|     |
|     |
|_____|_____
| blue      |
 ‾‾‾‾‾‾‾‾‾‾‾
  

В то время как то, что я пытаюсь получить, это:

 |‾‾‾‾‾|‾‾‾‾‾‾‾‾‾‾‾|
| red | green     |
|     |___________|
|     | blue      |
|     |‾‾‾‾‾‾‾‾‾‾‾
|     |
|_____|
  

Другими словами, я ищу способ переместить blue элемент к его green родственному элементу. Проблема в том, что green занимает всю высоту red . Я попытался уменьшить green высоту с помощью display: inline и inline-block , а также height , а также align-items и align-content на родительском элементе, ни один из которых не сработал.

Возможно ли это с помощью flexbox, не прибегая к CSS grid?

Примечание: к сожалению, я не могу группировать green и blue , потому что у меня должно быть red промежуточное соединение на мобильном устройстве.

Ответ №1:

Мне неприятно даже предлагать это (потому что поплавки — это зло), но вы могли бы сделать это через float: left . Поток содержимого вокруг элемента — это, по сути, то, для чего предназначен float.

(Я удалил медиа-запрос здесь, чтобы упростить его просмотр в крошечном фрагменте SO.)

 #red { background: red; height: 500px }
#green { background: green; height: 200px }
#blue { background: blue; height: 100px }

/* desktop */
.container: { display: block; }
.container > * { float: left; }
#red { width: 33.33333% }
#green, #blue { width: 66.66666% }  
 <div class='container'>
  <div id="red">red</div>
  <div id="green">green</div>
  <div id="blue">blue</div>
</div>  

Если вы не хотите начать позиционировать вещи:

 #red { background: red; height: 500px }
#green { background: green; height: 200px }
#blue { background: blue; height: 100px }

/* desktop */
.container: { position: relative; padding-left: 33.3333%; }
#red { width: 33.33333%; position: absolute; }  
 <div class='container'>
  <div id="red">red</div>
  <div id="green">green</div>
  <div id="blue">blue</div>
</div>  

Комментарии:

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

2. Flex этого не сделает, и вы явно сказали, что вам не нужна сетка, поэтому… Я думаю, что float — единственный оставшийся вариант, если вы не хотите начать позиционировать вещи. (Вы могли бы расположить #red абсолютно, а затем использовать левое заполнение контейнера, чтобы переместить #green и #blue вправо, но это … неоптимально.)

3. Добавлен еще один фрагмент, используя идею расположения / заполнения в комментарии выше.

4. Я проголосовал за это, затем удалил свой голос, потому что я не согласен с тем, что поплавки — это зло. Они очень полезны.