Обтекаемость элементов в сетке при изменении высоты одного из них
Всем привет! Есть сетка из элементов в несколько столбцов, у каждого элемента есть спойлер с текстом. Верстка примерно следующая:
<div class="list">
<div class="list__item"></div>
<div class="list__item"></div>
<div class="list__item"></div>
<div class="list__item"></div>
<div class="list__item"></div>
<div class="list__item"></div>
</div>
То есть только один контейнер, в котором все элементы, внутри больше не может быть никаких дополнительных оберток, то есть нельзя сделать 3 обертки для разделения на 3 столбика.

Если раскрыть спойлер, высота элемента с раскрытым спойлером больше, чем у остальных, и он должен сдвинуть элемент, который находится под ним.
Вот так:

Сейчас у меня следующий css для формирования сетки, при таком подходе при раскрытом спойлере отодвигается вниз весь нижний ряд, а не элемент под раскрытым элементом:
.courses-list {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
.courses-list__item {
width: calc(33.33333% - 30px);
margin-left: 15px;
margin-right: 15px;
margin-bottom: 70px;
}
Как сделать, что бы при увеличении высоты одного элемента сдвигался только элемент под ним? По возможности без использования JS
Ответы (2 шт):
Верстка примерно следующая
Если примерно, то значит имеется возможность ее немного видоизменить? Если да, то предлагаю следующий вариант (Flex):
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.list {
display: inline-flex;
flex-flow: column nowrap;
align-items: flex-start;
width: calc(33.33% - 7px);
margin: 2px;
}
.item {
flex: 0 1 auto;
margin: 5px 0;
width: 100%;
min-height: 100px;
border: 2px solid red;
}
/*спойлер*/
.spoiler {width: 90%; margin: 10px auto; border: 2px solid red;}.spoiler>input+label:after {content: "+"; float: right;}.spoiler>input:checked+label:after {content: "-"; float: right;}.spoiler>input {display: none;}.spoiler>input+label, .spoiler>.spoiler_body {display: block;overflow: hidden;padding: 2px 4px;}.spoiler>input+label+.spoiler_body {height: 0; transition: height 1s;}.spoiler>input:checked+label+.spoiler_body {height: 100px;}.spoiler>.spoiler_body {height: 100px;}
<div class="list">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="list">
<div class="item"></div>
<div class="item">
<!-- спойлер-->
<div class="spoiler"><input type="checkbox" id="spoiler"><label for="spoiler">Спойлер</label><div class="spoiler_body">Текст</div></div>
<!-- /спойлер-->
</div>
<div class="item"></div>
</div>
<div class="list">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
upd. Если верстку не меняем. Простое решение - с column-count:, рабочее, правда немного глюканутое, нужно подумать..
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.list {
column-count: 3;
min-height: 150vh;
}
.list__item {
width: calc(100% - 30px);
margin: 0 15px 20px 15px;
min-height: 100px;
border: 2px solid red;
}
/*спойлер*/
.spoiler {width: 90%; margin: 10px auto; border: 2px solid red;}.spoiler>input+label:after {content: "+"; float: right;}.spoiler>input:checked+label:after {content: "-"; float: right;}.spoiler>input {display: none;}.spoiler>input+label, .spoiler>.spoiler_body {display: block;overflow: hidden;padding: 2px 4px;}.spoiler>input+label+.spoiler_body {height: 0; transition: height 1s;}.spoiler>input:checked+label+.spoiler_body {height: 100px;}.spoiler>.spoiler_body {height: 100px;}
<div class="list">
<div class="list__item"></div>
<div class="list__item"></div>
<div class="list__item">
<!-- спойлер-->
<div class="spoiler"><input type="checkbox" id="spoiler"><label for="spoiler">Спойлер</label><div class="spoiler_body">Текст</div></div>
<!-- /спойлер-->
</div>
<div class="list__item"></div>
<div class="list__item"></div>
<div class="list__item"></div>
</div>
Самый простой вариант использовать column, но при условии, что вам не важно расположение, потому что колонки выстраиваются сверху-вниз:
1 4 7
2 5 8
3 6 9
.list {
display: block;
column-count: 3;
column-gap: 10px;
}
.list__item {
display: block;
width: 100%;
min-height: 100%;
border: 2px solid red;
padding: 5px;
padding-top: 4em;
margin-bottom: 10px;
box-sizing: border-box;
}
.list__item .spoiler {
display: block;
width: 100%;
height: 1.5em;
border: 2px solid red;
box-sizing: border-box;
transition: all .3s linear;
}
.list__item .spoiler::before {
content: 'show +';
display: block;
width: 100%;
text-align: center;
}
.list__item .spoiler:focus {
height: 5em;
}
.list__item .spoiler:focus::before {
content: 'hide -';
}
<div class="list">
<div class="list__item">
<!-- псевдоспойлер -->
<div class="spoiler" tabindex="-1"></div>
</div>
<div class="list__item">
<div class="spoiler" tabindex="-1"></div>
</div>
<div class="list__item">
<div class="spoiler" tabindex="-1"></div>
</div>
<div class="list__item">
<div class="spoiler" tabindex="-1"></div>
</div>
<div class="list__item">
<div class="spoiler" tabindex="-1"></div>
</div>
<div class="list__item">
<div class="spoiler" tabindex="-1"></div>
</div>
</div>