#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.