#html #css #css-grid
#HTML #css #css-сетка
Вопрос:
Я использую grid-template для настройки простой структуры сетки для одной строки и четырех столбцов. Два крайних левых столбца имеют фиксированную ширину, а оставшиеся два должны заполнить оставшееся пространство.
Однако второй столбец является необязательным — он может отсутствовать вообще. В этом случае я не хочу резервировать для него какое-либо пространство. Два крайних правых столбца должны заполнить пространство.
Очевидно, что это невозможно с grid-template. Возможно ли это вообще?
.grid {
display: grid;
grid-template-areas: "one two three four";
grid-template-columns: 8rem 8rem 1fr 1fr;
}
.one { background: #404788aa; grid-area: one; }
.two { background: #287d8eaa; grid-area: two; }
.three { background: #3cbb75aa; grid-area: three; }
.four { background: #dce319aa; grid-area: four; }
<div class="grid">
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
<div class="four">Four</div>
</div>
<hr><p>Three and Four should fill the space:</p>
<div class="grid">
<div class="one">One</div>
<div class="three">Three</div>
<div class="four">Four</div>
</div>
Комментарии:
1. Если у вас фиксированная ширина, то вы говорите браузеру «Придержите мое пространство»!
2. Сетка предназначена для случаев, когда вы знаете макет заранее, поэтому это не та технология верстки, которую следует использовать для такого рода вещей, когда вы не знаете макет заранее.
Ответ №1:
Попробуйте использовать display: flex
с flex
такими атрибутами:
.flex {
display: flex;
flex-direction: row;
justify-content: flex-start;
}
.one { background: #404788aa; flex: 0 1 8rem; }
.two { background: #287d8eaa; flex: 0 1 8rem; }
.three { background: #3cbb75aa; flex: 1 1 auto; }
.four { background: #dce319aa; flex: 1 1 auto; }
<div class="flex">
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
<div class="four">Four</div>
</div>
<hr><p>Three and Four should fill the space:</p>
<div class="flex">
<div class="one">One</div>
<div class="three">Three</div>
<div class="four">Four</div>
</div>
Ответ №2:
Flex, вероятно, лучшая идея, но это также вполне возможно легко сделать с помощью сетки. Это решение основано на том факте, что min-content установит ширину второго столбца равной 0, поскольку там нет элемента.
.grid {
display: grid;
grid-auto-columns: min-content min-content auto auto;
}
.one { background: #404788aa; width: 8rem }
.two { background: #287d8eaa; width: 8rem }
.three { background: #3cbb75aa; grid-column: 3; }
.four { background: #dce319aa; grid-column: 4; }
<div class="grid">
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
<div class="four">Four</div>
</div>
<hr><p>Three and Four should fill the space:</p>
<div class="grid">
<div class="one">One</div>
<div class="three">Three</div>
<div class="four">Four</div>
</div>
Ответ №3:
Это решение объединяет макет из 3 и 4 столбцов в макет из 5 столбцов и использует прием css для определения, какой класс использовать в divs, на основе определенного существования и порядка. Затем отрегулируйте divs вручную с помощью свойства grid-column для выравнивания по мере необходимости.
Это ужасно и абсолютно не масштабируемо, но он использует grid и css только для решения проблемы.
После просмотра моего решения я не решался делиться им вообще, но потом подумал, что это будет хорошей альтернативой, чтобы показать, насколько гибкое решение (предоставленное @ng-hobby) намного лучше этого.
Как сказал @TylerH, сеточная система не является идеальным решением, поскольку вам нужно определить структуру, прежде чем вы узнаете, сколько элементов вы хотите поместить в эту структуру.
Это визуальный пример, показывающий, как макеты 3 и 4 столбцов в конечном итоге объединяются вместе. Вертикальные линии показывают линии сетки, а цифры ниже — их названия.
4 column layout
| 8rem | 8rem | 1fr (50% - 8rem) | 1fr (50% - 8rem) |
| | | | |
3 column layout
| 8rem | 1fr (50% - 4rem) | 1fr (50% - 4rem) |
| | | |
5 column (mixed) layout
| | | | | |
1 2 3 4 5 6
| 8rem | 8rem | 50% - 12rem |4rem| 50% - 8rem |
Исходя из этого, мы можем вычислить свойство grid-template-columns.
Обратите внимание, что мне нужно было переключиться на проценты, потому что calc () не работает с fr.
( ) в css называется «Селектор смежных дочерних элементов», который в данном случае используется для применения правила css, когда определенные разделы находятся рядом друг с другом.
.grid {
display: grid;
grid-template-columns: 8rem 8rem calc(50% - 12rem) 4rem calc(50% - 8rem) ;
}
.one { background: #404788aa; grid-column: 1 / 2; }
.two { background: #287d8eaa; grid-column: 2 / 3; }
.two .three { background: #3cbb75aa; grid-column: 3 / 5; }
.three { background: #3cbb75aa; grid-column: 2 / 4; }
.four { background: #dce319aa; grid-column: 4 / 6; }
.two .three .four { background: #dce319aa; grid-column: 5 / 6; }
<div class="grid">
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
<div class="four">Four</div>
</div>
</div>
<hr><p>Three and Four should fill the space:</p>
<div class="grid">
<div class="one">One</div>
<div class="three">Three</div>
<div class="four">Four</div>
</div>
</div>