css网格随着fr增长超过100%宽度,但随着minmax增长不超过100%

时间:2018-07-09 19:51:08

标签: html css css3 css-grid

.small-container { width: 200px; }
.small-container > div { margin: 16px; }
.border { box-shadow: 0 0 2px 2px black; }

.break-long-text {
    width: 100%;
    word-wrap: break-word;
    overflow-wrap: break-word;
}

.grid-fr {
    display: grid;
    grid-template-columns: 1fr;
}

.grid-minmax {
    display: grid;
    grid-template-columns: minmax(120px, 1fr);
}
<div class="small-container">
  <div class="grid-fr">
    <div class="break-long-text border">
      LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG
    </div>
  </div>
  <div class="grid-minmax">
    <div class="break-long-text border">
      LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG
    </div>
  </div>
</div>

两个网格完全相同,唯一的区别是grid-template-columns值。但是,一个网格遵循其父级(200px)的宽度,而另一个忽略该宽度。

  1. 网格:grid-template-columns: 1fr; =>忽略父级宽度并继续直到内容被填充

  2. 网格:grid-template-columns: minmax(120px, 1fr); =>仅增加到父级宽度(200px),然后根据需要增大。但是,它仍然大于定义的最小宽度(120px),这是正确的,因为在此示例中1fr大于120px

由于最后两者的宽度应为1fr,所以我想知道结果是否不同。这是错误还是预期行为?为什么第二个网格不能按我期望的方式工作?

如果我不希望一个单元格大于其父单元格,我应该总是使用minmax吗?

3 个答案:

答案 0 :(得分:5)

这是第二个网格的解决方案。

.grid-minmax {
   display: grid;
   grid-template-columns: minmax(120px, 1fr);
 }

这是浏览器计算轨道大小的方法:

(200px container) - (120px nonflexible track size) + (1fr leftover space) = 200px

使用规范中提供的指导(请参阅下文),上述行为相对简单明了。

但是为什么第一个容器中的内容溢出?

这是一个棘手的情况,在这一点上,我可以看到两条可能的答案路径。

  1. 之间的工作方式存在问题/问题/错误:

    .break-long-text {
        word-wrap: break-word;
        overflow-wrap: break-word;
     }
    

    grid-template-columns: 1fr;
    

    之所以这样说,是因为当字符串分解后,问题中的问题就不存在了。换句话说,两个网格容器的行为都相同(demo)。

OR

  1. 我在规范中找不到答案。我已经审查了以下部分。


fr单元的工作原理如下:

根据规范:

  

§ 7.2.3. Flexible Lengths: the fr unit

     

弹性长度或<flex>是具有fr单位的尺寸,它表示网格容器中剩余空间的一部分。

     

大小为fr的轨道称为弹性轨道,因为它们响应剩余空间而弯曲,类似于弹性项目如何填充弹性容器中的空间。

好的。到目前为止,一切都很好。网格布局中的fr单元的功能与Flex布局中的flex-grow相似。

继续规范...

  

所有非灵活的轨道尺寸调整功能都达到最大值之后,就会发生剩余空间的分布。

     

从可用空间中减去此类行或列的总大小,得到剩余的空间,然后将其按弹性系数按比例在弹性尺寸的行和列之间进行分配。< / p>      

(重点是我的)

换句话说,首先从可用空间(在这种情况下为200px)中减去所有非灵活的轨道尺寸(例如基于像素或em的尺寸)。剩下的任何空间都被视为剩余空间,然后由fr单元作为目标。

还有,“轨道尺寸调整功能”到底是什么?

  

每个轨道大小调整功能都可以指定为长度,网格容器大小的百分比,占列或行的内容的度量或网格中自由空间的一部分。

     

也可以使用minmax()表示法将其指定为范围,该表示法可以结合前面提到的任何机制来为列或行分别指定最小和最大磁道大小调整功能。

     

https://www.w3.org/TR/css3-grid-layout/#grid-template-rows-track-sizing-function

这说明了第二个网格容器(使用minmax())而不是第一个(使用1fr)的工作原理。

答案 1 :(得分:1)

  

如果我不希望一个单元格变大,我应该总是使用minmax   比它的父母?

在我看来,fr单元在word-wrap , overflow-wraphyphens属性中的表现不佳。

在这种情况下,如果您有理由相信内部文本会包含长词,则建议使用minmax()函数作为解决方法。

注意:由于我们正在尝试模拟fr单位的结果-在minmax()函数中使用0作为最小长度是有意义的。例如:grid-template-columns: minmax(0, 1fr);

下面的演示将fr单位和minmax()与长文本进行了比较-结果似乎相同!

