创建Flexbox容器时会发生什么?

这是CSS规范开发人员之一Rachel Andrew的文章的翻译。


在简短的系列文章中,我将花一些时间详细解压Flexbox,就像过去使用grid一样 。 我们将研究Flexbox的用途 ,它的真正作用以及何时无法选择它作为布局方法。


在本文中,我们将仔细研究display:flex添加到样式表时的实际情况。


请弹性容器!


要使用Flexbox ,您需要一个将是Flex容器的元素。 在CSS中,使用display: flex



让我们考虑一下display: flex真正含义。 在“ 显示模块级别3”规范中,每个display属性值都描述为两个元素的组合:内部和外部显示模型。


当添加display: flex ,我们实际上定义了display: block flex 。 flex容器块的外部显示类型; 它充当标准流中的块级元素。 内部显示类型为flex,因此容器内部直接的元素将参与flex布局。


这是您可能从未想过的东西,但是您仍然可能理解。 flex容器的作用类似于页面上的其他任何块。 如果您在段落后面加上一个flex容器,则这两个元素的行为都与我们希望的块元素相同。


我们还可以使用display: inline flex设置容器为inline-flex display: inline flex ,即 flex容器充当行级元素,其子元素参与Flex布局。 line flex容器的子代的行为与block flex容器的子代的行为相同; 区别在于容器本身在整体布局中的行为。



具有外部显示类型的元素的行为这一概念非常有用,它定义为页面上的块(加上内部显示类型),决定了其子代的行为方式。 您可以将此推理应用于CSS中的任何块。 这个元素如何运作? 这个元素的孩子如何行动? 答案与它们的外部和内部显示模型有关。


行还是列?


定义flex容器后,一些初始值就会起作用。 在不添加其他属性的情况下,弹性项目将显示为字符串。 这是因为flex-direction属性的初始值为row 。 如果不更改它,您将得到一行。


flex-direction属性确定主轴的方向。 它可以采用其他值:


  • 专栏
  • 行反转
  • 列反转。

我们的元素将从直线的起始边缘开始沿行方向放置在一行中,并按照它们在源中出现的顺序显示。 在规范中,此边缘称为main-start


图_1
图_1。 主开始 -线方向的开始


如果使用值,则元素将从块方向的起始边缘开始定位,因此形成一列。


图_2
图_2。 主开始 -块方向的开始


如果我们使用row-reverse ,则main-startmain-end的位置将被交换; 因此,这些元素将以相反的顺序一个接一个地布置。


图_3
图_3。 main-start-从行尾开始


列反向值的作用相同。


重要的是要记住,这些值不会“切换元素的顺序”,尽管这是我们所看到的,它们只是改变元素流开始的位置,从而切换主起点的位置。 因此,我们的元素以相反的顺序显示,但这是因为它们开始从容器的另一端展开。


同样重要的是要记住,发生这种情况时,它纯粹是视觉效果。 我们要求元素从末端开始显示。 它们仍然以相同的顺序流动,这就是屏幕阅读器使用的顺序,以及可以将它们制成表格的顺序。 如果您确实想对项目进行重新排序,则永远不要使用行反向 。 为此,请对源文档进行更改。


两轴伸缩箱


我们已经揭示了flexbox的一个重要功能:能够将主轴从行切换到列的功能。 这是一个轴切换,所以我认为通常更容易理解网格布局中的对齐等内容。 使用双向网格时,可以几乎以相同的方式在两个轴上对齐。 Flexbox稍微复杂一点,因为根据使用主轴还是横轴会发生一些事件。


我们已经遇到了主轴,即您定义为弯曲方向值的轴。 横轴是另一个方向。 如果设置flex-direction:row ,则主轴沿行,横轴位于列的下方。 在flex-direction:列中,主轴位于列的下方,而横轴沿行。 在这里,我们需要考虑Flexbox的另一个重要功能,这是事实,它与屏幕的物理方向无关。 我们并不是在说从左到右的行或从上到下的列,因为并非总是如此。


