Flexbox:这个柔性盒有多大?

我将继续发布有关Flexbox CSS技术功能的翻译。




该周期已发表以下文章:


  1. 创建Flexbox容器时会发生什么
  2. 您需要了解有关Flexbox中对齐的所有信息



简要总结


在最后两篇文章中,我们研究了创建flex容器时发生的情况,还研究了对齐方式。 这次,我们将研究Flexbox中经常引起混淆的尺寸问题。 Flexbox如何决定物品的大小?


这是我的Flexbox系列的第三部分。 在前两篇文章中,我们研究了创建Flex容器时发生的情况 ,并检查了它在Flexbox中的工作方式 。 这次我们将看看尺寸。 我们如何控制弹性项目的大小,以及浏览器在调整大小时会做出什么选择?


Flex项目的原始显示


如果我有一组内部内容的长度可变的元素并设置了display:flex parent,则这些元素将显示为字符串,并从主轴的起点开始排列。 在下面的示例中,我的三个元素的内容较小,可以将每个元素的内容显示为连续的行。 在flex容器的末端,有一个空间,其中的元素不会增长,因为每个元素的flex-grow属性的初始值为0,即 禁止增加。


弹性项目显示在同一行上。
图_1。 弹性项目显示在同一行上。


如果我向这些元素添加更多文本,它们将逐渐填充容器,并且文本将开始换行。 为元素分配了一部分容器空间,对应于每个容器中的文本量-为文本行较长的元素分配了更多空间。 这意味着当下一个元素仅包含一个单词时,我们将不会获得包含大量文本的高窄列。


已分配空间以为更长的项目提供更多空间
图_2。 已分配空间以为更长的项目提供更多空间


如果您曾经使用过Flexbox,则此行为可能是您熟悉的。 但是,也许您想知道浏览器如何执行尺寸计算,因为如果您查看几种现代浏览器,您会发现它们都一样。


这是因为规范中已经解决了诸如此类的功能,以确保在新浏览器或其他用户代理中实现Flexbox的任何人都知道该计算的工作方式。 我们可以使用规范为自己找到这些信息。


用于计算内部和外部尺寸的CSS规范(CSS固有尺寸和外部尺寸)


查看Flexbox规范中有关调整大小的内容 ,您会很快发现所需的大多数信息都在另一个规范中-CSS Intrisnic和Extrinsic Sizing 。 这是因为我们使用的大小调整概念不是Flexbox独有的 ,对齐属性也不是Flexbox独有的


要了解如何构建Flexbox中使用的尺寸标注 ,您需要查看Flexbox规范。 这似乎有点像您来回跳跃,因此在此我将描述一些关键定义,这些定义将在本文的其余部分中使用。


首选尺寸


首选元素大小是由宽度或高度确定的大小,或者是inline-sizeblock-size中这些属性的逻辑别名。 使用:


.box { width: 500px; } 

或具有内联大小的逻辑别名:


 .box { inline-size: 500px; } 

您声称要让块的宽度为500像素或连续500像素。


最小内容大小(MIN-CONTENT SIZE)


最小内容大小是元素可以容纳而不会溢出的最小内容大小。 如果元素包含文本,则必须采取所有程序传输措施。


最大内容大小(最大内容大小)


最大内容大小是一个项目可以容纳的最大内容大小。 如果元素包含不带格式的文本,则它将显示为一条长长的连续行。


柔性元件的主要尺寸(FLEX ITEM MAIN SIZE)


柔性元件的主要尺寸是其在主方向上的尺寸。 如果您使用英文字符串,则主要尺寸为宽度。 在英文栏中,主要尺寸是高度。


元素还具有指示主方向上主尺寸的最小值和最大值的属性,定义为min-widthmin-height


处理弹性商品尺寸


现在我们已经定义了一些术语,我们可以看到我们的flex元素如何计算尺寸。 flex属性的初始值如下:


  • flex-grow :0;
  • flex-shrink :1;
  • flex-basis :自动。

flex-basis是计算尺寸的基础。 如果将flex-basis设置为0并将flex-grow设置为1,那么我们所有的元素都不会具有初始宽度,因此flex容器中的空间将平均分配,并为每个元素分配相同的空间大小。



同时,如果flex-basis设置为autoflex-grow:1 ,则仅分配可用空间,即 没有内容的空间。



例如,在没有可用空间的情况下,当我们的内容超出一行的容量时,则不会分配任何内容。



这向我们表明,如果我们想知道Flexbox如何处理元素的尺寸,弄清楚auto的意义就很重要。 auto值将是我们的起点。


自动的定义(定义自动)


当在CSS中将auto赋值为某物的值时,在此上下文中它将具有非常特定的含义,值得一看。 正如与Fantasai的规范编辑的对话所解释的那样,CSS工作组花费大量时间来确定在任何情况下auto的含义。


在规范中,我们可以找到有关auto用作flex-basis时的含义的信息。 上面定义的术语应有助于我们分析此陈述。


将flex元素的auto关键字指定为“ flex-basis ”会返回main size属性的值。 如果此值本身是auto ,则使用content值。

因此,如果我们将flex-basis设置为auto ,则Flexbox将查看main size属性的值。 如果我们给其中一个伸缩项目指定一个宽度,则必须有一个主尺寸 。 在下面的示例中,所有元素的宽度均为110px,因此该值用作主要尺寸,因为 flex-basis的初始值为auto



但是,在我们最初的示例中,有些元素没有宽度,这意味着它们的主要大小auto ,因此我们需要继续执行以下语句:“如果该值本身是auto ,那么将使用content值。”


现在,我们需要查看规范对关键字内容的说明 。 这是可以用于flex-basis属性的另一个值(具有浏览器支持),例如:


 .item { flex: 1 1 content; } 

