Гибкое позиционирование боковой панели в определенном порядке

#html #css #flexbox

#HTML #css #flexbox

Вопрос:

У меня простой макет из 2 столбцов с 3 разделами. В зависимости от медиа-запроса я хочу изменить их порядок — для этого я использую flex order .

Это работает нормально, за исключением того, что я получаю свой узкий раздел боковой панели, начинающийся в конце первого раздела или аналогичный этому. Есть ли способ заставить их позиционировать больше как кусочки головоломки?

Пример скрипки проблемы:https://jsfiddle.net/an7m3yvs /

HTML:

 <div class="page-wrapper">
  <div class="container">
    <div class="box1">
      BOX 1
    </div>

    <div class="box2">
      BOX 2
    </div>

    <div class="box3">
      BOX 3 Sidebar
    </div>
  </div>
</div>
  

CSS:

 .page-wrapper{
  width:100%;
  max-width:500px;
  margin:0 auto;
 
}
.container{
 display:flex;
 flex-wrap:wrap;
}
.box1{
  display:inline-block;
  background:red;
  width:70%;
  height:400px;
  order:1;
}
.box2{
  display:inline-block;
  background:green;
  width:70%;
  height:150px;
  order:2;
}
.box3{
  display:inline-block;
  background:grey;
  width:30%;
  height:600px;
  order:3;
}
  

Как я этого хочу:

Как я этого хочу

(Я знаю, что это можно сделать проще, но идея в том, чтобы я мог изменить порядок с помощью медиа-запроса, так как в мобильном устройстве я хочу один столбец, а они в другом порядке.)

ПОПЫТКА СОЗДАНИЯ СЕТКИ:https://jsfiddle.net/w489b2fj /

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

1. Для меня это звучит как работа для CSS Grid.

2. @davidgiesemann не могли бы вы привести пример этого в grid, где в мобильном приложении он поместил бы box3 между блоками 1 и 2?

3. конечно, взгляните на мой ответ ниже.

Ответ №1:

3-й элемент позиционируется не в соответствии с первым элементом, а в соответствии с его предшественником. Боковая панель будет занимать оставшееся пространство после 2-го элемента, а не 1-го.

Для достижения желаемого результата, я думаю, лучше управлять 2 контейнерами flexbox. Первый включает box1 и box2. Второй включает в себя контейнер box и боковую панель.

Редактировать HTML:

 <div class="page-wrapper">
  <div class="container">
    <div class="content-wrapper">
        <div class="box1">
          BOX 1
        </div>
        <div class="box2">
          BOX 2
        </div>
    </div>
    <div class="box3">
      BOX 3 Sidebar
    </div>
  </div>
</div>
  

И отредактируйте CSS:

 .container, .content-wrapper{
 display:flex;
 flex-wrap:wrap;
}

.content-wrapper {
    width: 70%;
}

.box1, .box2 {
    width: 100%;
}
  

Редактировать:

Хорошо, с этой новой информацией у меня есть другое решение:

 .container {
  position: relative;
}

.box3 {
  position: absolute;
  top: 0;
  right: 0;
}
  

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

1. Спасибо, но проблема в том, что я бы хотел, чтобы боковая панель 3 была посередине в мобильном макете. Так что это не сработает, поскольку я могу расположить его только над или под полем 1 2.

2. В конце я изменил свой ответ новым решением. Для изменения требуется только CSS.

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

4. решение @davidgiesemann, возможно, тогда лучше. Я не могу комментировать его сообщение. Если я правильно понял проблему, для ее решения вам нужно заменить 2-е значение grid-template-rows. Смотрите: jsfiddle.net/tnph5sjL

5. Я все еще новичок в CSS grid, поэтому я не уверен, что понимаю, почему auto не позволяет контейнеру переносить поля… свойство grid-template-rows определяет размер строк. Здесь у нас есть две строки, поэтому два значения. minmax определяет интервал размеров между min и max. Единица fr представляет собой часть пространства, доступного в сеточном контейнере, поэтому 1fr представляет все оставшееся пространство. 1-я строка: минимальный размер равен 0, а максимальный размер (автоматический) зависит от содержимого. 2-я строка: минимальный размер равен 0, а его максимальный размер должен соответствовать размеру пространства, доступного в контейнере (следовательно, 1fr).

Ответ №2:

Вы можете добиться этого, добавив flex-direction: column; в контейнер. Но в этом случае (для переноса элементов) вам также необходимо установить фиксированное height , в вашем случае height: 550px; .

