CSS 布局 (二) 常规流、弹性盒子、网格

3、常规流

这篇文章解释了正常的流程,或者如果你没有改变网页元素的布局,它们的布局方式。

正如在上一节介绍布局的课程中详细介绍的那样,如果你没有应用任何CSS来改变它们的行为方式,网页上的元素就会以常规流布局。而且,正如我们开始发现的那样,你可以通过调整它们在常规流中的位置或将它们从正常流动中完全移除来改变元素的行为。从一个坚实的、结构良好的文档开始,在正常的流程中是可读的,这是开始任何网页的最好方式。它确保您的内容是可读的,即使用户使用一个非常有限的浏览器或设备,如屏幕阅读器读取页面的内容。此外,由于常规流的设计目的是制作可读的文档,因此以这种方式开始,您将与文档一起工作,而不是在更改布局时与之抗争。

在深入研究不同的布局方法之前,有必要回顾一下您在前面的模块中关于常规流的一些内容。

3.1 元素在默认情况下是如何布局的?

这个过程开始于单个元素的盒子以这样一种方式布局,即它们碰巧拥有的任何填充、边框或边距都被添加到它们的内容(content)中。这就是我们所说的盒子模型(box model

默认情况下,块级元素的内容填充包含它的父元素的可用行内空间,并沿块尺寸增长以容纳其内容。内联级元素的大小就是其内容的大小。你可以在一些默认display属性值为inline的元素上设置width或height,比如,但是display 值仍然是inline的。

如果你想以这种方式控制内联级元素的display 属性,使用CSS将其设置为块级元素(例如,使用display: block;或者display: inline-block;,它混合了两者的特征)。

这解释了元素是如何单独构建的,但是当它们彼此交互时,它们是如何构建的呢?常规流(在布局介绍文章中提到)是将元素放置在浏览器视口中的系统。默认情况下,块级元素按照块流方向(block flow direction)布局,该方向基于父元素的写入模式(初始值:horizontal-tb)。每个元素将出现在上一个元素下面的新行上,每个元素之间用指定的任何边距(margin)分隔。例如,在英语中,(或任何其他水平的,从上到下的书写模式)块级元素是垂直布局的。

内联元素的行为不同。它们不会出现在新行上;相反,只要在父块级元素的宽度范围内有足够的空间,它们都与相邻的(或换行的)文本内容放在同一行。如果没有空间,那么溢出的内容将移到新的一行。

如果两个垂直相邻的元素都设置了边距,并且它们的边距相互接触,则两个边距中较大的保留,较小的消失。这就是所谓的边缘塌陷(margin collapsing)。折叠边距仅在垂直方向(vertical direction)上相关。

4、弹性盒子

Flexbox是一种用于按行或列排列项目的一维布局方法。项可伸缩(扩展,flex (expand) )以填充额外的空间或收缩以适应更小的空间。本文解释了所有的基本原理。

4.1 Why Flexbox ?

很长一段时间以来,唯一可靠的跨浏览器兼容的工具,用于创建CSS布局是像浮动(floats)和定位(positioning)功能。这些方法是有效的,但在某些方面,它们也有限制和令人沮丧。

以下简单的布局设计是很难或不可能用这种工具以任何方便、灵活的方式实现的:

  • 块内容垂直居中在其父元素中。
  • 使容器的所有子元素占用相同数量的可用宽度/高度,而不管可用的宽度/高度是多少。
  • 使多列布局中的所有列采用相同的高度,即使它们包含不同数量的内容。

正如您将在后面的小节中看到的,flexbox使许多布局任务变得更加容易。让我们开始吧!

4.2 介绍一个简单的例子

在本文中,您将通过一系列练习来帮助您理解flexx是如何工作的。要开始,你应该从GitHub的repo中复制第一个启动文件flexbox .html。在现代浏览器(如Firefox或Chrome)中加载它,并在代码编辑器中查看代码。你也可以在这里看到现场直播。

CSS 布局 (二) 常规流、弹性盒子、网格_第1张图片

您将看到,我们有一个

元素,其中包含一个顶级标题,以及一个
元素,其中包含三个
。我们将使用这些来创建一个相当标准的三列布局。

4.3 指定将哪些元素布置为弹性盒子

首先,我们需要选择将哪些元素布置为弹性盒子。为此,我们在想要影响的元素的父元素上设置一个特殊的display值。在本例中,我们想要布局

元素,所以我们在
上设置:

section {
  display: flex;
}

这会导致

元素变成一个flex 容器( flex container),它的子元素变成flex 项(flex items)。这样做的结果应该像这样:

CSS 布局 (二) 常规流、弹性盒子、网格_第2张图片
因此,这个声明就提供了我们所需要的一切。难以置信的,对吧?我们有多列布局,列的大小相同,列的高度相同这是因为为flex项(flex容器的子项)设置的默认值是为了解决诸如此类的常见问题。

为了清楚起见,让我们重申一下这里发生了什么。我们给display 设置flex值的元素在与页面其他部分交互方面表现得像一个块级元素,但它的子元素被布置为flex。下一节将更详细地解释这意味着什么。还需要注意的是,如果您希望将元素的子元素作为flex项进行布局,但又希望该元素表现得像内联元素一样,则可以使用displayinline-flex值。

4.4 flex模型

当元素作为flex 项(flex items)布局时,它们沿着两个轴进行布局:
CSS 布局 (二) 常规流、弹性盒子、网格_第3张图片

  • 主轴(main axis)是沿着 flex 项的布局方向运行的轴(例如,作为页面上的一行,或页面上的一列)。这个轴的起点和终点称为主起点(main start)和主终点(main end)。
  • 交叉轴(cross axis)是垂直于flex 项布局方向的轴。这个轴的起点和终点称为交叉起点(cross start)和交叉终点(cross end)。
  • 设置了display: flex的父元素(在我们的例子中是
    )称为flex容器(flex container)
  • 在flex容器内作为 flexible boxes布局的项称为flex项(在我们的示例中是
    元素)。

在阅读后续章节时,请记住这个术语。如果你对所使用的任何术语感到困惑,你可以随时查阅它。

4.5 行还是列?

Flexbox提供了一个名为flex-direction的属性,用于指定主轴运行的方向(Flexbox子节点的布局方向)默认情况下,它被设置为row,这将使它们按照浏览器默认语言的工作方向(从左到右,对于英语浏览器)排成一行

尝试在

规则中添加以下声明:

flex-direction: column;

您将看到,这将条目放回到列布局中,就像我们添加任何CSS之前一样。在继续之前,请从示例中删除此声明。

注意:您还可以使用row-reversecolumn-reverse值以相反的方向布局伸缩项。也试试这些值吧!

4.6 换行

当你在布局中有一个固定的宽度或高度时,出现的一个问题是,最终你的flexx子节点会溢出它们的容器,破坏布局。看看我们的flexbox-wrap0.html示例,并尝试实时查看它(如果你想跟随这个示例,现在就获取该文件的本地副本):

CSS 布局 (二) 常规流、弹性盒子、网格_第4张图片
在这里,我们看到子元素确实是从他们的容器中挣脱出来的。解决这个问题的一种方法是在

规则中添加以下声明:

flex-wrap: wrap;

同时,在

规则中添加以下声明:

flex: 200px;

现在试试这个。你会发现,包含以下内容后,布局看起来好多了:

CSS 布局 (二) 常规流、弹性盒子、网格_第5张图片
现在有多行了。每一行都有合理地尽可能多的flexbox填满它。任何溢出都向下移动到下一行。在文章上设置flex: 200px声明意味着每篇文章的宽度至少为200px。我们将在后面更详细地讨论这个属性。您可能还注意到,最后一行的最后几个子元素都变宽了,因此整个行仍然是填满的。

但我们能做的还有很多。首先,尝试将flex-direction属性值更改为行反向(row-reverse)。现在您将看到您仍然拥有多行布局,但是它从浏览器窗口的另一个角落开始,并反向流动。

4.7 flex-flow 简写

在这一点上,值得注意的是flex-directionflex-wrap有一个简写:flex-flow。例如,你可以替换

flex-direction: row;
flex-wrap: wrap;

flex-flow: row wrap;

4.8 flex项的灵活大小

现在让我们回到我们的第一个例子,看看我们如何控制与其他flex 项相比,flex 项占用的空间比例。启动flexbox1.html的本地副本,或者将flexbox1.html的副本作为新的起点(see it live)。

首先,在CSS的底部添加以下规则:

article {
  flex: 1;
}

这是一个无单位的比例值,用于指示每个flex项相对于其他flex项在主轴上占用多少可用空间。在本例中,我们为每个

元素赋予相同的值(值为1),这意味着在设置了paddingmargin等属性后,它们都将占用等量的剩余空间。这个值在flex项之间按比例共享:将每个flex项的值设置为400000将具有完全相同的效果。

现在在前面的规则下面添加以下规则:

article:nth-of-type(3) {
  flex: 2;
}

现在,当您刷新时,您将看到第三个

占用的可用宽度是其他两个的两倍。现在总共有四个可用的比例单位(因为1 + 1 + 2 = 4)。前两个伸缩物品各有一个单位,所以它们各占可用空间的1/4。第三个有两个单元,所以它占用了可用空间的2/4(或1 / 2)。

您还可以在flex值中指定最小大小值。尝试像这样更新你现有的文章规则:

article {
  flex: 1 200px;
}

article:nth-of-type(3) {
  flex: 2 200px;
}

这基本上说明,“每个flex项首先会被赋予200px的可用空间。在此之后,剩余的可用空间将按照比例单位共享。”尝试刷新,您将看到空间共享方式的不同。
CSS 布局 (二) 常规流、弹性盒子、网格_第6张图片
flexbox的真正价值体现在它的灵活性/响应性上。如果您调整浏览器窗口的大小或添加另一个

元素,布局将继续正常工作。

4.9 Flex:缩写与全写

Flex是一个简写属性,最多可以指定三个不同的值:

  • 我们上面讨论过的无单位比例值。这可以使用flex-grow 全写属性单独指定。
  • 第二个无单位的比例值flex-shrink,它在flex项溢出其容器时发挥作用。此值指定为防止溢出而收缩项的大小。这是一个相当高级的flex特性,我们不会在本文中进一步介绍它。
  • 我们上面讨论的最小值。这可以使用基于flex-basis单独指定。

我们建议不要使用全写flex 属性,除非你真的需要(例如,覆盖之前设置的东西)。它们会导致编写大量额外的代码,并且会让人有些困惑。

4.10 水平和垂直对齐

您还可以使用flexbox 特性沿主轴或交叉轴对齐flex项。让我们通过查看一个新示例来探讨这个问题:flex-align0.html(也请参见在线示例)。我们将把它变成一个整洁、灵活的按钮/工具栏。现在你会看到一个水平菜单栏,一些按钮挤在左上角。

在这里插入图片描述
首先,获取这个示例的本地副本。

现在,将以下内容添加到示例的CSS底部:

div {
  display: flex;
  align-items: center;
  justify-content: space-around;
}

CSS 布局 (二) 常规流、弹性盒子、网格_第7张图片
刷新页面,您将看到按钮现在很好地位于水平和垂直的中心。我们通过两个新的性质来实现。

align-items控制flex项在交叉轴上的位置:

  • 默认情况下,该值为stretch,它将拉伸所有flex项以沿交叉轴的方向填充父项如果父项在交叉轴方向上没有固定的高度,那么所有的flex项都将与最高的flex项一样高。这就是我们的第一个示例在默认情况下具有相等高度的列的方式。
  • 我们在上面代码中使用的center值使项目保持其固有尺寸,但沿着交叉轴居中。这就是为什么我们当前示例的按钮垂直居中。
  • 您还可以使用像flex-startflex-end这样的值,它们将分别在交叉轴的开始和结束处对齐所有项。有关详细信息,请参阅align-items。

您可以通过对单个flex项应用align-self属性来覆盖它们的align-items行为。例如,尝试在CSS中添加以下内容:

button:first-child {
  align-self: flex-end;
}

CSS 布局 (二) 常规流、弹性盒子、网格_第8张图片
看看有什么效果,完成后再把它去掉。

justify-content控制flex项在主轴上的位置。

  • 默认值是flex-start,它使所有项位于主轴的起点。
  • 你可以使用flex-end来使它们坐在末端。
  • center也是justify-content的值。它将使伸缩项目位于主轴的中心。
  • 我们上面使用的值space-around很有用——它将所有的项目均匀地分布在主轴上,在两端都留下一点空间。
  • 还有另一个值,space-between它与space-around非常相似,只是它在两端都不留下任何空间。

在弹性布局中,justify-items属性被忽略。

我们鼓励你在继续之前尝试一下这些值,看看它们是如何工作的。

4.11 flex 项排序

Flexbox还有一个特性,可以在不影响源顺序的情况下更改flex项的布局顺序。这是另一件传统布局方法无法做到的事情。

这方面的代码很简单。尝试将以下CSS添加到按钮栏示例代码中:

button:first-child {
  order: 1;
}

刷新后,你会看到“Smile”按钮已经移动到主轴的末端。让我们更详细地讨论一下这是如何工作的:

  • 默认情况下,所有伸缩项的order值为0
  • 具有较高指定order值的Flex项将比具有较低指定order值的项在显示顺序中显示较晚。
  • 具有相同order值的Flex项将按source order显示。因此,如果您有四个项,其顺序值分别设置为2、1、1和0,那么它们的显示顺序将是第4、第2、第3和第1。
  • 第三项出现在第二项之后,因为它具有相同的order值,并且在source order中位于第二项之后。

可以设置负序值,使项比值为0的项显示得早。例如,你可以使用以下规则使“腮红”按钮出现在主轴的开始:

button:last-child {
  order: -1;
}

4.12 嵌套弹性盒子

使用flexbox可以创建一些非常复杂的布局将flex项设置为flex容器是完全可以的,这样它的子项也可以像弹性盒子一样布局。请查看complex-flexbox.html(也请查看现场)。

CSS 布局 (二) 常规流、弹性盒子、网格_第9张图片
此操作的HTML相当简单。我们有一个包含三个

元素。第三个
包含三个
,第一个
包含五个

你可能感兴趣的:(前端,css,前端)