规范定义的内容如下:


根据flex元素的内容指示自动调整大小。 (通常,它等于最大内容大小,但具有处理纵横比,内部大小限制和正交流的设置。

在包含文本的flex元素的示例中,我们可以忽略一些更复杂的设置,并将content视为max-content的大小。


这解释了为什么当我们在每个元素中都有少量文本时,文本没有被包装。 flex项目默认情况下是自动调整大小的,因此Flexboxmax-content属性中获取其大小,将项目放置在该大小的容器中,然后完成工作!


故事还不止于此,因为当我们添加更多内容时,元素不会保留在max-content数量之内。 如果这样做,它们将脱离flex容器并导致溢出。 一旦它们装满容器,内容就开始被传送,并且元素根据它们内部的内容而变成不同的大小。


灵活的长度分辨率


在这一点上,很难查看该规范,但是您需要完成以下步骤:


首先,将所有元素的主要尺寸相加,然后查看它是否大于或小于容器的可用空间。


如果容器的大小大于数量,那么我们将对flex-grow参数感兴趣,因为我们有增长元素的空间。


在第一种情况下,我们的要素具有可用的增长空间。
图_3。 在第一种情况下,我们的要素具有可用的增长空间。


如果容器的大小小于总和,那么我们将对flex-shrink参数感兴趣,因为我们需要压缩元素以适合容器。


在第二种情况下,我们的元素太大,需要压缩才能放入容器
图_4。 在第二种情况下,我们的元素太大,需要压缩才能装入容器。


冻结大小已经可以设置的所有不可变元素。 如果我们使用flex-grow,它将包括所有具有flex-grow:0的元素。 这是弹性项目在容器中具有可用空间时的情况。 初始flex-grow值为0,因此它们变得与max-width一样大,然后它们不再从其main大小开始增长。


如果我们使用flex-shrink ,它将包括所有具有flex-shrink:0的元素。 如果我们给我们的flex元素集合flex-shrink:0,我们可以看到在这一步会发生什么。 元素冻结在最大含量状态,因此不会弯曲或装入容器中。



在本例中-使用flex元素的初始值-我们的元素可以被压缩。 因此,步骤继续进行,并且算法进入一个循环,在该循环中,算法确定要分配或删除的空间量。 在我们的例子中,我们使用flex-shrink ,因为项目的总大小大于容器,所以我们需要占用空间。


flex-shrink因子乘以元素的内部大小,在我们的例子中是最大内容大小。 这提供了减少空间的价值。 如果元素仅根据弯曲收缩系数删除空间,则当所有元素都将被删除时,较小的元素可能会消失,而较大的元素仍具有压缩空间。


在此循环中,还有一个额外的步骤来检查元素,这些元素将变得大于或小于其主要大小 ,在这种情况下,元素将停止增长或收缩。 同样,这样做是为了使某些元素与其他元素相比不会变得很小或太大。


在规范方面,所有这些操作都得到了简化,因为我没有考虑某些更极端的情况,并且您通常可以认为,假设您乐于让Flexbox发挥作用。 请记住,在大多数情况下,以下两个事实将起作用。


如果您不是从auto成长的,那么flex-basis将像元素的任何宽度或高度或最大内容大小一样被处理。 然后,将根据flex-basis尺寸乘以flex-shrink系数将其删除,因此,该空间将与元素的最大尺寸成比例地删除。


生长和收缩控制


我花了大部分时间介绍了Flexbox留在设备上时的功能。 当然,您可以使用flex属性对弹性项目进行更多控制。 希望他们通过了解幕后发生的事情看起来更加可预测。


通过设置自己的flex-basis或给元素本身指定大小,然后将其用作flex-basis ,可以返回对算法的控制,告诉Flexbox您要从该特定大小开始增大或缩小。 您可以通过将flex-growflex-shrink参数设置为0来完全禁用增长或压缩。但是,这时,您应该暂时使用愿望来控制flex项目,以查看您是否使用了正确的布局方法。 如果要在两个维度上对齐弹性项目,则最好选择网格布局。


相关的大小调试问题


如果您的flex元素以意外的大小结尾,那么通常会发生这种情况,因为您的flex-basis具有auto ,并且有些东西赋予该元素一定的宽度,然后将其用作flex-basis 。 在DevTools中检查一项可以帮助确定尺寸的来源。 您也可以尝试将flex-basis设置为0,这会使Flexbox将该项视为零宽度。 即使这不是您想要的结果,它也将有助于确定flex-basis的值以用作尺寸问题的元凶。


缩小差距


Flexbox的一个非常流行的功能是能够以与我们可以在网格布局和多列布局中指定间隙相同的方式来指定flex元素之间的间隙或装订线。 此功能是作为Box Alignment的一部分为Flexbox定义的,并且第一个浏览器实现即将到来Firefox希望在Firefox 63中为Flexbox提供间隙属性。 可以在Firefox Nightly中查看以下示例。



由于该图像在Firefox 63中可见
图_5。 由于该图像在Firefox 63中可见


与网格布局一样,在为弹性元素分配空间之前,请考虑间隙的长度。


完成中


在本文中,我试图解释Flexbox如何处理Flex项目增加的一些细微差别。 这似乎有些奇怪,但是,花一些时间弄清楚它是如何工作的,可以为您在布局中使用Flexbox节省大量时间。 我发现恢复默认值(默认情况下, Flexbox会尝试为您提供具有不同大小的多个元素的最合理布局)这一事实非常有用。 如果元素包含更多内容,则会为其提供更多空间。 如果您和您的设计师不同意Flexbox认为的最佳做法 ,则可以通过设置自己的flex-basis值来重新获得控制权。

Source: https://habr.com/ru/post/zh-CN425977/


All Articles