И на самом деле, вам не нужны order настройки для элементов flex в этом простом случае…

 .page-wrapper {
  width: 100%;
  max-width: 500px;
  margin: 0 auto;
}

.container {
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  height: 550px;
}

.box1 {
  display: inline-block;
  background: red;
  width: 70%;
  height: 400px;
  order: 1;
}

.box2 {
  display: inline-block;
  background: green;
  width: 70%;
  height: 150px;
  order: 2;
}

.box3 {
  display: inline-block;
  background: grey;
  width: 30%;
  height: 600px;
  order: 3;
}  
 <div class="page-wrapper">
  <div class="container">
    <div class="box1">
      BOX 1
    </div>

    <div class="box2">
      BOX 2
    </div>

    <div class="box3">
      BOX 3 Sidebar
    </div>
  </div>
</div>  

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

1. Это здорово, спасибо, но я не знаю окончательной высоты страницы, поэтому не смог бы ее реализовать. Как я упоминал в других комментариях, мне нужно, чтобы поле 3 находилось между 1 и 2 в мобильном режиме, поэтому группировка их, как и других ответов, также не сработала бы.

Ответ №3:

Вы хотели получить ответ с использованием CSS Grid, где box3 помещает между box1 и box2 в мобильных видовых экранах. Вот и все:

 .container{
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr 1fr 1fr;
  grid-template-areas: 
  "box1"
  "box3"
  "box2"
}

@media (min-width:768px){
  .container{
    display:grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    grid-template-areas:
    "box1 box3"
    "box2 box3"
  }
}

.box1{
  grid-area: box1;
  background-color: #f00;
}

.box2{
  grid-area: box2;
  background-color: #0f0;
}

.box3{
  grid-area: box3;
  background-color: #00f;
}  
 <div class="page-wrapper">
  <div class="container">
    <div class="box1">
      BOX 1
    </div>

    <div class="box2">
      BOX 2
    </div>

    <div class="box3">
      BOX 3 Sidebar
    </div>
  </div>
</div>  

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

1. Спасибо, Дэвид, я чувствую, что почти достиг цели, используя вместо этого сеточное решение. Однако у меня проблема, из-за которой поля на рабочем столе не поднимаются. Я отредактировал свой пост с помощью скрипки «ПОПЫТКА СЕТКИ», чтобы вы могли ее увидеть. Мне нужно, чтобы ОКНО 1 начиналось под окном 2 без промежутка между ними, у меня это отлично работает на мобильных устройствах с несколькими настройками.

2. jsfiddle.net/qdtzr69k взгляните на это.

3. Хорошо, итак, мы почти на месте, спасибо за вашу помощь с этим (сетки не моя сильная сторона, поэтому начинаю с flex). Это решает эту проблему, но контейнер не переносит поля: jsfiddle.net/xaeLj096 Я могу сделать это, только удалив grid-template-rows:minmax … но это возвращает его к предыдущему.

4. @nicksource Я не уверен, что понял, но как насчет этого: jsfiddle.net/58zmgtpj

Ответ №4:

Попробуйте использовать свойство position и поместите поля относительно оболочки страницы.

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

1. вы пробовали это?

Ответ №5:

если вы можете изменить HTML (и всегда создавать хорошую структуру), попробуйте это:
выполните гибкое позиционирование для элементов c1 и c2, и вы просто удалите все инструкции встроенного блока

 <div class="page-wrapper">
  <div class="container">
  <div class=c1>
    <div class="box1">
      BOX 1
    </div>

    <div class="box2">
      BOX 2
    </div>
  </div>
  <div class=c2>
    <div class="box3">
      BOX 3 Sidebar
    </div>
</div>
</div>
  

И css:

 .page-wrapper{
  width:100%;
  max-width:500px;
  margin:0 auto;
 
}
.container{
 display:flex;
}
.box1{
  background:red;
  height:200px;
  order:2;
}
.box2{
  background:green;
  height:150px;
  order:1;
}
.box3{

  background:grey;
  width:100%;
  height:400px;
}
.c2{
  
  width:30%;
  flex-basis:1;
}
.c1{
  display:flex;
  flex-direction:column;
  width:70%;
  flex-basis:1;
}
  

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

1. Спасибо, но проблема в том, что я бы хотел, чтобы боковая панель 3 была посередине в мобильном макете. Так что это не сработает, поскольку я могу расположить его только над или под полем 1 2.