常规流中的块和内联布局

翻译不完整。 请帮助我们翻译这篇文章!

在这篇指南中,我们会探讨块级元素和内联元素在常规流中是怎样工作的。

在CSS 2.1规范中我们定义了常规流(Normal Flow)。常规流中的任何一个盒子总是某个格式区域formatting context)中的一部分。块级盒子是在块格式区域block formatting context)中工作的盒子,而内联盒子是在内联格式区域inline formatting context)中工作的盒子。任何一个盒子总是块级盒子或内联盒子中的一种。

规范中还规定了块格式区域与内联格式区域中的元素行为。对于块级格式环境,规范内规定:

“在一个块格式区域中,盒子会从包含块的顶部开始,按序垂直排列。同级盒子间的垂直距离会由“margin”属性决定。相邻两个块级盒子之间的垂直间距会遵循外边距折叠原则被折叠。

在一个块格式区域中,每个盒子的左外边缘会与包含块左边缘重合(如果是从右到左的排版顺序,则盒子的右外边缘与包含块右边缘重合)。” - 9.4.1

对于内联格式区域中的元素:

“在内联格式区域中,盒子会从包含块的顶部开始,按序水平排列。只有水平外边距、边框合内边距会被保留。这些盒子可以以不同的方式在垂直方向上对齐:可以底部对齐或顶部对其,或者按文字底部进行对齐。我们把包含一串盒子的矩形区域称为一个线条框。(The rectangular area that contains the boxes that form a line is called a line box.)” - 9.4.2

需要注意的是,CSS 2.1规范将文档的书写模式定义为从上到下横板排布,这从块级盒子的垂直间距这一属性就能看出来(Note that the CSS 2.1 specification describes documents as being in a horizontal, top to bottom writing mode. For example, by describing vertical distance between block boxes.)。在竖版书写模式工作时,块元素和内联元素的行为是相同的,关于这个我们将在未来的流布局与书写模式指南中进行探讨。

块格式区域中的元素

比如在英语环境中,块元素工作于横板书写模式中,此时的块元素会垂直排布,一个在另一个之下。

而在竖版书写模式中,块元素会水平排布。

在本指南的例子中,我们使用的是英语,因此会按横板模式进行书写。不过,即使您的文档是按照竖版模式进行书写的,描述的所有内容也都应该以相同的方式工作。

如规范中所定义,外边距使得两个块级盒子分开。这个例子展示了一个非常简单的由两个段落组成的排版,每个段落都加了一个边框。浏览器的默认样式表通过增加外边距(margin)的方式在每个段落的顶部和底部留出一定空间。

如果我们将p元素的边距设置为0,两个边框会紧贴在一起。

默认情况下,块级元素将占据这一内联方向的所有空间,因此我们的段落会铺开分布在多行,尽可能排满他的包含块。(By default block elements will consume all of the space in the inline direction, so our paragraphs spread out and get as big as they can inside their containing block.)如果限定了段落元素的宽度,第二个段落仍然会排布在第一个段落的下面——即使有足够空间使它们并排。每个块级元素都会从包含块的起始边开始,因此,在当前书写模式下,所有句子会从包含块的起始边开始。

外边距折叠

在规范中提到,块级元素之间的外边距会发生折叠。这意味着,如果一个具有上边距的元素排在在一个具有下边距的元素之下时,他们之间的间距不会是这两个外边距的和,即外边距会发生折叠,简单来说就是,间距与两个外边距中的较大者一样大。

在下面的例子中,段落的上边距设为20px,下边距设为40px,而段落之间的间距大小会是40px。这是因为第二段中的上边距比较小被折叠,间距跟随了第一个段落更大的下边距。

你可以在我们的文章《掌握外边距折叠》中阅读更多关于这一部分的内容。

注:如果不确定是否发生了外边距折叠,你可以使用浏览器的开发人员工具查看盒模型。准确的外边距值可以帮助你判断是否有外边距折叠发生。
 

内联格式区域中的元素

Inline elements display one after the other in the direction that sentences run in that particular writing mode. While we don’t tend to think of inline elements as having a box, as with everything in CSS they do. These inline boxes are arranged one after the other. If there is not enough space in the containing block for all of the boxes a box can break onto a new line. The lines created are known as line boxes.
内联元素按照句子在特定书写模式下运行的方向依次显示。虽然我们不倾向于认为内联元素有一个框,就像CSS中的所有元素一样。这些内嵌的盒子一个接一个排列。如果包含块中没有足够的空间容纳所有框,则框可以换行。创建的行称为行框。

In the following example we have three inline boxes created by a paragraph with a strong element inside it.
在下面的示例中,我们有三个由段落创建的内联框,其中包含一个强元素。

The boxes around the words before the strong element and after the strong element are referred to as anonymous boxes, boxes introduced to ensure that everything is wrapped in a box, but ones that we cannot target directly.
在强元素前和强元素后的单词周围的框称为匿名框,引入的框确保所有内容都包装在一个框中,但我们不能直接针对它们。

