代码之家  ›  专栏  ›  技术社区  ›  Peter Bowers

在css网格中,为什么1fr+9fr在小屏幕中的行为与10fr不同?

  •  5
  • Peter Bowers  · 技术社区  · 7 年前

    所以我在CSS网格中定义了一个布局,它需要这个特定的行具有相同大小的输入。我可以做数学计算,只指定百分比,它可以很好地工作(见注释行),但是当我通过分数单位(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继续变小(减小到127px),但是B和C在169px时保持不变。

    如果我使用fr单位注释掉网格模板列行,而是使用下面的百分比,那么它可以正常工作。

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

    A with size 127px

    B with size 169px

    C with size 169px

    有人能帮我理解为什么会这样吗?我希望A停在169px,或者B和C继续缩小到127px,因为它们的定义几乎相同。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Temani Afif    7 年前

    添加 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 )将根据其内容(输入元素)调整大小,但前两列( 1FR 和 9fr )无法使用输入调整大小,因为这一个同时对它们(而不是其中一个)进行了跨度调整。换一种说法: 1FR 和 9FR 列没有任何显式内容,因此它们将根据可用空间调整大小,然后输入将匹配此空间。

    换句话说,第一个输入 尺寸 基于 1FR 和 9FR 但是另一个输入 上浆 这个 10FR .

    通过添加 最小宽度: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) 克服这一点而不是使用 最小宽度: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>