Ответ 1
fr
Блок fr
работает только со свободным пространством в контейнере.
Итак, в вашем коде:
grid-template-columns: repeat(12, 1fr);
... свободное место в контейнере распределяется поровну между 12 столбцами.
Поскольку столбцы имеют дело только со свободным пространством, grid-column-gap
не является фактором. Он был вычтен из ширины контейнера до определения длины fr
(спецификация).
Вот как браузер выполняет вычисления:
(free space - gutters) / 12 = 1fr
%
Когда вы используете проценты...
grid-template-columns: repeat(12, calc(100% / 12));
... контейнер разделен на 12 столбцов, каждый из которых имеет ширину 8,33333%. Это фактическая длина, в отличие от блока fr
, который работает только со свободным пространством.
И длина столбцов, и зазоры сетки учитываются в ширине.
Вот как браузер выполняет вычисления:
8.33333% * 12 = 100%
+
11 * 10px = 110px
Там явное переполнение.
(Примечание: свойства grid-*-gap
применяются только между элементами сетки - никогда между элементами и контейнером. Именно поэтому число разрывов сетки равно 11, а не 13.)
Это работает:
grid-template-columns: repeat(12, calc(8.3333% - 9.1667px));
Что сводится к этому:
12 столбцов
ширина каждого столбца определяется путем взятия полной ширины контейнера (
100%
) и деления его на 12100% / 12 = 8.3333% (individual column width)
затем вычтите пробелы в столбцах (их 11)
10px * 11 = 110px (total width of column gaps) 110px / 12 = 9.1667px (amount to be deducted from each column)
.grid {
display: grid;
grid-template-columns: repeat(12, calc(8.3333% - 9.1667px));
grid-column-gap: 10px;
grid-row-gap: 10px;
justify-content: center;
}
.l-1 { grid-column-start: span 1; }
.l-2 { grid-column-start: span 2; }
.l-3 { grid-column-start: span 3; }
.l-4 { grid-column-start: span 4; }
.l-5 { grid-column-start: span 5; }
.l-6 { grid-column-start: span 6; }
.l-7 { grid-column-start: span 7; }
.l-8 { grid-column-start: span 8; }
.l-9 { grid-column-start: span 9; }
.l-10 { grid-column-start: span 10; }
.l-11 { grid-column-start: span 11; }
.l-12 { grid-column-start: span 12; }
[class*=l-] { border: 1px solid red; }
<div class="grid">
<div class="l-6">Column 1</div>
<div class="l-6">Column 2</div>
<div class="l-3">Column 3</div>
<div class="l-4">Column 4</div>
<div class="l-3">Column 5</div>
<div class="l-2">Column 6</div>
<div class="l-1">Column 7</div>
<div class="l-10">Column 8</div>
<div class="l-1">Column 9</div>
<div class="l-5">Column 10</div>
<div class="l-5">Column 11</div>
<div class="l-2">Column 12</div>
</div>