Схлопнуть внутреннюю колонку грида если нет элемента
В следующем примере нижние элементы mid-left
и mid-right
должны поровну делить между собой пространство, оставшееся от других областей. Но если присутствует только один из них, то он должен занимать всё это пространство. Заранее неизвестно, будет ли присутствовать элемент, занимающий данную область, или нет. Поддержка gap
НЕ требуется.
У меня получилось сделать такое только с помощью селектора :has
. Как сделать то же самое, но без него?
Разметку менять нельзя. А то бы я mid-left
и mid-right
обернул в контейнер и всё бы получилось.
section {
display: grid;
grid-template: "l t t t" 2em
"l mt mt r" 1fr
"l ml mr r" 1fr / 5em 1fr 1fr 5em;
min-height: 8em;
}
section + section {
margin-top: 2em;
}
div {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.left { grid-area: l; background: antiquewhite; }
.top { grid-area: t; background: silver; }
.right { grid-area: r; background: antiquewhite; }
.mid-top { grid-area: mt; background: yellow; }
.mid-left { grid-area: ml; background: aquamarine; }
.mid-right { grid-area: mr; background: lightsalmon; }
section:not(:has(.mid-left)) {
grid-template-columns: 5em 0 1fr 5em;
}
section:not(:has(.mid-right)) {
grid-template-columns: 5em 1fr 0 5em;
}
<section>
<div class="left">Left</div>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-left">Mid left takes half of space</div>
<div class="mid-right">Mid right takes half of space</div>
</section>
<section>
<div class="left">Left</div>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-left">Mid left should take all width</div>
</section>
<section>
<div class="left">Left</div>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-right">Mid right should take all width</div>
</section>
<section>
<div class="left">Left</div>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-left">Mid left should have equal width even if it has more content</div>
<div class="mid-right">Mid right</div>
</section>
<section>
<div class="left">Left</div>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-left">Mid left</div>
<div class="mid-right">Mid right should have equal width even if it has more content</div>
</section>
PS: На самом деле в моей разметке есть несколько обёрток с display: contents
, поэтому весьма вероятно, что решения, основанные на порядке элементов мне не подойдут. Тем не менее, мне кажется эти решения тоже полезны в вопросе (поскольку display: contents
довольно редко используется, да и может меня на какую подходящую мысль наведут).
Вообще, я не собирался добавлять такие примеры, но раз уж просят, то вот:
section {
display: grid;
grid-template: "l t t t" 2em
"l mt mt r" 1fr
"l ml mr r" 1fr / 5em 1fr 1fr 5em;
min-height: 8em;
}
section + section {
margin-top: 2em;
}
div {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
some-wrapper {
display: contents;
}
.left { grid-area: l; background: antiquewhite; }
.top { grid-area: t; background: silver; }
.right { grid-area: r; background: antiquewhite; }
.mid-top { grid-area: mt; background: yellow; }
.mid-left { grid-area: ml; background: aquamarine; }
.mid-right { grid-area: mr; background: lightsalmon; }
section:not(:has(.mid-left)) {
grid-template-columns: 5em 0 1fr 5em;
}
section:not(:has(.mid-right)) {
grid-template-columns: 5em 1fr 0 5em;
}
<section>
<div class="left">Left</div>
<some-wrapper>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-right">Mid right</div>
</some-wrapper>
<some-wrapper>
<div class="mid-left">Mid left</div>
</some-wrapper>
</section>
<section>
<div class="left">Left</div>
<some-wrapper>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
</some-wrapper>
<some-wrapper>
<div class="mid-left">Mid left</div>
</some-wrapper>
</section>
<section>
<div class="left">Left</div>
<some-wrapper>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-right">Mid right</div>
</some-wrapper>
<some-wrapper>
</some-wrapper>
</section>
<section>
<div class="left">Left</div>
<some-wrapper>
<div class="mid-right">Mid right</div>
<div class="mid-top">Mid top</div>
<div class="top">Top</div>
</some-wrapper>
<div class="right">Right</div>
</section>
<section>
<div class="left">Left</div>
<div class="top">Top</div>
<some-wrapper>
<div class="mid-right">Mid right</div>
<div class="mid-top">Mid top</div>
</some-wrapper>
<some-wrapper>
<div class="mid-left">Mid left</div>
</some-wrapper>
<div class="right">Right</div>
</section>