【问题标题】:In CSS Grid why is 1FR+9FR not behaving the same as 10FR in small screen sizes?在 CSS Grid 中,为什么 1FR+9FR 在小屏幕尺寸中的行为与 10FR 不同?
【发布时间】:2019-06-05 08:09:30
【问题描述】:

所以我在 CSS Grid 中定义了一个布局,它需要这个特定的行具有相同大小的输入。我可以做数学计算,只指定百分比,它工作正常(见注释掉的行)但是当我通过小数单位(fr)指定它时,跨栏比非跨栏“挤压”更多。

.A {
  grid-area: a;
}

.B {
  grid-area: b;
}

.C {
  grid-area: c;
}

.Exchange_Row {
  display: grid;
  grid-template-columns: 1fr 9fr 10fr 10fr 1fr;
  /*
   grid-template-columns:  3% 27% 30% 30% 3%;
  */
  grid-template-areas: "a a b c ."
}

input[type=text] {
  border: solid;
}
<div style="width: 90%; border: solid; border-radius: 5px; padding: 5px;">
  <div id="currencyRow" class="Exchange_Row">
    <input type="text" class="A" value="A" />
    <input type="text" class="B" value="B" />
    <input type="text" class="C" value="C" />
  </div>
</div>

当我将其调整为窄视图(小于 598)时,A 继续变小(降至 127 像素),但 B 和 C 保持不变,为 169 像素。

如果我使用 fr 单位注释掉 grid-template-columns 行,而是使用下面的百分比,那么它可以正常工作。

以下屏幕截图显示了使用 fr 单位定义列时的不同大小(如上面的代码中所示):

谁能帮我理解为什么会这样?我预计 A 会停在 169 像素,否则 B 和 C 会继续缩小到 127 像素,因为它们的定义几乎相同。

【问题讨论】:

  • 正如@TemaniAfif 所说,input 上的min-width: 0;width: 100% 解决了这个问题。

标签: css css-grid


【解决方案1】:

min-width:0 添加到输入中,您应该修复百分比值,以便它们与fr 完全相同。你有31fr 所以1fr 大约是100/31 = 3.225%

.A {
  grid-area: a;
}

.B {
  grid-area: b;
}

.C {
  grid-area: c;
}

.Exchange_Row {
  display: grid;
  grid-template-columns: 1fr 9fr 10fr 10fr 1fr;
  grid-template-areas: "a a b c ."
}
.Exchange_Row.percentage {
 grid-template-columns:  3.225% 29.03% 32.25% 32.25% 3.225%;
}

input[type=text] {
  border: solid;
  min-width:0;
}
<div style="width: 90%; border: solid; border-radius: 5px; padding: 5px;">
  <div id="currencyRow" class="Exchange_Row">
    <input type="text" class="A" value="A" />
    <input type="text" class="B" value="B" />
    <input type="text" class="C" value="C" />
  </div>
</div>
<div style="width: 90%; border: solid; border-radius: 5px; padding: 5px;">
  <div id="currencyRow" class="Exchange_Row percentage">
    <input type="text" class="A" value="A" />
    <input type="text" class="B" value="B" />
    <input type="text" class="C" value="C" />
  </div>
</div>

这与Automatic Minimum Size of Grid Items 以及如何grid items are sized 有关。输入元素的默认宽度由浏览器设置为最小尺寸(与flexbox 相同)。此大小用于定义10fr 的列大小。

如果我们参考以上链接:

一旦放置了网格项目,就会计算网格轨道(行和列)的大小,考虑到 其内容的大小和/或 在网格定义

两列(由10fr 定义)将根据其内容(输入元素)调整大小,但前两列(1fr9fr)无法使用输入调整大小,因为这一列跨越两者他们,而不仅仅是其中之一。换一种说法:1fr9fr 列没有任何明确的内容,因此它们将根据可用空间调整大小,然后输入将匹配该空间。

换句话说,第一个输入根据1fr9fr 调整大小,但另一个输入调整10fr

通过添加min-width:0,我们删除了自动最小大小约束,因此不再需要考虑内容大小,所有网格列都将使用可用空间调整大小,然后输入将匹配该大小。