.medium-container { 
  width: 50vw;
  border: 1px solid green;
  padding: 20px; 
}
.border { box-shadow: 0 0 2px 2px black; }

.break-long-text {
    width: 100%;
    word-wrap: break-word;
    overflow-wrap: break-word;
}


.grid-fr {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 20px;
}

.grid-minmax {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-gap: 20px;
}

.break-long {
    width: 100%;
    word-wrap: break-word;
    overflow-wrap: break-word;
}
<h2>Using 'fr' units:</h2>
<div class="medium-container">
  <div class="grid-fr">
    <div class="break-long-text border"> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled
      it to make a type specimen book. 
    </div>
    <div class="break-long-text border"> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,  when an unknown printer took a galley of type and scrambled
      it to make a type specimen book. 
    </div>
    <div class="break-long-text border"> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled
      it to make a type specimen book. 
    </div>
      </div>
</div>
<hr>
<h2>Using 'minmax' workaround (contains long text):</h2>
<div class="medium-container">
  <div class="grid-minmax">
    <div class="break-long-text border"> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG when an unknown printer took a galley of type and scrambled
      it to make a type specimen book. 
    </div>
    <div class="break-long-text border"> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG when an unknown printer took a galley of type and scrambled
      it to make a type specimen book. 
    </div>
    <div class="break-long-text border"> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG when an unknown printer took a galley of type and scrambled
      it to make a type specimen book. 
    </div>
      </div>
</div>

Codepen demo(调整大小以查看效果)


另一种解决方法:word-break: break-word;

'fr'个单位发挥得很好,并具有word-break属性。

.break-long-text {
    word-break: break-word; /* word-break workaround */
}

特别是,基于眨眼的浏览器可以使用break-word值,而firefox需要使用break-all值。

.small-container { width: 200px; }
.small-container > div { margin: 16px; }
.border { box-shadow: 0 0 2px 2px black; }

.break-long-text {
    word-break: break-word;
}
/* firefox only CSS */
@-moz-document url-prefix() {
  .break-long-text {
    word-break: break-all;
  }
}

.grid-fr {
    display: grid;
    grid-template-columns: 1fr;
}

.grid-minmax {
    display: grid;
    grid-template-columns: minmax(120px, 1fr);
}
<div class="small-container">
  <div class="grid-fr">
    <div class="break-long-text border">
      LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG
    </div>
  </div>
  <div class="grid-minmax">
    <div class="break-long-text border">
      LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG
    </div>
  </div>
</div>

此解决方法的问题在于,要求break-all值的浏览器(例如firefox)在中间起作用,通常不是期望的结果。

.small-container { width: 200px; }
.small-container > div { margin: 16px; }
.border { box-shadow: 0 0 2px 2px black; }

.break-long-text {
    word-break: break-all;
}

.grid-fr {
    display: grid;
    grid-template-columns: 1fr;
}

.grid-minmax {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
}
<div class="small-container">
  <div class="grid-fr">
    <div class="break-long-text border">
      Lorem Ipsum is simply dummy text of the printing and typesetting industry. LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG when an unknown printer took a galley of type and scrambled
    </div>
  </div>
  <div class="grid-minmax">
    <div class="break-long-text border">
      Lorem Ipsum is simply dummy text of the printing and typesetting industry. LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG when an unknown printer took a galley of type and scrambled
    </div>
  </div>
</div>

答案 2 :(得分:1)

解决方案

设置min-width:0容器的.break-long-text可以解决问题。

.small-container { width: 200px; }
.small-container > div { margin: 16px; }
.border { box-shadow: 0 0 2px 2px black; }

.min-width-0{
    min-width: 0;
}
.break-long-text {
    width: 100%;
    word-wrap: break-word;
    overflow-wrap: break-word;
}

.grid-fr {
    display: grid;
    grid-template-columns: 1fr;
}

.grid-minmax {
    display: grid;
    grid-template-columns: minmax(120px, 1fr);
}
<div class="small-container">
  <div class="grid-fr">
    <div class="break-long-text border min-width-0">
      LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG
    </div>
  </div>
  <div class="grid-fr">
    <div class="break-long-text border">
      LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG
    </div>
  </div>
  <div class="grid-minmax">
    <div class="break-long-text border">
      LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG
    </div>
  </div>
</div>

说明:

From css-tricks:

网格列的最小宽度是自动的。 (顺便说一下,弹性项目也是如此。)

并且由于auto完全基于内容,因此我们可以说它的大小是“无限”的,其尺寸是可变的。如果我们在列上放置一个明确的宽度,例如50%或400px,那么我们会说它的大小是“绝对”。

要应用此修复程序,我们需要确保该列具有确定的最小宽度而不是自动宽度。