记录模式


当我在上面描述行和列时,我提到了块方向和行方向。 本文以英文撰写,具有水平录制模式。 这意味着,当您要求Flexbox为您提供字符串时,您会水平显示Flex项目。 在这种情况下, main-start在左侧-英语句子的开始位置。


如果我使用从右到左的语言(例如阿拉伯语),则起点将在右边:



flexbox的初始值意味着,如果我要做的只是创建一个flex容器,那么我的元素将在右侧开始显示,并向左移动。 沿行方向的起点是句子在所使用的录制模式下的起点。


如果您发现自己处于垂直记录模式并引用了某行,则该行将垂直运行,因为这是用垂直语言执行文本行的方式。 您可以通过向flex容器添加写入模式属性并将其值设置为vertical-lr来尝试此操作。 现在,将flex-direction设置为row时 ,您将获得一个垂直的元素列。



因此,该系列可以水平运行, 主起点在左侧或右侧,也可以竖直工作, 主起点在顶部。 即使对于习惯于水平文本的人来说,很难想到垂直方向的线条,这仍然是一条柔韧性方向的线条!


为了在块方向上定位元素,我们将flex-direction属性设置为columncolumn-reverse 。 用英语(或阿拉伯语),我们看到元素从容器的顶部开始在页面的另一个上方显示。


在垂直记录模式下,块方向贯穿页面,因为这是位于这些记录模式下的块的方向。 如果在vertical-lr中指定一列,则块将从左到右垂直运行:



但是,无论显示块的方向如何,如果您正在使用列,那么都将沿块方向进行操作。


了解行或列可以在不同的物理方向上运行这一事实对于理解GridFlexbox所用的某些术语很有用 。 在FlexboxGrid中 ,我们没有提到“左右”或“上下”,因为我们不对文档的记录模式做任何假设。 所有CSS都越来越意识到写入模式。


如果您对实现使CSS其余部分表现相同的其他一些属性和值感兴趣,请阅读我有关布尔属性和值的文章。


作为总结,请记住:


  • flex-direction:行
    • 主轴=内联尺寸;
    • 主开始将是此录制模式下句子的开始位置;
    • 横轴=块方向;
  • flex-direction:列
    • 主轴=块尺寸;
    • 主开始将是在此录制模式下开始布局块的位置;
    • 横轴=内联尺寸。

初始对齐


当我们使用display:flex时 ,也会发生其他一些事情。 一些初步调整正在进行中。 在本系列的下一篇文章中,我们将介绍对齐方式。 但是,在研究display:flex时,应该考虑进行初始化。


注意 :值得注意的是,尽管这些对齐属性在Flexbox规范中已开始生效 ,但Box Alignment规范最终将按照Flexbox规范中的说明替换它们。

主要轴对准


justify-content属性的初始值设置为flex-start 。 这就是我们的CSS的样子:


 .container { display: flex; justify-content: flex-start; } 

这就是我们的flex项目从flex容器的开始边缘对齐的原因。 这也是为什么当我们指定row-reverse时 ,它们切换到最终边缘的原因,因为 现在它成为主轴的起点。


如果您看到以justify-开头的alignment属性,则该属性将应用于Flexbox的主轴 。 因此, justify-content沿主轴对齐,并将元素放置在其开头。


justify-content的其他可能值:


  • 柔性端
  • 中心
  • 周围空间
  • 间隔
  • 空间均匀(添加到Box Alignment中 )。

这些值用于在flex容器上分配可用空间。 这就是为什么元素相邻或彼此分开的原因。 如果添加justify-content:space-between ,则所有可用空间将分配在所有元素之间。 但是,只有在有可用空间时才可能发生这种情况。 如果您有一个紧密包装的flex容器(在布置完所有元素之后再没有多余的空间),则justify-content根本不起作用。


