百分比单位和fr单位之间的差异

2022-04-02 00:00:00 css css-grid

我正在处理CSS网格布局,遇到了一个我无法找到答案的问题。

考虑以下示例:

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
:root {
  --grid-columns: 12;
  --column-gap: 10px;
  --row-gap: 10px;
}

.grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), calc(100% / var(--grid-columns)));
  grid-column-gap: var(--column-gap);
  grid-row-gap: var(--row-gap);
  justify-content: center;		
} 

[class*=l-] {
  border: 1px solid red;
}

.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;
}
<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>

如您所见,由于使用calc(100% / var(--grid-columns))设置的百分比宽度,列超出了屏幕宽度。

但如果我使用fr单位,它可以完美地工作:

数据-lang="js"数据-隐藏="真"数据-控制台="真"数据-巴贝尔="假">
:root {
  --grid-columns: 12;
  --column-gap: 10px;
  --row-gap: 10px;
}

.grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), 1fr); 
  grid-column-gap: var(--column-gap);
  grid-row-gap: var(--row-gap);
  justify-content: center;		
}

[class*=l-] {
  border: 1px solid red;
}

.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;
}
<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>

用于查找答案的资源:

  • https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns

  • https://css-tricks.com/snippets/css/complete-guide-grid/

  • https://www.w3.org/TR/css-grid-1/

如果有人能解释为什么百分比宽度会有如此大的差异,那就太好了。


解决方案

fr

fr单位仅适用于容器中的可用空间。

因此在您的代码中:

grid-template-columns: repeat(12, 1fr);

.容器中的可用空间平均分布在12列中。

由于这些列仅处理可用空间,因此grid-column-gap不是一个因素。在确定fr长度(spec reference)之前从容器宽度中减去它。

以下是浏览器进行计算的方式:

(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%)除以12来确定

    100% / 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)
    
数据-lang="js"数据-隐藏="真"数据-控制台="真"数据-巴贝尔="假">
.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>

相关文章