The line box size in the block direction (so the height when working in English) is defined by the tallest box inside it. In the next example I have made the strong element 300%, that content now defines the height of the line box on that line.
块方向上的线框大小(以英文工作时的高度为准)由其内部最高的框定义。在下一个示例中,我将强元素300%设为内容,该内容现在定义了该行上行框的高度。

Find out more about how Block and Inline Boxes behave in our Guide to the Visual Formatting Model.
在我们的视觉格式模型指南中,了解更多关于块和内联框的行为。

The display property and flow layout
显示属性和流布局编辑

In addition to the rules existing in CSS2.1, new levels of CSS further describes the behaviour of block and inline boxes. The display property defines how a box, and any boxes inside it behaves. In the CSS Display Model Level 3 we can learn more about how the display property changes the behaviour of boxes and the boxes they generate.
除了CSS2.1中现有的规则之外,新级别的CSS还进一步描述了块和内联框的行为。“显示”属性定义框及其内部的所有框的行为方式。在CSS显示模型级别3中,我们可以进一步了解显示属性如何更改框及其生成的框的行为。

The display type of an element defines the outer display type, this dictates how the box displays alongside other elements in the same formatting context. It also defines the inner display type, which dictates how boxes inside this element behave. We can see this very clearly when considering a flex layout. In the example below I have a div, which I have given display: flex. The flex container behaves like a block element, it displays on a new line and takes up all of the space it can in the inline direction. This is the outer display type of block.
一个元素的显示类型定义了外部显示类型,这规定了该框如何与同一格式上下文中的其他元素一起显示。它还定义了内部显示类型,该类型指示此元素内的框的行为方式。在考虑灵活布局时,我们可以很清楚地看到这一点。在下面的示例中,我有一个DIV,我已经给出了display:flex。flex容器的行为类似于一个块元素,它显示在一条新行上,并占用它在内联方向上可以占用的所有空间。这是块的外部显示类型。

The flex items however are participating in a flex formatting context, because their parent is the element with display: flex, which has an inner display type of flex, establishing the flex formatting context for the direct children.
但是,flex项正在参与flex格式上下文,因为它们的父级是带有display:flex的元素,后者具有flex的内部显示类型,为直接子级建立flex格式上下文。

Therefore you can think of every box in CSS working in this way. The box itself has an outer display type, so it knows how to behave alongside other boxes. It then has an inner display type which changes the way its children behave. Those children then have an outer and inner display type too. The flex items in the previous example become flex level boxes, so their outer display type is dictated by way of them being part of the flex formatting context. They have an inner display type of flow however, meaning that their children participate in normal flow. Items nested inside our flex item lay themselves out as block and inline elements unless something changes their display type.
因此,您可以想到CSS中的每个框都是以这种方式工作的。盒子本身有一个外部显示类型,所以它知道如何与其他盒子一起工作。然后它有一个内部显示类型,它改变了它的子对象的行为方式。然后,这些子级也有一个外部和内部显示类型。上一个示例中的flex项变为flex级别框,因此它们的外部显示类型取决于它们是flex格式上下文的一部分。然而,他们有一种内在的流动显示类型,这意味着他们的孩子参与正常的流动。嵌套在flex项中的项将自己设置为块和内联元素,除非有什么改变了它们的显示类型。

This concept of the outer and inner display type is important as this tells us that a container using a layout method such as Flexbox (display: flex) and Grid Layout (display: grid) is still participating in block and inline layout, due to the outer display type of those methods being block.
外部和内部显示类型的概念很重要,因为这告诉我们,由于这些方法的外部显示类型为块,因此使用flexbox(display:flex)和grid layout(display:grid)等布局方法的容器仍在参与块和内联布局。

Changing the Formatting Context an element participates in
更改元素参与的格式上下文

Browsers display items as part of a block or inline formatting context in terms of what normally makes sense for that element. For example a strong element is used to highlight a word, and displays bold in browsers. It would not generally make sense for that strong element to be displayed as a block level element, breaking onto a new line. If you did want all strong elements to display as block elements, you could do so by setting display: block on strong. This means that you can always use the most semantic HTML element to markup your content, and then change the way it displays using CSS.
浏览器将项目显示为块或内联格式上下文的一部分,根据该元素通常的意义。例如,强元素用于突出显示单词,并在浏览器中显示粗体。一般来说,将该强元素显示为块级元素并中断到新行是没有意义的。如果确实希望所有强元素显示为块元素,可以通过将display:block设置为强来实现。这意味着您可以始终使用最语义的HTML元素标记内容,然后使用CSS更改其显示方式。

Summary 总结

In this guide we have looked at how elements display in normal flow, as block and inline elements. Due to the default behaviour of these elements, an HTML document with no CSS styling at all, will display in a readable way. By understanding how normal flow works you will find layout easier, as you understand the starting point for making changes to how elements are displayed.
在本指南中,我们研究了元素在正常流中如何显示为块和内联元素。由于这些元素的默认行为,一个完全没有CSS样式的HTML文档将以可读的方式显示。通过了解正常流的工作方式,您将更容易找到布局,因为您了解更改元素显示方式的起点。

See Also 另请参见