添加width:100% 也可以解决问题,但方式不同。在这种情况下,我们根据其包含块(网格项)告诉输入具有其宽度,因此我们需要首先定义网格项的大小(考虑可用空间)然后解析百分比值以定义输入大小.

即使您更改 fr 值,任何配置都会发生这种情况:

.A {
  grid-area: a;
}

.B {
  grid-area: b;
}

.C {
  grid-area: c;
}

.Exchange_Row {
  display: grid;
  grid-template-columns: 5fr 5fr 1fr 1fr 1fr;
  grid-template-areas: "a a b c ."
}
.Exchange_Row.another {
 grid-template-columns:  50fr 50fr 3fr 1fr 1fr;
}

input[type=text] {
  border: solid;
}
<div style="width: 90%; border: solid; border-radius: 5px; padding: 5px;">
  <div id="currencyRow" class="Exchange_Row">
    <input type="text" class="A" value="A" />
    <input type="text" class="B" value="B" />
    <input type="text" class="C" value="C" />
  </div>
</div>
<div style="width: 90%; border: solid; border-radius: 5px; padding: 5px;">
  <div id="currencyRow" class="Exchange_Row another">
    <input type="text" class="A" value="A" />
    <input type="text" class="B" value="B" />
    <input type="text" class="C" value="C" />
  </div>
</div>

即使我们为第一个输入定义了更大的值,另一个总是会获胜,因为他们将定义自己的网格列的大小,而第一个将简单地获取剩余的值。

更新

另一种解释方式(正如@Michael_B 的评论)是1fr 单位等同于minmax(auto,1fr),这意味着对于10fr 列,我们将内容的auto 大小作为下限前两列不是这种情况,因为它们没有输入作为内容。

我们可以使用minmax(0,1fr) 来克服这个问题,而不是使用min-width:0

.A {
  grid-area: a;
}

.B {
  grid-area: b;
}

.C {
  grid-area: c;
}

.Exchange_Row {
  display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0,9fr) minmax(0,10fr) minmax(0,10fr) minmax(0,1fr);
  grid-template-areas: "a a b c ."
}
.Exchange_Row.percentage {
 grid-template-columns:  3.225% 29.03% 32.25% 32.25% 3.225%;
}

input[type=text] {
  border: solid;
}
<div style="width: 90%; border: solid; border-radius: 5px; padding: 5px;">
  <div id="currencyRow" class="Exchange_Row">
    <input type="text" class="A" value="A" />
    <input type="text" class="B" value="B" />
    <input type="text" class="C" value="C" />
  </div>
</div>
<div style="width: 90%; border: solid; border-radius: 5px; padding: 5px;">
  <div id="currencyRow" class="Exchange_Row percenage">
    <input type="text" class="A" value="A" />
    <input type="text" class="B" value="B" />
    <input type="text" class="C" value="C" />
  </div>
</div>

【讨论】:

  • 感谢您的意见。我不想让百分比列和 fr 列看起来相同 - 我试图让 fr 列的宽度保持相等,因为它们都有 10fr 宽度。 min-width 确实解决了这个问题,width=100% 也是如此,但它是一种解决方法,而不是问题的实际答案。我试图理解它为什么会发生 - 似乎它可能是 CSS 网格实现中的一个错误......
  • 当您使用百分比来调整列的大小时,实际上是在设置它们的长度。这是设置列宽的直接方法。另一方面,当您使用fr 单位时,您没有设置任何长度。您只是在分配可用空间(如果有)。因此,网格项的内容将对%fr 设置的轨道大小产生不同的影响。
  • 同样重要的是要注意1fr,默认情况下表示minmax(auto, 1fr)。这意味着使用fr 单位的列的最小宽度是内容的宽度。百分比大小没有最小宽度限制。要解决这个问题,请改用minmax(0, 1fr) (demo)。
  • @Michael_B 好的,编辑了答案以添加您的 cmets
  • 很棒 - 编辑非常有意义。因此,“10fr”列具有隐式最小宽度,而“1fr 9fr”列实际上并没有明确的内容,因此没有相同的隐式最小宽度。说得通。谢谢大家!
猜你喜欢
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
  • 1970-01-01
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多