如果将伸缩方向切换到列,则可以看到此信息。 没有高度,flex容器将没有可用空间,因此设置justify-content:space-between参数将不起作用。 如果增加高度并使容器高于显示元素所需的高度,则该属性将具有以下效果:



沿横轴对齐


元件还沿着柔性容器的横向轴线排列成一条直线。 我们执行的对齐方式包括将块连续对齐。 在下面的示例中,我们的一个块比其他所有块具有更多的内容。 某些东西告诉其他块伸展到相同的高度。 这是align-items属性,具有初始拉伸值:



当您看到以align-开头的alignment属性并且您在flexbox中时 ,您正在处理沿横轴的对齐方式,而align-items则使元素沿伸缩线对齐。 其他可能的值:


  • 弹性启动
  • 柔性端
  • 中心
  • 基线。

如果不希望将所有块拉伸到最高高度,则设置align-items: flex-start会将它们全部对齐到横轴的起始边缘。



Flex元素的初始值


最后,flex元素本身也具有初始值;它们被设置为:


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

这意味着默认情况下,我们的元素将不会增长以填充主轴上的可用空间。 如果为flex-grow参数设置一个正值,则元素将增长并占用任何可用空间。


但是,由于flex-shrink的正值为1,因此可以压缩块。这意味着,如果我们的flex容器非常狭窄,则在发生溢出之前,元素将尽可能小。 这是合理的行为; 通常,我们希望它们保留在其块内,并且在有显示空间的情况下不要溢出。


为了获得最佳布局,默认情况下flex-basis属性设置为auto 。 我们将在本系列的下一篇文章中了解这意味着什么,但是,大多数时候,您可以将auto视为“拥有足够大的价值来容纳内容”。 您将看到,如果您有填充容器的灵活元素,并且其中一个具有比其他元素更多的内容,那么它将获得更多的空间。



这就是Flexbox的灵活性。 当flex-basis处于自动状态并且没有指示元素的大小时,它们的基本大小为max-content 。 这将是它们被拉伸且未执行换行时的大小。 在这种情况下,可用空间按照flexbox规范的以下说明中所述的比例在元素之间分配


注意 :分配丢失的空间时,伸缩率乘以基本伸缩大小。这将根据元素的压缩方式成比例地分配丢失的空间,因此,例如,较小的元素在将较大的元素显着减小之前不会压缩为零。”

较大的元素具有较少的可用空间,我们得到了最终的布局。 您可以将下面的两个屏幕截图进行比较,两者均取自上例。 但是,在第一个屏幕截图中,第三个块的内容较少,因此我们的列具有更均匀的空间分布。


图_4
图_4。 元素会延续以赋予更大的元素更多的空间


在这里, Flexbox可以帮助我们最终获得合理的最终结果,而无需编写CSS的人员进行干预。 与其平均减少空间而不是最终获得一个非常高的元素(在每行中都包含几个单词),不如给该元素更多的空间来容纳自己。 作为此行为的一部分,对于Flexbox的实际用例有一个关键。 Flexbox最适合以一种灵活且有意义的方式沿一条轴放置多个元素。


我在这里仅介绍了一些细节,但是在本系列后面的部分中,我们将介绍这些算法。


结论


在本文中,我采用了Flexbox的初始值来说明指定display:flex时实际发生的情况。 一旦您开始拆包,这是一个惊人的数字,并且其中包含的几个属性证明是灵活布局的许多关键特征。


Flex布局非常灵活:默认情况下,它们会尝试对您的内容做出正确的选择-对其进行压缩和拉伸以使其具有更好的可读性。 灵活的布局支持记录模式:行和列方向与所使用的记录模式相关联。 灵活的布局使您可以沿主轴将元素成组对齐,选择空间分布方式。 它们使您可以沿其柔性线对齐元素,使元素沿横轴相对移动。 请务必注意,灵活的布局可以理解您的内容量,并会尝试做出正确的基本决定来显示它。


在以后的文章中,我们将更详细地探讨这些领域,并进一步考虑何时以及为何可以使用Flexbox

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


All Articles