Skip to content

Latest commit

 

History

History
2475 lines (1511 loc) · 240 KB

File metadata and controls

2475 lines (1511 loc) · 240 KB

第 12 章 灵活的框布局 Flexible Box Layout

The CSS Flexible Box Module Level 1, or Flexbox for short, makes the once difficult task of laying out many classes of page, widget, application, and gallery almost simple. With Flexbox, you often don’t need a CSS framework. In this chapter, you’ll learn how, with a few lines of CSS, you can create almost any feature your site requires.

CSS 灵活框模块级别 1(或简称为 Flexbox)使布置页面,小部件,应用程序和库的许多类这一艰巨的任务变得非常简单。使用 Flexbox,您通常不需要 CSS 框架。在本章中,您将学习如何使用几行 CSS 创建几乎所有站点所需的功能。

12.1 Flexbox Fundamentals

Flexbox is a simple and powerful way to lay out page components by dictating how space is distributed, content is aligned, and elements are visually ordered. Content can easily be arranged vertically or horizontally, and can be laid out along a single axis or wrapped across multiple lines. And much, much more.

Flexbox 是一种通过指示空间分布方式,内容对齐方式和视觉元素排序方式来布局页面组件的简单而强大的方法。内容可以轻松地垂直或水平排列,并且可以沿单个轴布局或跨多行折行。还有更多。

With flexbox, the appearance of content can be independent of source order. Though visually altered, flex properties should not impact the order of how the content is read by screen readers.

使用 flexbox,内容的外观可以与源顺序无关。尽管从视觉上进行了更改,但是 flex 属性不应影响屏幕阅读器阅读内容的顺序。

Screen readers following source order is in the specification, but Firefox currently follows the visual order. There is discussion in the accessibility community that this Firefox “bug” may be the correct behavior, so the spec may change.

Perhaps most importantly, with flexible box module layouts, elements can be made to behave predictably for different screen sizes and different display devices. Flexbox works very well with responsive sites, as content can increase and decrease in size when the space provided is increased or decreased.

也许最重要的是,通过灵活的盒式模块布局,可以使元素针对不同的屏幕尺寸和不同的显示设备具有可预测的行为。Flexbox 与响应式站点非常兼容,因为当提供的空间增加或减少时,内容的大小可能会增加和减小。

Flexbox works off of a parent and child relationship. Flexbox layout is activated by declaring display: flex or display: inline-flex on an element. This element becomes a flex container, arranging its children within the space provided and controlling their layout. The children of this flex container become flex items. Consider the following styles and markup, illustrated in Figure 12-1:

Flexbox 可以脱离父子关系。通过声明 display: flexdisplay: inline-flex 在元素上激活 Flexbox 布局。该元素成为一个 flex 容器,将其子元素布置在提供的空间内并控制其布局。此 flex 容器的子元素 成为 flex 项(译者注:以下称 flex 子元素)。考虑以下样式和标记,如图 12-1 所示:

div#one {
  display: flex;
}
div#two {
  display: inline-flex;
}
div {
  border: 1px dashed;
  background: silver;
}
div > * {
  border: 1px solid;
  background: #aaa;
}
div p {
  margin: 0;
}
<div id="one">
  <p>flex item with<br />two longer lines</p>
  <span>flex item</span>
  <p>flex item</p>
</div>
<div id="two">
  <span>flex item with<br />two longer lines</span>
  <span>flex item</span>
  <p>flex item</p>
</div>

The two kinds of flex containers

Look for the Play symbol to know when an online example is available. All of the examples in this chapter can be found at https://meyerweb.github.io/csstdg4figs/12-flexbox/.

Notice how each child element of the divs became a flex item, and furthermore, how they all laid out in the same way? It didn’t matter that some were paragraphs and others were spans. They all became flex items. (There would likely have been some differences due to the paragraphs’ margins, except those were removed.)

注意 divs 的每个子元素如何变成 flex 子元素,此外,它们如何以相同的方式布置?某些是段落而其他是 spans 没关系。他们都成为 flex 子元素。(由于删除了这些段落,因此由于段落的空白,可能会有一些差异。)

The only real difference between the first and second flex containers is that one was set to display: flex, and the other to display: inline-flex. In the first, the div becomes a block box with flex layout inside it. In the second, the div becomes an inline-block box with flex inside it.

第一和第二个 flex 容器之间的唯一真正的区别是一个被设置为 display: flex,另一个被设置为 display: inline-flex。在第一个中,div 变成一个内部具有 Flex 布局的块盒。在第二个中,div 变成一个 inline-block,内部包含 flex。

As of this writing, a new pattern emerging in CSS is to separate display values into separate keywords. In this new system, the values used would be display: flex block and display: flex inline. The legacy values flex and inline-flex will continue to work fine, so don’t worry about using them, but if you see values like inline flex or flex inline, that’s why.

The key thing to keep in mind is that once you set an element to be a flex container, like the divs in Figure 12-1, it will only flex its immediate children, and not further descendants. However, you can make those descendants flex containers as well, enabling some really complex layouts.

要牢记的关键是,一旦将一个元素设置为 flex 容器(如图 12-1 中的 divs),它仅将其直接子代变为 flex 子元素,而其他后代不受影响。但是,您也可以使这些子代变成 flex 容器,从而启用一些非常复杂的布局。

Within a flex container, items line up on the main axis. The main axis can either be horizontal or vertical, so you can arrange items into columns or rows. The main axis takes on the directionality set via the writing mode: this main axis concept will be discussed in depth later on (see “Understanding axes” on page 579).

在 flex 容器中,项目在主轴上排列。主轴可以是水平或垂直的,因此您可以将项目排列为列或行。主轴采用通过书写模式设置方向性:稍后将深入讨论该主轴概念(请参见第 579 页的“理解轴”)。

As the first div in Figure 12-1 demonstrates, when the flex items don’t fill up the entire main axis (in this case, the width) of the container, they will leave extra space. There are properties dictating how to handle that extra space, which we’ll explore later in the chapter. You can group the children to the left, the right, or centered, or you can spread them out, defining how the space is spread out either between or around the children.

如图 12-1 中的第一个 div 所示,当 flex 项目没有填满容器的整个主轴(在本例下为宽度)时,它们将留下额外的空间。有一些属性指示如何处理额外的空间,我们将在本章的后面部分进行探讨。您可以将子元素分组到左侧,右侧或居中,也可以将它们散开,定义空间如何在子元素之间或周围分布。

Besides distributing space, you can also allow the flex items to grow to take up all the available space by distributing that extra space among one, some, or all of the flex items. If there isn’t enough space to contain all the flex items, there are flexbox properties you can employ to dictate how they should shrink to fit within their container, or whether they’re allowed to wrap to multiple flex lines.

除了分配空间外,还可以通过在一个,某些或所有 flex 子元素之间分配额外的空间,使 flex 子元素增长以占用所有可用空间。如果没有足够的空间来容纳所有 flex 子元素,则可以使用 flex 框属性来指示如何收缩它们以适合其容器,或者是否允许它们折行到多个 flex 行。

Furthermore, the children can be aligned with respect to their container or to each other; to the bottom, top, or center of the container; or stretched out to fill the container. Regardless of the difference in content length among sibling containers, with flexbox you can make all the siblings the same size with a single declaration.

此外,flex 子元素可以相对于他们的容器或彼此对齐。到容器的底部,顶部或中心;或拉长以填充容器。不管兄弟容器之间内容长度的不同,使用 flexbox 都可以通过一个声明使所有兄弟具有相同的大小。

12.1.1 A Simple Example

Let’s say we want to create a navigation bar out of a group of links. This is exactly the sort of thing flexbox was designed to handle. Consider:

假设我们想从一组链接中创建一个导航栏。这正是 flexbox 设计用来处理的事情。考虑:

nav {
  display: flex;
}
<nav>
  <a href="/">Home</a>
  <a href="/about">About</a>
  <a href="/blog">Blog</a>
  <a href="/jobs">Careers</a>
  <a href="/contact">Contact Us</a>
</nav>

In the preceding code, with its display property set to flex, the nav element is turned into a flex container, and its child links are all flex items. These links are still hyperlinks, but they’re also flex items in terms of their presentation. They are no longer inline-level boxes: rather, they participate in their container’s flex formatting context. Therefore, the whitespace between the a elements is completely ignored in layout terms. If you’ve ever used HTML comments to suppress the space between links, list items, or other elements, you know why this is a big deal.

在前面的代码中,其 display 属性设置为 flex,该 nav 元素被转换为 flex 容器,并且其子链接均为 flex 子元素。这些链接仍然是超链接,但就其表示而言,它们也是 flex 子元素。它们不再是内联级别的框:相反,它们参与了容器的 flex 格式化上下文。因此,就布局而言,a 元素之间的空白将被完全忽略。如果您曾经使用 HTML 注释来隐藏链接,列表项或其他元素之间的空格,那么您就会知道为什么这样做很重要。

So let’s add some more CSS to the links:

因此,让我们向链接添加更多 CSS:

nav {
  display: flex;
  border-bottom: 1px solid #ccc;
}
a {
  margin: 0 5px;
  padding: 5px 15px;
  border-radius: 3px 3px 0 0;
  background-color: #ddaa00;
  text-decoration: none;
  color: #ffffff;
}
a:hover,
a:focus,
a:active {
  background-color: #ffcc22;
  color: black;
}

With that CSS, we’ve got ourselves a simple tabbed navigation bar, as shown in Figure 12-2.

使用该 CSS,我们获得了一个简单的选项卡式导航栏,如图 12-2 所示。

A simple tabbed navigation

That might not seem like much right now, because there’s nothing here you couldn’t have done with old-school CSS. Just wait: it gets better.

现在这似乎还不算什么,因为这里没有什么是用老式 CSS 不能完成的。稍等:它会变得更好。

By design, flexbox is direction-agnostic. This is different from block or inline layouts, which are defined to be vertically and horizontally biased, respectively. The web was originally designed for the creation of pages on monitors, and assumed a horizontal constraint with infinite vertical scroll. This vertically-biased layout is insufficient for modern applications that change orientation, grow, and shrink, depending on the user agent and the direction of the viewport, and change writing modes depending on the language.

根据设计,flexbox 与方向无关。这与块或行内布局不同,后者分别定义为垂直和水平方向布局。该网络最初是为在监视器上创建页面而设计的,并且假定无限垂直滚动的水平约束。对于根据用户代理和视口的方向更改方向,增大和缩小以及根据语言更改书写方式的现代应用程序来说,这种垂直偏向的布局是不够的。

For years we joked about the challenges of vertical centering and multiple column layout. Some layouts were no laughing matter, like ensuring equal heights in a grid of multiple side-by-side boxes, with buttons or “more” links fixed to the bottom of each box, and with the button’s content neatly vertically centered, as shown in Figure 12-3; or, ensuring boxes in a varied content gallery were all the same height, while the top gallery row of boxes was neatly lined up with the boxes in subsequent rows, as shown in Figure 12-4; or, keeping the pieces of a single button all neatly lined up, as shown in Figure 12-5. Flexbox makes all of these challenges fairly simple.

多年来,我们开玩笑说垂直居中和多列布局面临挑战。某些布局绝非易事,例如确保在多个并排的框的网格中具有相等的高度,将按钮或“更多”链接固定在每个框的底部,并且将按钮的内容整齐地垂直居中,如图 12-3 所示; 或者,确保内容库中所有框的高度都相同,而顶层库中的框与后续行中的框整齐地对齐,如图 12-4 所示;或者,使单个按钮的各个部分整齐地排列,如图 12-5 所示。Flexbox 使所有这些挑战变得相当简单。

Power grid layout with flexbox, with buttons aligned on the bottom

Gallery with columns neatly lined up using flexbox

Widget with several components, all vertically centered

Before floated layouts, it was common to see tables used for layout. Tables should not be used for layout for many reasons, including the fact that table layout is not semantic, is difficult to update if your layout changes, can be challenging to make accessible, adds to code bloat, and makes it more difficult to copy text. That said, tables are appropriate for tabular data.

The classic “Holy Grail” layout, with a header, three equal-height columns of varying flexibility, and a footer, could be solved in many ways—none of them simple—until we had flexbox. Here’s an example of the HTML that might represent such a layout:

直到我们有了 flexbox 为止,可以通过许多方法(没有一个简单)解决经典的“圣杯”布局,它具有标题,三个可变高度的等高列和页脚。这是一个可能表示这种布局的 HTML 示例:

<header>Header</header>
<main>
  <nav>Links</nav>
  <aside>Aside content</aside>
  <article>Document content</article>
</main>
<footer>Footer</footer>

Most designs call for columns of equal heights, but adding backgrounds to the aside, article, and nav would amplify that they have different heights. To provide for the appearance of equal-height columns, we often added a faux background to the parent based on the column widths declared in our CSS, used massive padding and negative margins, inserted cleared generated content, and other tricks.

大多数设计要求相等的高度的列,但增加背景的 aside,article 以及 nav 会放大,他们有不同的高度。为了提供等高列的外观,我们经常根据 CSS 中声明的列宽向父级添加虚假背景,使用大量填充和负边距,插入清除的生成内容,以及其他技巧。

With all of these tricks cluttering up our CSS (and somethings our HTML), the old layout methods could be downright confusing. Many people started using YUI grids, Bootstrap, Foundation, 960 grid, and other CSS layout libraries just to bring a little bit of sanity to their development process. Hopefully, this book will help you realize you no longer need a CSS framework to keep your layout styles sane.

由于所有这些技巧使我们的 CSS(以及我们的 HTML)杂乱无章,旧的布局方法可能会造成混乱。许多人开始使用 YUI 网格,Bootstrap,Foundation,960 网格和其他 CSS 布局库,只是为了使他们的开发过程更完整健全。希望这本书可以帮助您认识到不再需要 CSS 框架来保持布局样式的健全。

As this chapter progresses, remember that flexbox was designed for a specific type of layout, that of single-dimensional content distribution. In other words, it works best at arranging information along a single dimension, or axis. While you can create grid-like layouts (two-dimensional alignment) with flexbox, this is not its intended purpose. If you find yourself pining for two-dimensional layout capabilities, see Chapter 13, Grid Layout.

随着本章的进行,请记住 flexbox 是为特定类型的布局(即一维内容分发)设计的。换句话说,它最适合沿单个维度或轴排列信息。虽然可以使用 flexbox 创建类似网格的布局(二维对齐),但这并不是其预期目的。如果您发现自己想使用二维布局功能,请参阅第 13 章,网格布局。

12.2 Flex Containers

The first important notion to fully understand is that of flex container, also known as container box. The element on which display: flex or display: inline-flex is applied becomes the flex container and generates a flex formatting context for its child elements.

要完全理解的第一个重要概念是 flex 容器,也称为 container 盒子。应用了 display: flex 或的元素 display: inline-flex 成为 flex 容器,并为其子元素生成 flex 格式化上下文。

These children are flex items, whether they are DOM nodes, text nodes, or generated content. Absolutely positioned children of flex containers are also flex items, but each is sized and positioned as though it is the only flex item in the flex container. We’ll first learn all about the CSS properties that apply to the flex container, including several properties impacting the layout of flex items. Flex items themselves are a major concept you need to understand, and will be covered in full later on, in “Flex Items” on page 609.

这些子元素是 flex 项,无论它们是 DOM 节点,文本节点还是生成的内容。flex 容器的绝对定位子元素也是 flex 子元素,但是每个子元素的大小和位置都好像是 flex 容器中唯一的 flex 子元素。我们将首先了解适用于 flex 容器的 CSS 属性,包括一些影响 flex 子元素布局的属性。flex 子元素本身是您需要了解的一个主要概念,稍后将在第 609 页的“flex 子元素”中全面介绍。

The display property examples in Figure 12-1 show three flex items side by side, going from left to right, on one line. With a few additional property value declarations, we can center the items, align them to the bottom of the container, rearrange their order of appearance, or lay them out from left to right or from top to bottom. We can even make them span a few lines.

图 12-1 中的 display 属性示例在一行上从左到右并排显示了三个 flex 子元素。通过一些附加的属性值声明,我们可以使子元素居中,将它们与容器的底部对齐,重新排列其外观顺序,或从左至右或从上至下进行布局。我们甚至可以使它们跨越几行。

Sometimes we’ll have one flex item, sometimes we’ll have dozens. Sometimes we’ll know how many children a node will have, and sometimes the number of children will not be under our control. We might know the number of items, but not know the width of the container. We should have robust CSS that can handle our layouts when we don’t know how many flex items we’ll have or how wide the flex container will be (think responsive). Fortunately, flexbox makes all of that much easier than it sounds, and it does so with just a handful of new properties.

有时我们会有一个 flex 子元素,有时我们会有几十个。有时我们会知道一个节点有多少个子元素,有时子元素的数量将不受我们的控制。我们可能知道项目的数量,但不知道容器的宽度。当我们不知道会有多少个 flex 子元素或 flex 容器有多宽时(考虑响应),我们应该有健壮的 CSS 来处理我们的布局。幸运的是,flexbox 使得这一切比听起来容易得多,并且只需几个新属性即可做到。

12.2.1 The flex-direction Property

If you want your layout to go from top to bottom, left to right, right to left, or even bottom to top, you can use flex-direction to control the main axis along which the flex items get laid out.

如果要使布局从上到下,从左到右,从右到左,甚至从下到上,则可以使用 flex-direction 来控制主轴,flex 子元素沿主轴放置。

The flex-direction property specifies how flex items are placed in the flex container. It defines the main axis of a flex container, which is the primary axis along which flex items are laid out (see “Understanding axes” on page 579 for more details).

该 flex-direction 属性指定将 flex 子元素放置在 flex 容器中的方式。它定义了 flex 容器的主轴,该主轴是 flex 子元素沿其布置的主轴(有关更多详细信息,请参见第 579 页的“理解轴”)。

Assume the following basic markup structure:

假定以下基本标记结构:

<ol>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ol>

Figure 12-6 shows how that simple list would be arranged by each of the four values of flex-direction applied, assuming a left-to-right language.

图 12-6 显示了假设使用从左到右的语言,如何通过flex-direction的四个值中的每个来排列该简单列表。

The four values of the flex-direction property

The default value, row, doesn’t look all that different than a bunch of inline or floated elements. This is misleading, for reasons we’ll soon see, but notice how the other flex-direction values affect the arrangement of the list items.

默认值 row 看起来与一堆内联或浮动元素没有什么不同。这具有误导性,原因我们很快就可以看到。但是请注意其他 flex-direction 值如何影响列表项的排列。

For example, you can reverse this layout of the items with flex-direction: row-reverse. The flex items are laid out from top to bottom when flex-direction: column is set, and from bottom to top if flex-direction: column-reverse is set, as shown in Figure 12-6.

例如,您可以使用反转项目的这种布局 flex-direction: row-reverse。如果 flex-direction: column ,flex 项目从上到下布置。若flex-direction: column-reverse则从下到上布置 ,如图 12-6 所示。

We specified left-to-right languages, because the direction of the main axis for row—the direction the flex items are laid out in—is the direction of the current writing mode. We’ll discuss how writing modes affect flex direction and layout in a bit.

我们指定了从左到右的语言,因为主轴 row 的方向(即 flex 子元素的放置方向)是当前书写模式的方向。我们将讨论写入模式如何影响 flex 方向和布局。

Do not use flex-direction to change the layout for right-to-left languages. Rather, use the dir attribute, or the writing-mode CSS property described in “Setting Writing Modes” on page 249, which enables switching between horizontal and vertical, to indicate the language direction. To learn more about language direction and flex box, see “Other Writing Directions” on page 574, later in the chapter, for more details.

In languages like English, the column value sets the flex container’s main axis to be the same orientation as the block axis of the current writing mode. This is the vertical axis in horizontal writing modes like English, and the horizontal axis in vertical writing modes like traditional Japanese.

在英语之类的语言中,该 column 值将 flex 容器的主轴设置为与当前书写模式的块轴相同的方向。这是水平书写模式(例如英语)中的垂直轴,也是垂直书写模式(例如传统日语)中的水平轴。

Thus, when declaring a column direction, the flex items are displayed in the same order as declared in the source document, but from top to bottom instead of left to right, so the flex items are laid out one on top of the next instead of side by side. Consider:

因此,在声明 一个 column 方向时,flex 子元素的显示顺序与源文档中声明的顺序相同,但从上到下而不是从左到右显示,因此,flex 子元素在下一个排列,而不是并排。考虑:

nav {
  display: flex;
  flex-direction: column;
  border-right: 1px solid #ccc;
}
a {
  margin: 5px;
  padding: 5px 15px;
  border-radius: 3px;
  background-color: #ccc;
  text-decoration: none;
  color: black;
}
a:hover,
a:focus,
a:active {
  background-color: #aaa;
  text-decoration: underline;
}

Using markup like that, by simply changing a few CSS properties, we can create a nice sidebar-style navigation for the list of links we saw earlier as a horizontal row of tabs. For the new layout, we merely change the flex-direction from the default value row to column, move the border from the bottom to the right, and change the colors, border-radius, and margin values, with the result seen in Figure 12-7.

使用这样的标记,只需更改一些 CSS 属性,我们就可以为我们之前看到的作为选项卡的水平行链接列表创建一个漂亮的边栏式导航。对于新布局,我们只需将其 flex-direction 从默认值 row 更改为 column,将边框从底部移至右侧,然后更改颜色,边框半径,和外边距,结果如图 12-7 所示。

Changing the flex direction can completely change the layout

The column-reverse value is similar to column, except the main axis is reversed, with main start being at the bottom, and main end being at the top of the vertical main axis, going upward, as shown in Figure 12-6. The reverse values only change the appearance. The speech order and tab order remains the same as the underlying markup.

column-reverse 值与 column值类似,不同之处在于主轴反转,主轴起点在垂直主轴的底部,主轴终点在垂直主轴的顶部,如图 12-6 所示。反向值只会更改外观。语音顺序和制表符顺序与基础标记相同。

What we’ve learned so far is super powerful and makes layout a breeze. If we include the navigation within a full document, we can see how simple layout can be with just a few flexbox property declarations.

到目前为止,我们所学的内容非常强大,并且使布局变得轻而易举。如果将导航包含在完整的文档中,则可以看到仅用几个 flexbox 属性声明即可实现简单的布局。

Let’s expand a little on our preceding HTML example, and include the navigation as a component within a home page:

让我们在前面的 HTML 示例中进行一些扩展,并将导航作为组件包含在主页中:

<body>
  <header>
    <h1>My Page's title!</h1>
  </header>
  <nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
    <a href="/blog">Blog</a>
    <a href="/jobs">Careers</a>
    <a href="/contact">Contact Us</a>
  </nav>
  <main>
    <article>
      <img alt="" src="img1.jpg" />
      <p>This is some awesome content that is on the page.</p>
      <button>Go Somewhere</button>
    </article>
    <article>
      <img alt="" src="img2.jpg" />
      <p>This is more content than the previous box, but less than the next.</p>
      <button>Click Me</button>
    </article>
    <article>
      <img alt="" src="img3.jpg" />
      <p>
        We have lots of content here to show that content can grow, and
        everything can be the same size if you use flexbox.
      </p>
      <button>Do Something</button>
    </article>
  </main>
  <footer>Copyright &#169; 2018</footer>
</body>

By simply adding a few lines of CSS, we’ve got a nicely laid out home page, as shown in Figure 12-8:

通过简单地添加几行 CSS,我们就得到了一个布局良好的主页,如图 12-8 所示:

* {
  outline: 1px #ccc solid;
  margin: 10px;
  padding: 10px;
}
body,
nav,
main,
article {
  display: flex;
}
body,
article {
  flex-direction: column;
}

Home page layout using flex-direction: row and column

Yes, elements can be both flex items while being flex containers, as we see with the navigation, main, and articles in this case. The body and articles have column set as their flex directions, and we let nav and main default to row. Just two lines of CSS!

是的,元素既可以是 flex 容器,又可以是 flex 子元素,正如我们在本例中看到的导航,主要内容和文章。 正文和文章的 flex 方向设置为column,我们将 nav 和 main 默认设置为row。 只需两行 CSS!

To be clear, there’s more styling at work in Figure 12-8. Some border, margin, and padding were applied to all the elements, so you can visually differentiate the flex items for the sake of learning (I wouldn’t put this less-than-attractive site in production). Otherwise, all we’ve done is simply declare the body, navigation, main, and articles as flex containers, making all the navigation, links, main, article, images, paragraphs, and buttons flex items.

需要说明的是,图 12-8 中有更多的样式在起作用。所有元素都应用了一些边框、外边距和内边距,因此为了便于学习,您可以在视觉上区分 flex 子元素(我不会将这个不太有吸引力的站点放到生产环境中)。否则,我们所做的只是将 body、navigation、main 和 articles 声明为 flex 容器,使所有导航、链接、main、article、图像、段落和按钮成为 flex 子元素。

12.2.2 Other Writing Directions

If you’re creating websites in English, or another left-to-right (LTR) language, you likely want the flex items to be laid out from left to right, and from top to bottom. Defaulting or setting row will do that. If you’re writing in Arabic, or another right-to left language, you likely want the flex items to be laid out from right to left (RTL), and from top to bottom. Defaulting or setting row will do that, too.

如果您正在用英语或另一种从左到右(LTR)语言创建网站,那么您可能希望从左到右以及从上到下地布置 flex 子元素。 默认设置或设置行都会做到这一点。 如果您使用阿拉伯语或另一种从右到左的语言编写,您可能希望将 flex 项从右到左(RTL)并从上到下排列。 默认或设置行也会这样做。

flex-direction: row arranges the flex items in the same direction as the text direction, also known as the writing mode, whether it’s the language is RTL or LTR. While most websites are presented in left-to-right languages, some sites are in right-to-left languages, and yet others are top to bottom. With flexbox, you can define single layout. When you change the writing mode, flexbox takes care of changing the flex direction for you.

flex-direction:row安排 flex 子元素和文本方向相同的方向,也称为写作模式,无论是语言是 RTL 或 LTR。虽然大多数网站以从左到右的语言来呈现,一些网站在从右到左的语言,然而其他情况则从上到下。使用 flexbox,您可以定义单个布局。当您更改写入模式时,flexbox 将负责为您更改 flex 方向。

The writing mode is set by the writing-mode, direction, and text-orientation properties, or by the dir attribute in HTML. (These are covered in Chapter 6.) When the writing mode is right to left, the direction of the main axis—and therefore the flex items within the flex container—will go from right to left when the flex-direction is row. This is illustrated in Figure 12-9.

写入模式是由写入模式,方向和文本方向属性或 HTML 中的 dir 属性设置的。 (这些内容将在第 6 章中介绍。)当书写模式从右到左时,当 flex-direction 为行时,主轴的方向(以及因此 flex 容器中的 flex 项目)将从右到左。 如图 12-9 所示。

The four values of the flex-direction property when writing direction is right to left

If the CSS direction value is different from the dir attribute value on an element, the CSS property value takes precedence over the HTML attribute. The specifications strongly recommend using the HTML attribute rather than the CSS property.

There are vertically written languages, including Bopomofo, Egyptian hieroglyphs, Hiragana, Katakana, Han, Hangul, Meroitic cursive and hieroglyphs, Mongolian, Ogham, Old Turkic, Phags Pa, Yi, and sometimes Japanese. These languages are only vertical when a vertical writing mode is specified. If one isn’t, then all of those languages are horizontal. If a vertical writing mode is specified, then all of the content is vertical, whether one of the listed vertically written languages or even English.

有垂直书写的语言,包括波波摩伏语、埃及象形文字、平假名、片假名、汉语、韩语、麦罗提克草书和象形文字、蒙古语、奥格罕文、古突厥语、帕斯帕语、伊语,有时还有日语。 只有在指定垂直书写模式时,这些语言才是垂直的。 如果没有,那么所有的语言都是水平的。 如果指定了垂直书写模式,那么所有的内容都是垂直的,无论是列出的垂直书写语言之一,还是英语。

For top-to-bottom languages, writing-mode: horizontal-tb is in effect, the main axis is rotated 90 degrees clockwise from the default left to right, so flex-direction: row goes from top to bottom and flex-direction: column proceeds from right to left. The effects the various flex-direction values have on the following markup is shown in Figure 12-10:

对于自顶向下的语言,实际上是writing-mode: horizontal-tb生效,主轴从默认的左到右顺时针旋转 90 度,所以 flex-direction: row是从上到下,flex-direction: column从右到左。 图 12-10 显示了各种 flex-direction 值对以下标记的影响:

<ol lang="jp">
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ol>

The four values of flex-direction property when writing mode is horizontal-tb

That’s right: the rows are vertical, and columns are horizontal. Not only that, but the basic column direction is right to left, whereas column-reverse runs left to right. That’s what comes of applying these values to a top-to-bottom, right-to-left language like we see here.

没错: 行是垂直的,列是水平的。 不仅如此,基本的column方向是从右到左,而 column-reverse 是从左到右排列的。 这就是将这些值应用于从上到下、从右到左的语言的结果,就像我们在这里看到的。

All right, we’ve seen various ways flex direction and writing modes interact. But so far, all the examples have shown a single row or column of flex items. What happens when the flex items’ main dimension (their combined widths for row or combined heights for column) don’t fit within the flex container? We can either have them overflow, or we can allow them to wrap onto additional flex lines. We’ll later learn how to make the flex items shrink to fit too.

好了,我们已经看到了多种方式来调节方向和书写模式之间的交互。但是到目前为止,所有的示例都显示了一行或一列的 flex 子元素。当 flex 项的主维度(行的组合宽度或列的组合高度)不适合于 flex 容器时会发生什么情况?我们可以让它们溢出,或者我们可以让它们折行。 稍后我们将学习如何使 flex 子元素缩小以适应。

12.2.3 Wrapping Flex Lines

If the flex items don’t all fit into the main axis of the flex container, by default the flex items will not wrap, nor will they necessarily resize. Rather, the flex items may shrink if allowed to do so via the flex item’s flex property (see “Growth Factors and the flex Property” on page 619) and/or the flex items may overflow the bounding container box.

如果 flex 子元素不能全部放入 flex 容器的主轴,那么默认情况下 flex 子元素不会换行,也不一定会调整大小。 相反,如果允许通过 flex 子元素的 flex 属性(请参阅第 619 页的“ Growth Factors and the flex Property”)收缩 flex 子元素,或者 flex 项可能会溢出 flex 容器框。

You can affect this behavior. The flex-wrap property can be set on the container to allow the flex items to wrap onto multiple flex lines—rows or columns of flex items—instead of having flex items overflow the container or shrink as they remain on one line.

你可以影响这种行为。 可以在容器上设置 flex-wrap 属性,以便让 flex 子元素排列在多个 flex 行或列上,而不是让 flex 子元素在一行上溢出或者缩小。

The flex-wrap property controls whether the flex container is limited to being a single-line container or is allowed to become multiline if needed. When the flex-wrap property is set to allow for multiple flex lines, whether the value of wrap or wrap-reverse is set determines whether any additional lines appear either before or after the original line of flex items.

Flex-wrap 属性控制 flex 容器是仅限于单行容器,还是允许在需要时变成多行容器。 当 flex-wrap 属性设置为允许多个 flex 行时,是否设置 wrap 值或 wrap-reverse 值将确定是否有任何附加行出现在原始 flex 项行之前或之后。

By default, no matter how many flex items there are, all the flex items are drawn on a single line. This is often not what we want. That’s where flex-wrap comes into play. The wrap and wrap-reverse values allow the flex items to wrap onto additional flex lines when the constraints of the parent flex container are reached.

默认情况下,不管有多少个 flex 子元素 ,所有的 flex 子元素都绘制在一行上。 这往往不是我们想要的。 这就是 flex-wrap 发挥作用的地方。 wrapwrap-reverse 值允许 flex 子元素在达到父 flex 容器的边界时折到附加的 flex 行上。

Figure 12-11 demonstrates the three values of flex-wrap property when the flex-direction value is row (and the language is LTR). Where these examples show two flex lines, the second line and subsequent flex lines are added in the direction of the cross axis (in this case, the vertical axis).

图 12-11 演示了当 flex-direction 值为row(语言为 LTR)时, flex-wrap 属性的三个值。 在这些示例中显示两行的情况下,第二行和随后的行是沿着交叉轴(在本例中是垂直轴)的方向添加的。

Generally for wrap, the cross axis goes from top to bottom for row and row-reverse and the horizontal direction of the language for column and column-reverse. The wrap-reverse value is similar to wrap, except that additional lines are added before the initial line rather than after it.

通常对于换行,横轴从上到下表示行和行反向,而语言的水平方向表示列和列反向。wrap-reverse值与wrap相似,不同之处在于在初始行之前而不是在初始行之后添加了其他行。

When set to wrap-reverse, the cross axis direction is reversed: subsequent lines are drawn on top in the case of row and row-reverse and to the left of the previous column in the case of column and column-reverse. Similarly, in right-to-left languages, row wrap-reverse and row-reverse wrap-reverse, new lines will also be added on top, but for column wrap-reverse and column-reverse wrap-reverse newlines will be added to the right—the opposite of the language direction or writing mode, the direction of the inverted cross axis.

当设置为 wrap-reverse 时,交叉轴方向是颠倒的: 在 rowrow-reverse 情况下,后续的行在顶部绘制,在 columncolumn-reverse 情况下,后续的行在前一列的左侧绘制。 同样,在从右到左的语言中,row wrap-reverserow-reverse wrap-reverse也会在顶部添加新的行,但是对于 column wrap-reversecolumn-reverse wrap-reverse则会在右侧添加新的行ーー与语言方向或写入方式相反的方向,即倒置的交叉轴的方向。

We’ll talk about axes in just a moment, but first, let’s talk about the shorthand that bring flex direction and wrapping together.

稍后我们将讨论轴,但首先,让我们讨论将 flex 方向和折行结合在一起的简写。

The three values of the flex-wrap property in a row-oriented flow

12.2.4 Defining Flexible Flows

The flex-flow property lets you define the directions of the main and cross axes, and whether the flex items can wrap to more than one line if needed.

flex-flow属性允许您定义主轴和交叉轴的方向,以及在需要时,flex 项是否可以换行成多行。

The flex-flow shorthand property sets the flex-direction and flex-wrap properties to define the flex container’s wrapping and main and cross axes.

flex-flow 简写属性设置 flex-directionflex-wrap 属性,以定义 flex 容器的折行、主轴和交叉轴。

As long as display is set to flex or inline-flex, omitting flex-flow, flex-direction, and flex-wrap is the same as declaring any of the following three, all of which have the result shown in Figure 12-12:

只要 display 设置为 flexinline-flex,省略 flex-flowflex-directionflex-wrap 等同于声明以下三个中的任何一个,所有这三个的结果如图 12-12 所示:

flex-flow: row;
flex-flow: nowrap;
flex-flow: row nowrap;

A row-oriented unwrapped flex flow

In left-to-right writing modes, declaring any of the property values just listed, or omitting the flex-flow property altogether, will create a flex container with a horizontal main axis that doesn’t wrap. Figure 12-12 illustrates flex items distributed along the horizontal axis, on one line, overflowing the container that’s 500 pixels wide.

在从左到右的写入模式中,声明刚才列出的任何属性值,或者完全忽略 flex-flow 属性,将创建一个具有不折行的水平主轴的 flex 容器。 图 12-12 说明了沿水平轴分布的 flex 子元素,在一行上,溢出了这个容器 500 像素宽。

If instead we wanted a reverse-column-oriented flow with wrapping, either of these would suffice:

相反,如果我们想要一个折行的反向列方向的流,以下任何一个都可以:

flex-flow: column-reverse wrap;
flex-flow: wrap column-reverse;

In an LTR language, that would cause the flex items to flow from bottom to top, starting at the left side, and wrap to new columns in the rightward direction. In a vertical writing mode like Japanese, the columns would be horizontal, flowing from left to right, and wrap top to bottom.

在 LTR 语言中,这将导致 flex 项从底部到顶部流动,从左侧开始,并向右换行到新列。在像日语这样的垂直书写模式中,列应该是水平的,从左到右流动,从上到下换行。

We’ve kept using terms like “main axis” and “cross axis” without really delving into what they mean. It’s time to clarify all that.

我们一直使用“主轴”和“交叉轴”这样的术语,但并没有真正深入研究它们的含义。 是时候澄清这一切了。

Understanding axes

first: flex items are laid out along the main axis. flex lines are added in the direction of the cross axis.

第一:flex 子元素沿主轴布置。flex 行沿交叉轴方向添加。

Up until we introduced flex-wrap, all the examples had a single line of flex items. That single line of flex items involved laying out the flex items along the main axis, in the main direction, from main-start to main-end. Depending of the flex-direction property, those flex items were laid out side by side, top to bottom or bottom to top, in one row or column along the direction of the main axis. These are illustrated in detail in Figure 12-13.

在我们引入flex-wrap之前,所有示例都只有一行 flex 项目。flex 子元素的单行沿主轴在主要方向上从主轴起点到主轴终点布置 flex 子元素。根据flex-direction属性的不同,这些 flex 子元素沿着主轴方向在一行或一列中并排,从上到下或从下到上排列。这些在图 12-13 中详细说明。

As you can see, there are a lot of terms used in that figure, many of them new to the discussion. Here are some quick definitions:

如您所见,该图中使用了许多术语,其中许多是新讨论中的术语。以下是一些快速定义:

main axis

The axis along which content flows. In flexbox, this is the direction in which flex items are flowed.

主轴:内容沿其流动的轴。在 flexbox 中,这是 flex 子元素的流向。

main size

The total length of the content along the main axis.

内容沿主轴的总长度。

main start

The end of the main axis from which content begins to flow.

主轴中内容流出的一端。

main end

The end of the main axis toward which content flows, opposite the main start.

主轴中内容流向的一端,与主轴起点相反。

cross axis

The axis along which blocks are stacked. In flexbox, this is the direction in which new lines of flex items are placed, if flex wrapping is permitted.

交叉轴:块堆叠的轴。在 flexbox 中,这是放置 flex 项目的新行的方向(如果允许 flex 折行)。

cross size

The total length of the content along the cross axis.

内容沿着交叉轴的总长度。

cross start

The edge of the cross axis where blocks begin to be stacked.

块开始堆积的交叉轴边缘。

cross end

The opposite edge of the cross axis from the cross start.

交叉轴的另一端,与交叉轴起点相反。

Where each of these are placed depends on the combination of the flex direction, the flex wrapping, and the writing mode. Charting all the combinations for every writing mode would get difficult, so let’s examine what the mean for left-to-right languages. Table 12-1 breaks it down for us.

这些文件的放置位置取决于 flex 方向,是否折行和书写方式的组合。绘制每种书写模式的所有组合图表会很困难,因此让我们研究一下从左到右语言的含义。表 12-1 为我们细分了它。

It’s important to understand things get reversed when writing direction is reversed. To make explaining (and understanding) flex layout much simpler, we’re going to base the rest of the explanations and examples in this chapter on left-to-right writing mode, but will include how writing mode impacts the flex properties and features discussed.

Main- and cross-axis term placements in left-to-right writing modes

// T12-1

When thinking about flex-direction, we know the flex items are going to start being laid out along the main axis of the flex container, starting from the main-start. When the flex-wrap property is used to allow the container to wrap if the flex items don’t fit onto one line, the cross directions determine the direction of additional lines in multiline flex containers.

当考虑flex-direction时,我们知道 flex 子元素将从 flex 容器的主轴开始,从主轴起点开始排列。当使用flex wrap属性允许容器在 flex 子元素不适合一行时进行折行时,cross方向确定多行 flex 容器中其他行的方向。

As we learned in the flex-flow shorthand overview in “Wrapping Flex Lines” on page 576, flex items can be set to wrap to additional lines if they would otherwise overflow the main size of the container. While the laying out of the flex items on each flex line is done in the main direction, going from main-start to main-end, the wrapping to additional lines is done along the cross direction, from cross-start to crossend.

正如我们在第 576 页上的“Wrapping Flex Lines”中的 flex-flow概述中所了解的,可以将 flex 子元素设置为换行,否则它们会溢出容器。在从主轴起点到主轴终点的主方向上布置 flex 子元素的同时,从交叉轴起点到交叉轴终点的方向折到其他行。

The cross axis is always perpendicular to the main axis. As we see in Figure 12-14, when we have horizontal rows of flex items, the cross axis is vertical. Flex lines are added in the direction of the cross axis. In these examples, with flex-flow: row wrap and flex-flow: row-reverse wrap set on horizontal languages, new flex lines are added below preceding flex lines.

交叉轴始终垂直于主轴。如图 12-14 所示,当我们有水平行的 flex 子元素时,交叉轴是垂直的。其它行沿交叉轴方向添加。在这些示例中,在水平语言上设置了 flex-flow: row wrapflex-flow: row-reverse wrap 后,新的行会添加到前面的行下方。

The cross size is the opposite of main size, being height for row and row-reverse and width for column and column-reverse in both RTL and LTR languages (though not top-to-bottom languages). Flex lines are filled with items and placed into the container, with the first line added at the cross-start side of the flex container and going toward the cross-end side.

交叉轴大小与主轴大小相对,在 RTL 和 LTR 语言中,“ row”和“ row-reverse”的高度分别为“ column”和“ column-reverse”的高度(尽管不是自上而下的语言) 。 Flex 行充满了 flex 子元素并放置在容器中,第一行添加到 Flex 容器的交叉起点侧,并朝向交叉终点侧。

Stacking of row-oriented flex lines

The wrap-reverse value inverts the direction of the cross axis. Normally for flex-direction of row and row-reverse, the cross axis goes from top to bottom, with the cross-start on top and cross-end on the bottom. When flex-wrap is wrap-reverse, the cross-start and cross-end directions are swapped, with the cross-start on the bottom, cross-end on top, and the cross axis going from bottom to top. Additional flex lines get added on top of, or above, the previous line.

“ wrap-reverse”值使交叉轴的方向反转。通常,对于“flex-direction”的“row”及“row-reverse”,交叉轴从上到下,交叉起点在顶部,交叉终点在底部。当“ flex-wrap”为“ wrap-reverse”时,交叉起点和交叉终点方向会互换,交叉起点在底部,交叉终点在顶部,交叉轴从底部到顶部。其他行将添加到前一行的上方。

If the flex-direction is set to column or column-reverse, by default the cross axis goes from left to right in left-to-right languages, with new flex lines being added to the right of previous lines. As shown in Figure 12-15, when flex-wrap is set to wrap-reverse, the cross axis is inverted, with cross-start being on the right, cross-end being on the left, the cross axis going from right to left, with additional flex lines being added to the left of the previously drawn line.

如果将“ flex-direction”设置为“ column”或“ column-reverse”,则默认情况下,在 LTR 的语言中交叉轴从左到右,新的行会添加到前一行的右侧。如图 12-15 所示,当“ flex-wrap”设置为“ wrap-reverse”时,交叉轴反转,交叉起点在右侧,交叉终点在左侧,交叉轴从右到左,并在先前绘制的行的左侧添加其他行。

align-items: flex-start and align-content: flex-start were added to the flex container in Figure 12-14 and Figure 12-15 to enunciate the height and directions of the flex lines. These properties are covered in the following sections.

Now that we have a better understanding of all these terms and dimensions, let’s get back to the flex-wrap property.

现在,我们对所有这些术语和维度有了更好的了解,让我们回到“ flex-wrap”属性。

Stacking of column-oriented flex lines

12.2.5 flex-wrap Continued

The default value of nowrap prevents wrapping, so the cross- directions just discussed aren’t relevant when there is no chance of a second flex line. When additional lines are possible—when flex-wrap is set to wrap or wrap-reverse—those lines will be added in the cross direction. The first line is placed at the cross-start, with additional lines being added on the cross-end side.

“ nowrap”的默认值可防止换行,因此,在没有第二行的情况下,刚刚讨论的“交叉”方向无关紧要。当可能有其他行时(将“ flex-wrap”设置为“ wrap”或“ wrap-reverse”时),这些行将沿交叉方向添加。第一行放置在交叉起点处,其他行添加在交叉终点。

You can invert the direction of the cross axis, adding new lines on top or to the left, of previous lines by including flex-wrap: wrap-reverse. In Figure 12-16, the last example is wrap-reverse. You’ll notice the new line starts at the main-start, but is added in the inverse direction of the cross axis set by the flex-direction property.

您可以通过添加flex-wrap:wrap-reverse来反转交叉轴的方向,在前一行的顶部或左侧添加新行。在图 12-16 中,最后一个示例是“ wrap-reverse”。您会注意到,新行从主轴起点开始,但沿由“ flex-direction”属性设置的交叉轴的反方向添加。

The three values of flex-wrap property in a column-oriented flow

In Figure 12-16, the same flex-wrap values are repeated, but with a flex-direction: column property value instead of row. In this case, the flex items are laid out along the vertical axis. Just as with the row-oriented flows, if wrapping is not enabled by the flex-wrap property—either because flex-wrap: nowrap is explicitly set on the container, or if the property is omitted and it defaults to nowrap—no new flex lines will be added even if that means the flex items are drawn beyond the bounding box of the flex container.

在图 12-16 中,重复相同的“ flex-wrap”值,但具有“ flex-direction:column”属性值而不是“ row”。在这种情况下,flex 子元素沿垂直轴布置。与面向行的流一样,如果 flex-wrap 属性没有启用换行,或者是因为在容器上显式设置了 flex-wrap:nowrap,或者省略了该属性,并且默认为nowrap-不会添加新的行,即使这意味着将 flex 子元素绘制到 flex 容器的边界框之外。

With column, just like with row, if the flex items don’t fit into the flex container and no wrapping is allowed, they’ll overflow the flex container, unless explicitly changed with min-width: 0 or similar, in which case they shrink to fit, though flex items will not shrink to smaller than their border, padding and margins combined.

row一样,使用column时,如果 flex 子元素不能放入 flex 容器并且不允许换行,它们将溢出 flex 容器,除非用min-width:0或类似的设置,在这种情况下,它们会缩小以适合其大小,但 flex 子元素不会缩小到小于其边框,内边距和外边距的组合。

When flex-flow: column wrap is set on a flex container, if there isn’t enough room for the flex items to fit into the first column, they’ll wrap onto new lines. The next flex item will be put on a new line in the cross-axis direction, which in this case is a vertical line (a column) to the right of the previous line, as can be observed in the flex-flow: column wrap example in Figure 12-16. In that particular case, the flex items have wrapped onto three lines. When we set flex-flow: column wrap-reverse, the same thing happens, except the cross-start and cross-end placements are swapped, so the initial column goes on the right and subsequent columns (flex lines) are added to the left of that initial column.

如果在 flex 容器上设置了“ flex-flow:column wrap”,则如果没有足够的空间容纳 flex 子元素到第一列中,它们将换行。下一个 flex 项目将在交叉轴方向上放置在新行上,在这种情况下,它是前一行右边的垂直行(一列),如在图 12-16 中的示例:“flex-flow:column wrap”。在那种特定情况下,flex 子元素已折到三行上。当我们设置“ flex-flow:column-reverse”时,发生了相同的事情,交换了交叉起始和交叉末端的位置,因此初始列在右边,随后的列(flex lines)被添加到该初始列的左侧。

As you can see, flex-direction and flex-wrap have great impact on your layout and on each other. Because it’s generally important to set both if you’re going to set either, we’re provided with the flex-flow property, which the specification strongly recommends we use.

如您所见,“ flex-direction”和“ flex-wrap”对您的布局以及彼此之间都有很大的影响。因为通常两者都设置很重要(如果您要设置两者之一),所以我们提供了“ flex-flow”属性,规范强烈建议我们使用此属性。

12.3 安排 flex 子元素 Arranging Flex Items

In our examples thus far, we’ve skated past the precise arrangement of flex items within each line, and how that’s determined. It might seem intuitive that a row fills in horizontally, but why should all the items huddle toward the main-start edge? Why not have them grow to fill all available space, or distribute themsleves throughout the line?

到目前为止,在我们的示例中,我了解了 flex 子元素在每行中的精确排列以及如何确定。他们在一行的水平填充似乎很直观,但是为什么所有子元素都挤向主起点边缘?为什么不让它们增长以填满所有可用空间,或在整个行上分配它们?

For an example of what we’re talking about here, check out Figure 12-17. Notice the extra space on the top left. In this bottom-to-top, right-to-left flow, new flex items get placed above of the previous ones, with new wrap lines being placed to the left of each previously filled line.

有关我们在此处讨论的示例,请查看图 12-17。请注意左上方的多余空间。在从下到上,从右到左的流中,新的 flex 子元素被放置在先前的 flex 子元素之上,而新的行被放置在前面每个行的左侧。

Empty space will be in the direction of main-end and cross-end

By default, no matter the values of flex-flow, empty space beyond the flex items in a flex container will be in the direction of main-end and cross-end…but there are properties that allow us to alter that.

默认情况下,无论`flex-flow'的值如何,flex 容器中 flex 子元素之外的空白空间都将朝向主端和交叉端的方向……但是有些属性允许我们对其进行更改。

12.4 Flex 容器 Flex Container

Thus far in our examples, when the flex items did not fill the flex container, the flex items were all grouped toward the main-start on the main axis. Flex items can be flush against the main-end instead, centered, or even spaced out evenly across the main axis.

到目前为止,在我们的示例中,当 flex 子元素未填满 flex 容器时,所有 flex 子元素都从主轴起点沿主轴排列。flex 子元素可以与主轴终点对齐,或者居中,甚至可以在主轴上均匀分布。

The flex layout specification provides us with flex container properties to control the distribution of space: in addition to display and flex-flow, the CSS Flexible Box Layout Module Level 1 properties applied to flex containers include the justify-content, align-content, and align-items properties.

flex 布局规范为我们提供了 flex 容器属性来控制空间的分布:除了“ display”和“ flex-flow”外,应用于 flex 容器的 CSS flex 盒子布局模块级别 1 属性还包括“ justify-content” ,“ align-content”和“ align-items”属性。

The justify-content property controls how flex items in a flex line are distributed along the main axis. The align-content defines how flex lines are distributed along the cross axis of the flex container. The align-items property defines how the flex items are distributed along the cross axis of each of those flex lines. Let’s start by arranging flex items within flex lines.

“ justify-content”属性控制行中的 flex 子元素如何沿主轴分布。 “ align-content”定义了 flex 子元素沿交叉轴分布的方式。 “ align-items”属性定义了每个 flex 子元素的行在交叉轴方向怎么摆放。让我们从在行内布置 flex 子元素开始。

12.5 Justifying Content

The justify-content property enables us to direct how flex items are distributed along the main axis of the flex container within each flex line. It is applied to the flex container, not the individual flex items.

“ justify-content”属性使我们能够指示 flex 子元素如何在每个行内沿 felx 容器的主轴分布。它应用于 flex 容器,而不是单个 flex 子元素。

The value of justify-content defines how space is distributed around, or in some cases between, the flex items inside a flex container. The effects of the six possible values are shown in Figure 12-18.

“ justify-content”的值定义了如何在 flex 容器内的 flex 子元素周围或在其之间分配空间。六个可能值的作用如图 12-18 所示。

The six values of the justify-content property

With flex-start, which is the default value, flex items are placed flush against main-start. With flex-end, flex items are justified toward main-end. center groups the items flush against each other, centered in the middle of the main-dimension along the main axis.

如果使用默认值flex-start,则将 flex 子元素与主轴起点对齐放置。使用flex-end,flex 子元素向主端终点对齐。 “居中”将子元素彼此对齐,并沿着主轴在主轴中心位置居中。

The space-between value puts the first flex item on a flex line flush with main-start and the last flex item in each flex line flush with main-end, and then puts an equal amount of space between every pair of adjacent flex items. space-around splits up the leftover space and then applies half of each portion to each flex item, as if there were non-collapsing margins of equal size around each item. Note that this means the space between any two flex items is twice that of the space between the first and last flex items and those at the main-start and main-end of the flex line. space-evenly takes the leftover space and splits it so that every gap is the same length. This means the spaces to the start and end edges of the main axis will be the same as the spaces placed between flex items.

“ space-between”值将第一个 flex 子元素放在与 main-start 齐平的行上,而最后一个 flex 子元素在每个与 main-end 齐平的行上,然后在每对相邻的 flex 子元素之间放置相等的空间。 'space-around'会分割剩余的空间,然后将每个部分的一半应用于每个 flex 子元素,就好像每个 flex 子元素周围都有大小相等的外边距一样。请注意,这意味着任何两个 flex 子元素之间的间隔是第一个和最后一个 flex 子元素在行的主轴起点和主轴终点处的间隔的两倍。 space-evenly占用剩余空间并分割剩余空间,以使每个间隙的长度相同。这意味着主轴起点和终点的间距将与 flex 子元素之间的间距相同。

justify-content affects more than just the placement within a flex line. If the items are not wrapped and overflow the flex line, then the value of justify-content influences how the flex items will overflow the flex container. This is illustrated in Figure 12-19.

justify-content不仅会影响一行中的位置。如果没有使 flex 子元素折行或是溢出,那么“ justify-content”的值会影响 flex 子元素如何溢出 flex 容器。如图 12-19 所示。

Overflow of a single-line flex container is affected by justify-content

Let’s take a look at the six values in slightly more detail.

让我们更详细地了解这六个值。

Setting justify-content: flex-start explicitly sets the default behavior of grouping the flex items toward main-start, placing the first flex item of each flex line flush against the main-start side. Each subsequent flex item then gets placed flush with the preceding flex item’s main-end side, until the end of the flex line is reached if wrapping is set. The location of the main-start side depends on the flex direction and writing mode, which is explained in “Understanding axes” on page 579. If there isn’t enough room for all the items, and nowrap is the default or expressly set, the items will overflow on the main-end edge, as shown in Figure 12-20.

设置justify-content:flex-start会显式设置默认的行为,即将 flex 子元素组合到主起点,将每行的第一个 flex 子元素与主轴起点齐平。然后,将每个后续的 flex 子元素与上一个 flex 子元素的主轴终点侧放置,直到设置了折行后到达行的末端。主轴起点的位置取决于 flex 的方向和书写方式,这在第 579 页的“理解轴”中进行了说明。如果没有足够的空间容纳所有子元素,则若默认或明确地使用“ nowrap”设置后,子元素将在主轴终点溢出,如图 12-20 所示。

Flex-start alignment

Setting justify-content: flex-end puts the last flex on a line flush against the main-end with each preceding flex item being placed flush with the subsequent item. In this case, if the items aren’t allowed to wrap, and if there isn’t enough room for all the items, the items will overflow on the main-start edge, as shown in Figure 12-21. Any extra space on a flex line will be on the main-start side.

设置justify-content:flex-end将最后一个 flex 子元素放在一行中与主轴终点齐平的位置,并且每个在前的 flex 子元素都与后续的子元素齐平。在这种情况下,如果不允许折行,并且如果没有足够的空间容纳所有 flex 子元素,则 flex 子元素将在主轴起点边缘溢出,如图 12-21 所示。一行上的任何多余空间都将位于主轴起点侧。

Flex-end alignment

Setting justify-content: center will pack all the items together, flush against each other at the center of each flex line instead of at the main-start or main-end. If there isn’t enough room for all the items and they aren’t allowed to wrap, the items will overflow evenly on both the main-start and main-end edges, as shown in the second example in Figure 12-22. If the flex items wrap onto multiple lines, each line will have centered flex items, with extra space being on the main-start and main-end edges.

设置'justify-content:center'会将所有子元素打包在一起,在每个行的中心而不是在主起点或主终点彼此齐平。如果没有足够的空间容纳所有子元素,并且不允许将他们折行,则这些子元素将在主边缘和主边均等地溢出,如图 12-22 中的第二个示例所示。如果 flex 子元素分布在多行上,则每行将具有居中的 flex 子元素,并在主起点和主终点边缘留有额外的空间。

Center alignment

Setting justify-content: space-between puts the first flex item flush with main-start and the last flex item on the line flush with main-end, and then puts an even amount of space around each flex item, until the flex line is filled. Then it repeats the process with any flex items that are wrapped onto additional flex lines. If there are three flex items, there will be the same amount of space between the first and second items as between the second and third, but there will be no extra empty space between the main-start edge of the container and the first item and the opposite (or main-end) edge of the container and the main-end edge of the last item, as shown in the second example in Figure 12-23. With space-between, the first item is flush with main-start, which is important to remember when you only have one flex item or when your flex items overflow the flex container in a nowrap scenario. This means, if there is only one flex item, it will be flush with main-start, not centered, which seems counterintuitive to many at first.

设置justify-content:space-between将第一个 flex 子元素与 main-start 齐平,并将一行的最后一个 flex 子元素与 main-end 齐平,然后在每个 flex 子元素周围放置均匀的空间,直到行已被填满。然后,被折行到其他行的 flex 子元素将重复该过程。如果有三个 flex 子元素,则第一和第二子元素之间的空间将与第二和第三个子元素之间的空间相同,但是容器的主轴起点边缘与第一子元素之间将没有多余的空白空间。容器的另一个(或主轴末端)边缘和与最后一个子元素的主轴末端边缘,如图 12-23 中的第二个示例所示。使用space-between,第一个子元素与 main-start 齐平,记住当您只有一个 flex 子元素或在'nowrap'场景中 flex 子元素溢出 flex 容器时,记住这一点很重要。这意味着,如果只有一个 flex 子元素,它将与 main-start 齐平,而不是居中,这乍看起来似乎与许多反常.

Space-between alignment

With justify-content: space-between the space between any two items on a flex line will be equal but won’t necessarily be the same across flex lines. When set to allow wrapping, on the last flex line, the first flex item of that last line is flush against main-start, the last if there are two or more on that line will be against main-end, with equal space between adjacent pairs of flex items. As shown in the last example of Figure 12-23, A and G, the first items on each flex line, are flush against main-start. F and I, the last items on each line, are flush against main-end. The flex items are evenly distributed with the spacing between any two adjacent items being the same on each of the lines, but the space between flex items on the first line is narrower than the space between flex items on the second line.

使用justify-content:space-between时,一行上任何两个子元素子元素之间的间隔都将相等跨行的不一定相同。设置为允许换行时,在最后一行上,最后一行的第一个 flex 子元素与 main-start 齐平,如果该行上有两个或多个,则最后一条将与 main-end 对齐,相邻子元素之间的间距相等。如图 12-23 的最后一个示例所示,每行的第一项 A 和 G 均与主轴起点齐平。 F 和 I(每行的最后一项)与主轴终点齐平。felx 子元素均匀分布,每行上任何两个相邻子元素之间的间距相同,但是第一行上的 flex 子元素之间的间隔比第二行上的 flex 子元素之间的间隔窄。

Setting justify-content: space-around evenly distributes the extra space on the line around each of the flex items, as if there were non-collapsing margins of equal size around each element on the main-dimension sides. So there will be twice as much space between the first and second item as there is between main-start and the first item, and main-end and the last item, as shown in Figure 12-24.

设置'justify-content:space-around'可以将多余的空间均匀地分布在每个 flex 子元素周围的行上,就好像在主轴方向的每个元素周围都有大小不等的非折叠外边距一样。因此,第一项和第二项之间的空间是 main-start 和第一项以及 main-end 和最后一项之间空间的两倍,如图 12-24 所示。

Space-around alignment

If the flex items wrap onto multiple lines, the space around each flex item is based on the available space on each flex line. While the space around each element on a flex line with be the same, it might differ between lines, as shown in the last examples in Figure 12-24. The spaces between A and B and between G and H are twice the width of the spaces between the main-start edge and A and the edge and G.

如果 flex 子元素分布在多行上,则每个 flex 子元素周围的空间将基于每行上的可用空间。尽管一行内每个元素子周围的空间相同,但不同行之间的空间可能有所不同,如图 12-24 中的最后一个示例所示。 A 和 B 之间以及 G 和 H 之间的间距是主轴起点边缘和 A 以及和 G 之间的间距的两倍。

If nowrap is set, and there isn’t enough room on the flex container’s main-direction for all the flex items, the flex items will overflow equally on both sides, similar to setting center, as shown in the third example in Figure 12-24.

如果设置了“ nowrap”,并且在 flex 容器的主轴方向上没有足够的空间容纳所有子元素,子元素项将在两侧均等地溢出,类似于设置“居中”,如第三个示例所示。在图 12-24 中。

Setting justify-content: space-evenly means the user agent counts the items, adds one, and then splits any extra space on the line by that many (i.e., if there are five items, the amount of space is split into six equal-size portions). One portion of the space is placed before each item on the line, as if it were a non-collapsing margin, and the last portion is placed after the last item on the list. Thus, there will the same amount of space between the first and second item as there is between main-start and the first item, and main-end and the last item, as shown in Figure 12-25.

设置'justify-content:space-evenly'表示浏览器对子元素进行计数,添加一项,然后将行上的任何多余空间均按该数量进行拆分(即,如果有五个子元素,则将空间量拆分为六个大小相等的部分)。空间的一部分放在行中每个子元素的前面,就好像它是非折叠外边距一样,剩下的部分放在列表中的最后一个子元素之后。因此,第一项和第二项之间的空间量与主轴起点和第一项之间,主轴终点和最后一项之间的空间量相同,如图 12-25 所示。

Space-evenly alignment

With the margin added to the flex items to make the examples less hideous, this may be difficult to see. Comparing margin-free examples of center, space-around, space-between, and space-evenly might be more helpful, so they’re shown in Figure 12-26.

将边距添加到 flex 子元素中以使示例更不难看出,这可能很难看到。比较 center, space-around, space-between, and space-evenly的无边距示例可能会更有帮助,因此如图 12-26 所示。

Space-evenly is not currently in the flexbox specification (late 2017), but it is part of the CSS Box Alignment specification. As the flexbox specification states it must follow the CSS Box Alignment specification, it should make its way back into the flexbox specsoon. Plus, most browsers already support it.

Comparing center, space-between, space-around, and space-evenly

12.5.1 justify-content Examples

We took advantage of the default value of justify-content in Figure 12-2, creating a left-aligned navigation bar. By changing the default value to justify-content: flex-end, we can right-align the navigation bar in English:

我们利用了图 12-2 中的justify-content默认值,创建了一个左对齐的导航栏。通过将默认值更改为justify-content:flex-end,我们可以将英语导航栏右对齐:

nav {
  display: flex;
  justify-content: flex-start;
}

Note that justify-content is applied to the flex container. If we’d applied to the links themselves, using something like nav a {justify-content: flex-start;}, there would have been no alignment effect.

注意,justify-content被应用于 flex 容器。如果我们使用nav a {justify-content:flex-start;}之类的东西来应用子元素本身,将不会有对齐效果。

A major advantage of justify-content is that when the writing direction changes, say for right-to-left writing modes, we don’t have to alter the CSS to get the tabs where they need to go. The flex items are always grouped toward main-start when flex-start is applied; in English, main-start is on the left. For Hebrew, main-start is on the right. If flex-end is applied and the flex-direction is row, then the tabs go to the right side in English, and the left side in Hebrew, as shown in Figure 12-27.

justify-content的主要优点是,当书写方向发生变化时(例如,从右向左书写模式),我们无需更改 CSS 即可将标签放到需要的地方。当应用flex-start时,flex 子元素总是按照主轴起点分组。对于英语,main-start 在左边。对于希伯来语来说,main-start 在右边。如果应用了“ flex-end”,而“ flex-direction”是“ row”,则选项卡位于英语的右侧,而希伯来语的左侧,如图 12-27 所示。

Internationally robust navigation alignment

We could have centered that navigation, as shown in Figure 12-28:

我们本可以将导航居中,如图 12-28 所示:

nav {
  display: flex;
  justify-content: center;
}

Changing the layout with one property value pair

12.6 Aligning Items

Whereas the justify-content defines how flex items are aligned along the flex container’s main axis, the align-items property defines how flex items are aligned along its flex line’s cross axis. As with justify-content, align-items is applied to flex containers, not individual flex items.

justify-content定义了 flex 子元素沿 flex 容器的主轴对齐的方式,而“ align-items”属性定义了 flex 子元素沿交叉轴对齐的方式。与justify-content一样,align-items适用于 flex 容器,而不是单个 flex 子元素。

With the align-items property, you can align all the flex items in a container to the start, end, or center of the cross axis of their flex lines. align-items is similar to justify-content but has effects in the perpendicular direction, setting the cross axis alignment for all flex items, including anonymous flex items.

使用align-items属性,您可以将容器中的所有 flex 子元素对准 flex 的交叉轴的起点,终点或中心。 align-itemsjustify-content类似,但是在垂直方向上有效果,为所有 flex 子元素(包括匿名 flex 子元素)设置在交叉轴的对齐方式。

With align-items, you can set all the items to be placed flush against the cross-start or cross-end of their flex line, or stretched flush to both. Alternatively, you can center all the flex items in the middle of the flex line. There are five values, including flex-start, flex-end, center, baseline, and the default stretch, as shown in Figure 12-29.

使用align-items,您可以将所有子元素设置为与交叉轴起点或交叉轴终点齐平,或拉伸至两者都齐平。或者,您可以将所有 flex 子元素在行的中间居中。有五个值,包括flex-startflex-endcenterbaseline和默认的stretch,如图 12-29 所示。

While align-items sets the alignment for all the flex items within a container, the align-self property enables overriding the alignment for individual flex items, as we’ll see in an upcoming section, `The align-self Property” on page 602.

In Figure 12-29, note how the flex items either hug the cross-start or cross-end side of the flex container, are centered, or stretch to hug both—except for baseline. With baseline, the flex items’ baselines are aligned: the flex item that has the greatest distance between its baseline and its cross-start side will be flush against the cross-start edge of the line.

在图 12-29 中,请注意 flex 子元素如何对齐 flex 容器的交叉轴起点或交叉轴终点,居中或拉伸以对其两者(除了baseline以外)。使用baseline,可调整 flex 子元素的基行:在基行和交叉起点之间具有最大距离的 flex 子元素将与交叉轴起点齐平。

The five values of the align-items property for both rows and columns

That’s the general idea—and explains non-wrapping flex containers pretty well—but there’s more to it than that. In the multiline align-items figures that follow, the following styles have been applied:

这是一般的想法,并且很好地解释了非折行的 Flex 容器,但除此之外,还有更多。在下面的多行align-items图中,已应用以下样式:

flex-container {
  display: inline-flex;
  flex-flow: row wrap;
  border: 1px dashed;
}
flex-item {
  border: 1px solid;
  margin: 0 10px;
}
.C,
.H {
  margin-top: 10px;
}
.D,
.I {
  margin-top: 20px;
}
.J {
  font-size: 3rem;
}

For each flex line, the red line is cross-start and the blue is cross-end. The lines appear purple when a new flex line abuts the previous flex line. C, H, D, and I have different values for top and bottom margins. We’ve added a bit of margin to the sides of all the flex items to make the figures more legible, which doesn’t affect the impact of the align-items property in this case. J has the font size increased, increasing the line height. This will come into play when we discuss the baseline value.

对于每行,红行是交叉轴起点,蓝色是交叉轴终点,当折行的行后接了新行后,这些行将显示为紫色。 C,H,D 和 I 的顶部和底部边距值不同。我们在所有 flex 子元素的侧面增加了一些边距,以使图形更清晰易读,在这种情况下,这不会影响“ align-items”属性的影响。 J 的字体大小增加了,增加了行高。这将在我们讨论baseline值时发挥作用。

The default is align-items: stretch, as shown in Figure 12-30.

默认值为align-items:Stretch,如图 12-30 所示。

Stretch alignment

stretch, as its name implies, stretches all stretchable flex items to be as tall or wide as the tallest or widest flex item on the line. What does “stretchable” mean? While by default flex items will stretch to take up 100% of the cross-size, if min-height, min-width, max-height, max-width, width, or height are set, those properties will take precedence. in other words, if an element has an explicitly set dimension along the cross axis, then it is not stretchable, and stretch will not affect its sizing.

顾名思义,stretch将所有可拉伸的 flex 子元素拉伸为与该行中最高或最宽的 flex 子元素一样高或宽。 “可拉伸”是什么意思?默认情况下,flex 子元素将拉伸以占据交叉轴尺寸的 100%,如果设置了min-height, min-width, max-height, max-width, width, 或 height,这些属性将优先。换句话说,如果一个元素沿横轴具有明确设置的尺寸,则该元素不可拉伸,而stretch将不会影响其尺寸。

Otherwise, the flex items’ cross-start will be flush with the flex line’s cross-start, and the flex items’ cross-end will be flush with the flex line’s cross-end. The flex item with the largest cross-size will remain its default size, and the other flex items will grow to the size of that largest flex item.

否则,flex 子元素的交叉轴起点将与行的交叉轴起点齐平,而 flex 子元素的交叉轴终点将与行的交叉终点齐平。在交叉轴方向尺寸最大的 flex 子元素将保留其默认大小,其他 flex 子元素将增大到该最大 flex 子元素的尺寸。

The size of the stretched flex item includes the margins on the cross-start and crossend sides: it is the outer edge of the flex items’ margin that will be flush with crossstart and cross-end. This is demonstrated by items C, D, H, and I in Figure 12-31.

拉伸后的 flex 子元素的大小包括交叉轴起点和交叉轴终点两侧的边距:flex 子元素的边距的外边缘将与交叉起点和交叉轴终点齐平。图 12-31 中的 C,D,H 和 I 项对此进行了展示。

Effect of cross-axis margins on item alignment

Their margins are the reason C, D, H, and I appear smaller than the other flex items on their flex lines. They’re not. The outer edges of the top and bottom margins are flush with the cross-starts and cross-ends of the flex lines they occupy. Those flex lines are, in turn, as tall as the tallest item on the line, or as wide as the widest item when the cross dimension is horizontal.

它们的边距是 C,D,H 和 I 看起来比该行上的其他子元素小的原因。他们不是。上边距和下边距的外边缘与它们所占据的行的交叉起点和交叉端点齐平。这些行的高度与行上的最高子元素一样高,或者在交叉轴方向为水平时与最宽的项子元一样宽。

Flex lines are only as tall or wide as they need to be to contain their flex items. In the five align-items figures, the line height of the flex line containing only K is much smaller than the other two lines.

行的高度或宽度仅与包含 flex 子元素所需的高度或宽度相同。在图中五个align-items里,仅包含 K 的行的高度比其他两行小得多。

12.6.1 Start, End, and Center Alignment

The values and effects of start, end, and center alignment are pretty straightforward, so we’ll take them all at once.

开始,结束和居中对齐的值和效果非常直接,因此我们将一次性全部考虑。

The flex-start value lines up each flex items’ cross-start edge flush against the cross-start edge of their flex line. The flex item’s cross-start edge is on the outside of the margin: if a flex item has a margin that is greater than 0, flex item will not appear flush with the flex line’s cross-start edge, as seen in flex item C, D, H, and I in the first example in Figure 12-32.

“ flex-start”值将每个 flex 子元素的交叉起始边缘与它们的行的交叉起始边缘对齐。flex 子元素的交叉起始边缘在边距的外部:如果 flex 子元素的边距大于 0,则 flex 子元素将不会与行的交叉起始边缘齐平,如在图 12-32 中第一个示例中的 flex 子元素 C,D,H 和 I 中所示。

Flex-start, flex-end, and center alignment

Setting align-items: flex-end will align the cross-end edge of all the flex items along the cross-end edge of the line they are in as shown in the second example in Figure 12-32. None of the flex items has a bottom margin greater than 0 pixels, so unlike the other examples, this example does not look jagged—all the flex items’ cross-end edges are visibly flush against the cross-end edge of each flex line.

设置align-items:flex-end将使所有 flex 子元素的交叉终点边缘沿着它们所在行的交叉终点边缘对齐,如图 12-32 中的第二个示例所示。所有 flex 子元素的底边距都没有大于 0 像素,因此与其他示例不同,该示例看起来并不参差不齐-所有 flex 子元素的交叉终点边缘在视觉上都与每个行的交叉终点边缘齐平。

As shown in the third example in Figure 12-32, setting align-items: center will center the flex items’ cross-size along the middle point of the cross axis of the line. The center is the midpoint between the outer edges of a flex item’s margin edges—remember, flex item margins do not collapse. Because the cross-edge margins for C, D, H, and I are not symmetrical, the flex items do not appear visibly centered along the cross axis, even though they are: the halfway points between their top and bottom margin edges are exactly aligned with the midpoints of the flex lines in which they sit.

如图 12-32 中的第三个示例所示,设置align-items:center将使 flex 子元素的交叉轴方向的尺寸沿行的交叉轴的中点居中。中心是 flex 子元素边距外边缘之间的中点-请记住,flex 子元素边距不会折叠。由于 C,D,H 和 I 的交叉边方向边距不是对称的,因此即使他们是居中的,看起来子元素也不会沿交叉轴明显居中:它们的顶部和底部边距边缘之间的中点已完全对齐它们行的中点。

In LTR and RTL languages, in the case of flex-direction: row and row-reverse, the aligned midpoint of a flex item is the point halfway between its top and bottom margin edges. For flex-direction: column, and column-reverse, the aligned midpoint of a flex item is the point halfway between its left and right margin edges.

在 LTR 和 RTL 语言中,在flex-direction:rowrow-reverse的情况下,flex 子元素的对齐中点是其上边缘和下边缘之间的中间点。对于flex-direction:columncolumn-reverse,flex 子元素的对齐中点是其左边缘和右边缘之间的中间点。

If a flex container’s cross size is constrained, the contents may overflow the flex container’s cross-start and/or cross-end edge. The direction of the overflow is not determined by the align-items property, but rather by the align-content property, discussed in an upcoming section, “Aligning Content” on page 604. align-items aligns the flex items within the flex line and does not directly impact the overflow direction of the flex items within the container.

12.6.2 Baseline Alignment

The baseline value is a little more complicated. With baseline, the flex items in each line are all aligned at their first baselines. The flex item on each flex line with the biggest distance between its baseline and its cross-start margin edge has that margin edge placed flush against the cross-start edge of the line, and all other flex items’ baselines are lined up with the baseline of that flex item.

baseline值稍微复杂一些。使用baseline,每行中的 flex 子元素都在其第一个基行处对齐。每行的 flex 子元素的基行和交叉起始边缘之间的距离最大的子元素,该元素的交叉起点方向边缘与行的起始边缘齐平,所有其他 flex 子元素的基行都与该 flex 子元素基行对齐。

Take a look at the second line in Figure 12-33, where J dominates. The font size for J in this was was increased to 3rem in order to create a flex item with a taller first line of text than the other flex items. Its top (cross-start) edge is placed against the top (cross-start) edge of the flex line. All the other flex items in the line we moved down until their first text line’s baseline is aligned with the first baseline of J. (The green line indicates the placement of this baseline.)

看一下图 12-33 中的第二行,其中 J 占主导地位。 J 中的字体大小已增加到“ 3rem”,以便创建比其他 flex 子元素具有更高的第一行文本的 flex 子元素。其顶部(交叉起点)边缘紧贴着行的顶部(交叉起点)边缘。我们向下移动该行中的所有其他 flex 子元素,直到其第一行文本的基行与 J 的第一个基行对齐为止。(绿行表示此基行的位置。)

Baseline alignment

Now look at the first flex line, the one starting with A. You’ll notice that A, B, C, D, and E are all top-aligned, but look closer. The subtlety here is that they are not visibly flush to the top of the flex line. This happens because D has a top margin of 20 pixels. The outer edge of D’s top (cross-start) margin is flush against the cross-start of the flex line. As previously noted, the distance between the cross-start line and baseline is determined by the item on the line that has the biggest distance between its outer margin on its cross-start side and its baseline. Therefore, D’s placement (due to its top margin) becomes the baseline against which the other items in the line are aligned.

现在看第一行,以 A 开头。您会注意到 A,B,C,D 和 E 都是顶部对齐,但看起来更近。此处的微妙之处在于,它们显然没有与行的顶部齐平。发生这种情况是因为 D 的上边距为 20 像素。 D 的顶部(交叉起点)外边距边缘与 fle 行的交叉起点齐平。如前所述,交叉起始行与基行之间的距离由该行上在其交叉起始侧上的外部边缘与基行之间具有最大距离的子元素确定。因此,D 的位置(由于其顶部边距)成为该行中其他子元素对齐的基准。

In many cases, baseline will look like flex-start. For example, had D lacked a top margin, then all the items in that first line would have been visibly flush against the top of the flex line, just as would have happened with flex-start. Whenever the items have different margins, borders, padding, font sizes, or line heights on their cross-start side, there will be a difference between flex-start and baseline.

在许多情况下,baseline看起来像 flex-start。例如,如果 D 缺少上边距,那么第一行中的所有子元素都将明显地与行的顶部齐平,就像使用flex-start一样。只要这些子元素的交叉起始端的外边距,边框,内边距,字体大小或行高不同,·flex-startbaseline之间就会有所不同。

There is one case in which baseline literally becomes flex-start, and that’s when the baselines of the flex items are parallel to the cross axis. For example, suppose we took the flex container in Figure 12-33 and changed it to flex-direction: column. Now the cross axis, like the baselines of the English text within, is horizontal. Since there’s no way to create an offset from the cross-start edge of the columns (the left side), baseline is treated exactly as if it were flex-start instead.

在某些情况下,baseline从字面上变为flex-start,那就是 flex 子元素的基行平行于交叉轴。例如,假设我们使用了图 12-33 中的 flex 容器,并将其更改为flex-direction:column。现在,交叉轴像其中的英文文本的基行一样,是水平的。由于无法从列的交叉起始边缘(左侧)创建偏移,因此将 baseline视为完全是 flex-start

12.6.3 Additional Notes

If you want to change the alignment of one or more flex items, but not all, you can include the align-self property on the flex items you would like to align differently. The align-self takes the same values as align-items, and is discussed in “Flex Items” on page 609.

如果要更改一个或多个 flex 子元素(但不是全部)的对齐方式,则可以在希望以不同方式对齐的 flex 子元素中使用align-self属性。 align-selfalign-items具有相同的值,并在第 609 页的“flex 子元素”中进行了讨论。

You cannot override the alignment for anonymous flex items (non-empty text node children of flex containers). Their align-self always matches the value of align-items of their parent flex container.

您不能覆盖匿名 flex 子元素(flex 容器的非空文本子元素)的对齐方式。他们的align-self总是匹配其父级 flex 容器的`align-items'的值。

In the align-items examples, the flex container’s cross-size was as tall as it needed to be. No height was declared on the container, so it defaulted to height: auto. Because of this, the flex container grew to fit the content. You may have noticed the example flex containers were all the same height, and the flex line heights were the same across all examples.

align-items示例中,flex 容器的交叉轴方向尺寸已达到所需的高度。容器上没有声明height,因此默认为height:auto。因此,flex 容器逐渐适合内容。您可能已经注意到示例 flex 容器的高度都相同,并且所有示例的行高度都相同。

Had the cross-size—in this case the height—been set to a specific size, there may have been extra space at cross-end, or not enough space to fit the content. Flexbox allows us to control the alignment of flex lines with the align-content property. The align-content property is the last property we need to focus on that applies to the flex container (versus the flex items). The align-content property only impacts flex line alignment in multiline flex containers.

如果将交叉轴方向尺寸(在这种情况下为高度)设置为特定尺寸,则交叉终点可能有多余的空间,或者没有足够的空间来容纳内容。 Flexbox 允许我们使用align-content属性来控制行的对齐方式。 align-content属性是我们需要关注的最后一个属性,它适用于 flex 容器(相对于 flex 子元素)。align-content属性仅影响多行 flex 容器中的行对齐。

12.7 The align-self Property

This is jumping ahead a bit, but now is the right time to talk about the align-self property. This is used to override the align-items property value on a per-flex-item basis.

这有点太前面了,但是现在是讨论align-self属性的合适时机。这用于每个 flex 子元素覆盖align-items属性值。

With the align-items property set on the flex container, you align all the flex items of that container. You can override the alignment of any individual flex item with the align-self property. The default value of align-items is stretch, which is why all the flex items in the five examples in Figure 12-34 are all as tall as the parent, with the exception of the second flex item.

通过在 flex 容器上设置align-items属性,可以对齐该容器的所有 flex 子元素。您可以使用align-self属性覆盖任何单个 flex 子元素的对齐方式。align-items的默认值为stretch,这就是为什么图 12-34 的五个示例中的所有 flex 子元素都与父项一样高的原因,第二个 flex 子元素除外。

Changing flex item alignments

All the flex items have the align-self’s default value of auto set, meaning they inherit the alignment (in this case, stretch) from the container’s align-items property, except the second flex item in each example. That flex item has been given the align-self value shown underneath the example.

所有的 flex 子元素都具有align-self的默认值auto set,在每个示例中这意味着它们从容器的align-items属性继承了对齐方式(在这种情况下为stretch),第二个 flex 子元素除外。该 flex 子元素已获得示例下方显示的align-self值。

Just as with the values of the align-items property, the flex-start value places the item at the cross-start edge. flex-end places the item at the cross-end edge. center aligns the item in the middle of the cross axis. baseline aligns the baseline of the flex item with the lowst baseline in its flex line. Finally, auto and stretch both stretch the flex items, as the align-items value was allowed to default to stretch. (Similarly, align-self: inherit would cause a stretch alignment in this case.)

就像align-items属性的值一样,flex-start值将子元素放置在交叉起点边缘。 flex-end将子元素放置在交叉端边缘。center 在交叉轴的中间对齐子元素。 baseline将 flex 子元素的基准行与其行中的最低基准行对齐。最后,auto 和 stretch 都拉伸了 flex 子元素,因为align-items值被默认设置为stretch。 (同样,在这种情况下,align-self:Inherit会导致拉伸对齐。)

To learn more about the flex-start, flex-end, center, baseline, and stretch values, see “Aligning Items” on page 596.

要了解有关 flex-start, flex-end, center, baseline, 和stretch值的更多信息,请参见第 596 页上的“Aligning Items”。

12.8 Aligning Content

The align-content property aligns a flex container’s lines within a flex container that has extra space in the cross-axis direction, and dictates which direction will have overflow when there is not enough room to fit the flex lines.

align-content属性将 flex 容器中的行对齐,使其在交叉轴方向上具有额外的空间,并指示当没有足够的空间容纳所有行时,哪个方向会溢出。

The align-content property dictates how any extra cross-direction space in a flex container is distributed between and around flex lines. Although the values and concepts are the same, align-content is different from the previously discussed align-items property, which dictates flex item positioning within each flex line.

align-content属性决定了 flex 容器中任何多余的交叉轴方向的空间如何在行之间和周围分布。尽管align-content与之前讨论的align-items属性的值和概念相同,但是这两个属性不同,后者规定了 flex 子元素子元素在行内的位置。

Think of align-content as similar to how justify-content aligns individual items along the main axis of the flex container, but it does it for flex lines with regard to the cross axis of the container. This property only applies to multiline flex containers, having no effect on non-wrapping and otherwise single-line flex containers.

可以将align-content想像成与justify-content如何让单个项目沿 flex 容器的主轴对齐类似,但是它针对行沿容器的交叉轴进行对齐。此属性仅适用于多行 flex 容器,对非折行和单行 flex 容器没有影响。

Consider the following CSS as a base, and assume the flex items have no margins:

以以下 CSS 为基础,并假设 flex 子元素没有空白:

.flex-container {
  display: flex;
  flex-flow: row wrap;
  align-items: flex-start;
  border: 1px dashed;
  height: 480px;
  background-image: url(banded.svg);
}
.flex-items {
  margin: 0;
  flow: 1;
}

Figure 12-35 demonstrates the seven possible values of the align-content property, as used in conjunction with that CSS. In each example, there are three flex lines. Each flex line’s cross-start and cross-end edges are denoted by red and blue lines, respectively. The leftover space in the flex container; that is, the space between or around the flex lines, is represented by the banded regions.

图 12-35 演示了与 CSS 结合使用的align-content属性的七个可能值。在每个示例中,都有三行。每条行的交叉方向起点和交叉方向终点分别由红行和蓝行表示。 flex 容器中的剩余空间;也就是说,行之间或周围的空间由带状区域表示。

Distribution of extra space for each value of align-content

With a height of 480 pixels, the flex container is taller than the default combined heights of the 3 flex lines. Let’s say the tallest items in each line—E, F, and K—are 150 pixels, 180 pixels, and 30 pixels, respectively, for a combined total of 360 pixels. Each flex container has an extra 120 pixels of free space in the cross-size direction.

flex 容器的高度为 480 像素,比 3 行的默认高度和高。假设每行中最高的项目(E,F 和 K)分别为 150 像素,180 像素和 30 像素,总共为 360 像素。每个 flex 容器在交叉方向上都有额外的 120 像素的可用空间。

With five of the align-items values, the free space is distributed outside of the flex lines, as illustrated in Figure 12-35. These act in the same ways the same values do for justify-content, only along the cross axis instead of the main axis (as is the case for justify-content). With the value stretch, the extra space is evenly distributed to all the flex lines, increasing their cross-size until their edges touch.

如图 12-35 所示,通过五个align-content值,自由空间分布在行的外部。它们以相同的方式对justify-content进行相同的操作,只是沿交叉轴而不是主轴(justify-content就是这种情况)。值为stretch时,多余的空间将均匀地分配到所有行,从而增加其交叉轴方向尺寸,直到其边缘接触容器为止。

In the previous example, with a flex container height of 480 pixels, we have 120 pixels of “leftover” space along the cross axis, distributed differently depending on the value of the align-content property.

在前面的示例中,flex 容器的高度为 480 像素,我们在横轴上有 120 像素的剩余空间,其分布取决于align-content属性的值。

As shown in the top three examples in Figure 12-35, with flex-start the 120 pixels is all on the cross-end side of the cross axis. With flex-end, the extra 120 pixels of available space is all placed at the cross-start side. With center, the lines are centered, and 60 pixels of extra space (half of 120 pixels) is placed at cross-start and cross-end sides.

如图 12-35 的前三个示例所示,使用flex-start时,120 个像素全部位于交叉轴末端。使用flex-end时,多余的 120 像素可用空间全部放在交叉轴起始段端。使用center时,行居中,并且在交叉起点和交叉终点放置 60 像素的额外空间(120 像素的一半)。

With space-between, there is 60 pixels between adjacent pairs of flex lines. With space-around, on the other hand, the space is evenly distributed around each line: the 120 pixels is split into 3, since there are 3 flex lines. This puts 20 pixels of noncollapsed space (half of 40 pixels) on the cross-start and cross-end sides of each flex line, so there are 20 pixels of extra space at the cross-start and cross-end sides of the flex container, and 40 pixels of space between adjacent flex lines.

space-between,相邻的行之间有 60 个像素。另一方面,在space-around中,空间均匀地分布在每行周围:由于有 3 行,因此 120 像素被分成 3 部分。这会将 20 像素的非折叠空间(40 像素的一半)放置在每条行的交叉起点和交叉终点侧,因此 flex 容器的交叉起点和交叉端侧有 20 像素的额外空间,相邻的行之间的间距为 40 像素。

For space-evenly, there are four spaces to insert: one before each flex line, and an extra space after the last flex line. With three lines, that means four spaces, or 30 pixels for each space. That places 30 pixels of space at the cross-start and cross-end sides, and 30 pixels between adjecent flex lines.

对于space-evenly,有四个空间要插入:在每个行之前一个空间,在最后一个行之后一个多余的空间。三行表示四个空间,每个空间 30 像素。这样在交叉起点和交叉终点放置了 30 个像素的空间,在相邻的行之间放置了 30 个像素。

The stretch value is different: with stretch the lines stretch with the extra space evenly distributed among the flex lines rather than between them. In this case, 40 pixels was added to each of the flex lines, causing all 3 to grow in height by an equal amount—that is, the exact same amount, not an amount proportional to each. You’ll note in the sixth example of Figure 12-35, there is no area within the container that is not occupied by a flex line. stretch is the default value, as you likely want to fill all the available space.

stretch值是不同的:使用stretch时,行拉伸时,多余的空间均匀地分布在行内而不是在行之间。在这种情况下,向每个行添加了 40 个像素,从而使所有这 3 个行的高度都增长了相等的数量,即完全相同的数量,而不是与每个像素成比例的数量。您会注意到,在图 12-35 的第六个示例中,容器内没有未被行占据的区域。 stretch是默认值,因为您可能想填充所有可用空间。

If there isn’t enough room for all the lines, they will overflow at cross-start, cross-end, or both, depending on the value of the align-content property. This is shown in Figure 12-36, where the dotted box with a light gray background represents a short flex container. (align-items: flex-start was set to make the effect of align-content more obvious.)

如果没有足够的空间容纳所有行,则它们会在交叉起点,交叉终点或两者同时溢出,具体取决于align-content属性的值。如图 12-36 所示,其中带有浅灰色背景的虚行框表示一个短的 flex 容器。 (align-items:flex-start的设置使align-content的效果更加明显。)

Flex-line overflow directions for each value of align-content

The only difference in the CSS between this and Figure 12-35 is the height of the flex container. Here, the flex containers have been reduced to a height of 240 pixels, so as to create flex containers not tall enough to encompass all their flex lines (which, as you may recall, total 360 pixels in height).

图 12-36 与图 12-35 之间的 CSS 唯一区别是 flex 容器的高度。在这里,flex 容器的高度已减小到 240 像素,以便创建 flex 容器不足以容纳其所有行(您可能还记得,它们的总高度为 360 像素)。

When the flex lines overflow the flex container, align-content: flex-start, space-between, and stretch cause them overflow the cross-end side, whereas align-content: space-around and center evenly overflow both the cross-end and crossstart sides. Only align-content: flex-end causes flex lines overflow just the crossstart side.

当行溢出 flex 容器时,align-content:flex-startspace-betweenstretch会导致它们的交叉轴点终点端溢出,而align-content:space-aroundcenter会在交叉端和交叉起始端均匀溢出。只有align-content:flex-end会导致行仅交叉轴起点端溢出。

Keep in mind that these values are not top- or bottom-centric. If the cross axis goes upward, then align-content: flex-start will start aligning flex lines from the bottom and work upward from there, potentially overflowing the top (cross-end) edge. For that matter, when the flow direction is columnar, the cross axis will be horizontal, in which case the cross-start and -end edges will be the right or left edges of the flex container.

请记住,这些值不是顶部或底部。如果交叉轴朝上,那么align-content:flex-start将开始从底部开始对齐折行,然后从底部开始向上折行,可能会溢出顶部(交叉终点)边缘。因此,当流动方向为竖直时,交叉轴将为水平,在这种情况下,交叉起点和终点边缘将为 flex 容器的右边缘或左边缘。

Space between, around, and evenly

It’s worth taking a closer look at, and thinking about how, space-between and space-around affect the alignment of flex lines.

值得仔细研究一下,并思考space-betweenspace-around如何影响行的对齐方式。

When align-content: space-between is set, the flex lines are evenly distributed in the flex container. This “even distribution” is based on the available space, not the size of the lines. If there is more than one flex line, the first line will be flush against the container’s cross-start, the last line will be flush against the container’s cross-end, and any available extra space is distributed evenly between the additional lines, if there are any. The extra space is distributed evenly, not proportionally. The space between any two flex lines within the flex container is equal, even if the cross-sizes of the multiple flex lines differ. Furthermore, the middle flex line, if there are an odd number of lines, is not necessarily centered in the flex container, because the lines don’t necessarily all have the same cross dimensions.

当设置了align-content:space-between时,行均匀地分布在 flex 容器中。这种“均匀分布”是基于可用空间,而不是行的大小。如果有多行,则第一行将与容器的交叉起点齐平,最后一行将与容器的交叉端点齐平,并且任何可用的额外空间将在另外的行之间平均分配。多余的空间均匀分布,而不是成比例分布。即使多个行的交叉方向尺寸不同,flex 容器中任意两条行之间的间距也相等。此外,如果折行的数量是奇数,则中间的行不一定会在 flex 容器中居中,因为这些行不一定都具有相同的交叉方向尺寸。

Only flex containers with multiple lines can have free space in the cross axis for lines to be aligned in. If there is only one line, the align-content property will not impact the distribution of the content. In flex containers with a single line of flex items, the lone line stretches to fill all of the available space.

Instead, the spacing between any two adjacent lines is the same. Assume 3 lines with 120 pixels total of free space, as we saw in the previous section. The first flex line goes against the cross-start edge, and the second flex line goes against the cross-end edge. That means there is one line to place between them, and two gaps. The 120 pixels of leftover space gets divided equally into 2 chunks of 60 pixels each. One 60-pixel chunk is placed between the first and second flex lines, and the other between the second and third flex lines. This is illustrated in Figure 12-37.

相反,任何两条相邻行之间的间距都相同。如上一节所述,假定 3 行共有 120 像素的可用空间。第一行靠在交叉起点边缘,第二行靠在交叉终点边缘。这意味着它们之间只有一行,两个间隙。剩余空间的 120 像素被平均分为 2 块 ​​,每块 60 个像素。一个 60 像素的块放置在第一和第二行之间,另一个放置在第二和第三行之间。如图 12-37 所示。

Distribution of free space for space-between, space-around, and spaceevenly

The space-around value distributes the lines within a multiline flex container evenly, as if all the flex lines had equal, non-collapsing margins on both the cross-start and cross-end sides. Because there is an equal distribution of the extra available space around each line, the space between the edges of the container and the first and last flex lines is half the size of the distance between any two flex lines. The distribution of the extra space is shown in Figure 12-37.

space-around值将行均匀地分布在多行 flex 容器中,就好像所有行在开始和结束两端都具有相等的,不塌陷的边距一样。由于每行周围的可用空间均等分布,因此容器的边缘与第一行和最后一行之间的空间是任何两行之间距离的一半。多余空间的分布如图 12-37 所示。

As of late 2017, the various alignment values like flex-start, flex-end, and so on are being made more generic: start, end, and so forth. These are part of a wider effort to make CSS more aware of writing and layout directions. An example of this is the addition of properties like margin-start and padding-end. It wasn’t quite advanced enough (or well-supported enough) to merit complete coverage in this edition, but keep an eye on these developments.

We have been, for the most part, taking a look at properties of the flex container (the exception was align-self). It’s time to take a look at the properties directly applied to flex items.

我们大部分时间都在研究 flex 容器的属性( align-self是一个例外)。现在该看看直接应用于 flex 子元素的属性了。

12.9 Flex 子元素 Flex Items

In the previous sections, we saw how to globally lay out all the flex items within a flex container by styling that container. The flexible box layout specification provides several additional properties applicable directly to flex items. With these flex-itemspecific properties, we can more precisely control the layout of individual flex containers’ children.

在前面的部分中,我们了解了如何通过样式化容器在 Flex 容器中全局布置所有 flex 子元素。灵活框布局规范提供了一些直接适用于 flex 子元素的其他属性。通过这些 flex 子元素特殊定制的属性,我们可以更精确地控制单个 flex 容器的子代的布局。

12.9.1 What Are Flex Items?

We create flex containers simply by adding a display: flex or display: inline-flex to an element that has child nodes. The children of those flex container are called flex items—whether they’re child elements, non-empty text nodes between child elements, or generated content. Figure 12-38 shows a situation where each letter is enclosed in its own element, including the space between words, so that each letter and space becomes a flex item.

我们只需在具有子节点的元素上添加display:flexdisplay:inline-flex即可创建 flex 容器。这些 flex 容器的子元素称为 flex items,无论它们是子元素,子元素之间的非空文本节点还是生成的内容。图 12-38 显示了一种情况,其中每个字母都包含在其自己的元素中,包括单词之间的空格,因此每个字母和空格都变成一个 flex 子元素。

The child nodes are flex items, the parent node is a flex container

When it comes to text-node children of flex containers, if the text node is not empty—containing content other than whitespace—it will be wrapped in an anonymous flex item, behaving like its flex item siblings. While these anonymous flex items do inherit all the flex properties set by the flex container, just like their DOM node siblings, they are not directly targetable with CSS. Therefore, we can’t directly set any of the flex item specific properties on them. Thus, in the following markup, the two elements (the <strong> and the <em>) and the text “ they’re what’s for ” each become flex items,for a total of three flex items:

对于 flex 容器的文本子节点,如果文本节点不为空(包含空格以外的内容),它将被包裹在一个匿名的flex item中,其行为就像其 flex 子元素的兄弟姐妹一样。尽管这些匿名文本元素确实继承了 flex 容器设置的所有 flex 属性,就像它们的 DOM 节点一样,但它们不能直接用 CSS 定位。因此,我们无法直接在其上设置任何特定于 flex 子元素的属性。因此,在下面的标记中,两个元素(<strong><em>)以及文本“ they’re what’s for ”将成为 flex 子元素,总共三个 flex 子元素:

<p style="display: flex;">
  <strong>Flex items:</strong> they’re what’s for <em>&lt;br&gt;fast!</em>
</p>

Generated content (via ::before and ::after) can be styled directly; therefore all the properties discussed in this chapter apply equally to generated content as they do to element nodes.

生成的内容(通过:: before:: after)可以直接设置样式。因此,本章讨论的所有属性与元素节点一样,同样适用于生成的内容。

Whitespace-only text nodes within a flex container are ignored, as if their display property were set to none, as the following code example shows:

flex 容器中的纯空白文本节点将被忽略,就像它们的 display 属性设置为 none 一样,如以下代码示例所示:

nav ul {
  display: flex;
}
<nav>
  <ul>
    <li><a href="#1">Link 1</a></li>
    <li><a href="#2">Link 2</a></li>
    <li><a href="#3">Link 3</a></li>
    <li><a href="#4">Link 4</a></li>
    <li><a href="#5">Link 5</a></li>
  </ul>
</nav>

In the preceding code, with the display property set to flex, the unordered list is the flex container, and its child list items are all flex items. These list items, being flex items, are flex-level boxes, semantically still list items, but not list items in their pre‐sentation. They are not block-level boxes either. Rather, they participate in their container’s flex formatting context. The whitespace between and around the li elements—the line feeds and indenting tabs and/or spaces—is completely ignored. The links are not flex items themselves, but are descendants of the flex items the list items have become.

在前面的代码中,将 display 属性设置为 flex,无序列表是 flex 容器,其子列表项都是 flex 子元素。这些列表项(即 flex 子元素)是 flex 级别的框,在语义上仍会列出项目,但在其预先表示中不会列出项目。它们也不是块级框。相反,他们参与了容器的 flex 格式设置上下文。li元素之间和周围的空格(换行和缩进制表符和/或空格)将被完全忽略。链接本身不是 flex 子元素,而是已成为 flex 子元素的列表项目的后代。

12.9.2 Flex Item Features

The margins of flex items do not collapse. The float and clear properties don’t have an effect on flex items, and do not take a flex item out of flow. In effect, float and clear are ignored when applied to flex items. (However, the float property can still affect box generation by influencing the display property’s computed value.) Consider:

flex 子元素的边距不会崩溃。 floatclear属性对 flex 子元素没有影响,也不会影响 flex 子元素的流动性。实际上,将floatclear应用于 flex 子元素时会被忽略。 (但是,float属性仍会通过影响display属性的计算值来影响盒子的生成。)请考虑:

aside {
  display: flex;
}
img {
  float: left;
}
<aside>
  <!-- this is a comment -->
  <h1>Header</h1>
  <img src="images/foo.jpg" alt="Foo Master" />
  Some text
</aside>

In this example, the aside is the flex container. The comment and whitespace-only text nodes are ignored. The text node containing “some text” is wrapped in an anonymous flex item. The header, image, and text node containing “some text” are all flex items. Because the image is a flex item, the float is ignored.

在此示例中, aside是 flex 容器。注释和仅空白文本节点将被忽略。包含“某些文本”的文本节点被包裹在一个匿名 flex 子元素中。包含“某些文本”的标题,图像和文本节点都是 flex 子元素。由于图像是 flex 子元素,因此会忽略float

Even though images and text nodes are inline-level nodes, being flex items, as long as they are not absolutely positioned, they are blockified:

即使图像和文本节点是内联级别的节点,它们都是 flex 子元素,只要它们不是绝对定位的,它们就会被块状化:

aside {
  display: flex;
  align-items: center;
}
<aside>
  <!-- a comment -->
  <h1>Header</h1>
  <img src="images/foo.jpg" alt="foo master" />
  Some text <a href="foo.html">with a link</a> and more text
</aside>

In the last example, the markup is similar to the code in the second example, with the addition of a link within the non-empty text node. In this case, we are creating five flex items. The comment and whitespace-only text nodes are ignored. The header, the image, the text node before the link, the link, and the text node after the link are all flex items. This is illustrated by Figure 12-39.

在最后一个示例中,标记类似于第二个示例中的代码,并在非空文本节点内添加了链接。在这种情况下,我们将创建五个 flex 子元素。注释和仅空白文本节点将被忽略。标题,图像,链接之前的文本节点,链接和链接之后的文本节点都是 flex 子元素。如图 12-39 所示。

Five flex items in an aside

The text nodes containing “some text” and “and more text” are wrapped in anonymous flex items, represented in Figure 12-39 by the dashed boxes (the dashes having been added for illustrative purposes) with no background. The header, image, and link, being actual DOM nodes, can be styled directly with CSS. The anonymous flex containers are not directly targetable, and so will only have whatever styles they pick up from the flex container.

包含 “some text”和 “and more text”的文本节点被包裹在匿名 flex 子元素中,在图 12-39 中由虚行框(为说明目的添加了虚线)表示,没有背景。标题,图像和链接是实际的 DOM 节点,可以直接使用 CSS 设置样式。匿名 Flex 容器不可直接定位,因此只能使用 flex 容器设置的任何样式。

Additionally, vertical-align has no effect on a flex item, except as it affects the alignment of text within the flex item. In other words, setting vertical-align: bottom on a flex item will make the text inside the flex item all align to the bottoms of their line boxes, not push the flex item to the bottom of its container. (That’s what align-items and align-self are for.)

另外,vertical-align对 flex 子元素没有任何影响,除了会影响 flex 子元素中文本的对齐方式。换句话说,在 flex 子元素上设置vertical-align:bottom将使 flex 子元素内的文本全部与行框的底部对齐,而不是将 flex 子元素推到其容器的底部。 (这就是align-itemsalign-self的用途。)

Absolute positioning

While float will not actually float a flex item, setting position: absolute is a different story. The absolutely positioned children of flex containers, just like any other absolutely positioned element, are taken out of the flow of the document. More to the point, they do not participate in flex layout, and are not part of the document flow. However, they can be impacted by the styles set on the flex container, just as a child can be impacted by a parent element that isn’t a flex container. In addition to inheriting any inheritable properties, the flex container’s properties can affect the origin of the positioning.

尽管float实际上不会浮动 flex 子元素,但是设置position:absolute是另外一个故事。就像其他任何绝对定位的元素一样,flex 容器的绝对定位子元素将从文档流中删除。更重要的是,它们不参与 flex 布局,也不属于文档流。但是,它们可能会受到 flex 容器上设置的样式的影响,就像孩子可能会受到非 flex 容器的父元素所影响一样。除了继承任何可继承的属性外,flex 容器的属性还会影响定位的来源。

The absolutely positioned child of a flex container is affected by both the justify-content value of the flex container, and its own align-self value, if there is one. For example, if you set align-self: center on the absolutely positioned child, it will start out centered with respect to the flex container parent’s cross axis. From there, it can moved by properties like top, bottom, margins, and so on.

flex 容器的绝对定位子元素受 flex 容器的“ justify-content”值及其自身的“ align-self”值(如果有)的影响。例如,如果您在绝对定位的子项上设置“ align-self:center”,则该子项将从 flex 容器父项的交叉轴开始居中。从那里,它可以通过诸如 top,bottom,margin 等属性移动。

The order property (explained in a later section, “The order property” on page 648) may not impact where the absolutely positioned flex container child is drawn, but it does impact the order of when it is drawn in relation to its siblings.

“ order”属性(在后面的第 648 页中的“The order property”一节中有解释)可能不会影响绘制绝对位置的 flex 容器子元素的位置,但会影响相对于其同级元素绘制子元素时的顺序。

12.9.3 Minimum Widths

In Figure 12-40, you’ll note the line that is set to the nowrap default overflows the flex container. This is because when it comes to flex items, the implied value of min-width is auto, rather than 0. Originally in the specification, if the items didn’t fit onto that single main axis, they would shrink. However, the specification of min-width was altered as applied to flex items. (Traditionally, the default value for min-width is 0.)

在图 12-40 中,您会注意到设置为“ nowrap”默认值的行溢出 flex 容器。这是因为涉及 flex 子元素时,min-width的隐含值为auto,而不是“ 0”。最初是在规范中,如果项目不适合一条主轴,它们会收缩。但是,“最小宽度”的规范已更改为适用于 flex 子元素。 (传统上,“最小宽度的默认值为 0”。)

Flex container overflow with minimum-width flex items

If you set the min-width to a width narrower than the computed value of auto—for example, if you declare min-width: 0—then the flex items in the nowrap example will shrink to be narrower than their actual content (in some cases). If the items are allowed to wrap, then they will be as narrow as possible to fit their content, but no narrower. Both situations are illustrated in Figure 12-41.

如果将min-width设置为比 auto的计算值窄的宽度——例如,如果声明“最小宽度:0”,则“ nowrap”示例中的 flex 子元素将缩小为比实际内容窄(在某些情况下)。如果允许折行,则它们将尽可能缩小以适合其内容,但不会变窄。两种情况都在图 12-41 中进行了说明。

Zero-minimum-width flex items in non-wrapped and wrapped flex containers

12.10 Flex-Item–Specific Properties

While flex items’ alignment, order, and flexibility are to some extent controllable via properties set on their flex container, there are several properties that can be applied to individual flex items for more granular control.

虽然 flex 子元素的对齐方式,顺序和灵活性可以通过在其 flex 容器上设置的属性在某种程度上进行控制,但可以将多个属性应用于单个 flex 子元素以进行更精细的控制。

The flex shorthand property, along with its component properties of flex-grow, flex-shrink, and flex-basis, controls the flexibility of the flex items. Flexibility is the amount by which a flex item can grow or shrink along the main axis.

“ flex”的简写属性以及它的“ flex-grow”,“ flex-shrink”和“ flex-basis”的组成属性,控制 flex 子元素的“ flexibility”。“ Flexibility”是 flex 子元素沿着主轴增长或收缩的量。

12.11 The flex Property

The defining aspect of flex layout is the ability to make the flex items “flex”: altering their width or height to fill the available space in the main dimension. A flex container distributes free space to its items proportional to their flex grow factor, or shrinks them to prevent overflow proportional to their flex shrink factor. (We’ll explore these concepts momentarily.)

flex 布局的定义方面是使 flex 子元素“flex”的能力:更改其宽度或高度以填充主轴方向中的可用空间。flex 容器根据生长因子将自由空间按其 flex 比例分配给其项目,或根据收缩银子因子将其收缩以防止溢出。 (我们将先探讨这些概念。)

Declaring the flex shorthand property on a flex item, or defining the individual properties that make up the shorthand, enables authors to define the grow and shrink factors. If there is excess space, you can tell the flex items to grow to fill that space. Or not. If there isn’t enough room to fit all the flex items within the flex container at their defined or default sizes, you can tell the flex items to shrink proportionally to fit into the space. Or not.

在 flex 子元素上声明flex简写属性,或定义组成简写的单个属性,使作者能够定义增长和收缩因子。如果有多余的空间,您可以告诉 flex 子元素是否增加以填充该空间。如果没有足够的空间来以其定义的大小或默认大小将所有 flex 子元素容纳在 flex 容器中,则可以告诉 flex 子元素是否按比例收缩以适合该空间。

This is all done with the flex property, which is a shorthand property for flex-grow, flex-shrink, and flex-basis. While these three sub-properties can be used separately, it is highly recommended to always use the flex shorthand, for reasons we’ll soon cover.

所有这些都通过“ flex”属性完成,这是“ flex-grow”,“ flex-shrink”和“ flex-basis”的简写属性。虽然这三个子属性可以单独使用,但强烈建议始终使用“ flex”简写,我们很快将介绍其原因。

The flex property specifies the components of a flexible length: the “length” of the flex item being the length of the flex item along the main axis (see “Understanding axes” on page 579). When a box is a flex item, flex is consulted to determine the size of the box, instead of the main-axis size dimension property (height or width). The “components” of the flex property include the flex growth factor, flex shrink factor, and the flex basis.

“ flex”属性指定了 flex 长度的组成部分:flex 子元素的“长度”是 flex 子元素沿主轴的长度(请参见第 579 页的“理解轴”)。当盒子是 flex 子元素时,将使用“ flex”来确定盒子的尺寸,而不是主轴尺寸的维属性(“ height”或“ width”)。 “ flex”属性的“组成部分”包括flex growth factor, flex shrink factor, 以及 flex basis

The flex basis determines how the flex growth and shrink factors are implemented. As its name suggests, the flex-basis component of the flex shorthand is the basis on which the flex item determines how much it can grow to fill available space or how much it should shrink to fit all the flex items when there isn’t enough space. It’s the initial size of each flex item, and can be restricted to that specific size by specifying 0 for both the growth and shrink factors:

flex 基础决定了 flex 增长和收缩因子的实现方式。顾名思义,flex 简写的“ flex-basis”属性是 flex 子元素确定可增长多少以填充可用空间或应收缩多少以适应没有足够空间以容纳所有 flex 子元素的基础。它是每个 flex 子元素的初始尺寸,可以通过将增长和收缩因子都指定为 0 来限制为该特定尺寸:

.flexItem {
  width: 50%;
  flex: 0 0 200px;
}

In the preceding CSS, the flex item will have a main-axis size of exactly 200 pixels, as the flex basis is 200px, and it is allowed to neither grow nor shrink. Assuming that the main axis is horizontal, then the value of width (50%) is ignored. Similarly, a value for height would be ignored if the main axis were vertical.

在前面的 CSS 中,flex 子元素的主轴大小恰好为 200 像素,因为 flex 为“ 200px”,并且不允许增长或收缩。假设主轴是水平的,则忽略“ width”(“ 50%”)的值。同样,如果主轴是垂直的,则高度值将被忽略。

This override of height and width occurs outside the cascade, so you can’t even override the flex basis by adding !important to the height or width value of a flex item.

If the target of a selector is not a flex item, applying the flex property to it will have no effect.

如果选择器的目标不是 flex 子元素,则对其应用flex属性将无效。

It is important to understand the three components that make up the flex shorthand property in order to be able to use it effectively.

重要的是要理解组成 flex 简写属性的三个组成部分,以便能够有效地使用它。

12.12 The flex-grow Property

The flex-grow property defines whether a flex item is allowed to grow when there is available space, and, if it is allowed to grow and there is available space, how much will it grow proportionally relative to the growth of other flex item siblings.

“ flex-grow”属性定义了在有可用空间时是否允许 flex 子元素增长,如果允许增长并且有可用空间,则相对于其他 flex 子元素的增长,它会成比例地增长。

Declaring the growth factor via the flex-grow property is strongly discouraged by the authors of the specification itself. Instead, declare the growth factor as part of the ,flex shorthand. We’re only iscussing the property here to explore how growth works.

The value of flex-grow is always a number. Negative numbers are not valid. You can use non-integers if you like, just as long as they’re zero or greater. The value sets the flex growth factor, which determines how much the flex item will grow relative to the rest of the flex item siblings as the flex container’s free space is distributed.

“ flex-grow”的值始终是一个数字。负数是无效的。您可以根据需要使用非整数,只要它们为零或更大即可。该值设置 flex 增长因子,该因子决定了在分配 flex 容器的可用空间时,flex 子元素相对于其余 flex 子元素将增长多少。

If there is any available space within the flex container, the space will be distributed proportionally among the children with a nonzero positive growth factor based on the various values of those growth factors.

如果'flex'容器中有可用空间,则该空间将根据那些增长因子的各个值在具有非零的正增长因子的子元素之间按比例分配。

For example, assume a 750px wide horizontal flex container with three flex items, each set to width: 100px. That means there is a total of 300 pixels of space taken up by the flex items, leaving 450 pixels of “leftover” or available space (since 750 - 300 = 450). This is the first scenario shown in Figure 12-42. In that scenario, none of the flex items are permitted to grow.

例如,假设一个宽度为 750px 的水平 flex 容器,其中包含三个 flex 子元素,每个 flex 子元素均设置为宽度:100 像素。这意味着 flex 子元素总共占用 300 个像素的空间,剩下 450 个像素的“剩余”或可用空间(因为 750-300 = 450)。这是图 12-42 中所示的第一种情况。在那种情况下,任何 flex 子元素都不允许增长。

A variety of flex-growth scenarios

In the second scenario in Figure 12-42, only one of the flex items (the third) has been given a growth factor. The declaration we gave it is flex-grow: 1, but it could be literally any positive number the browser can understand. In this case, with two items having no growth factor and the third having a growth factor, all of the available space is given to the flex item with a growth factor. Thus, the third flex item gets all 450 pixels of available space added to it, arriving at a final width of 550 pixels. The width: 100px applied to it elsewhere in the styles is overridden.

在图 12-42 的第二种情况下,只有 flex 子元素之一(第三项)被赋予了增长因子。我们给它的声明是“ flex-grow:1”,但实际上它可以是浏览器可以理解的任何正数。在这种情况下,如果两个项目没有增长因子,而第三个项目具有增长因子,则将所有可用空间分配给具有增长因子的 flex 子元素。因此,第三个 flex 子元素将所有 450 像素的可用空间添加到其中,最终宽度为 550 像素。应用于他的宽度:100px 会被覆盖。

In the third and fourth scenarios, the same flex item widths result despite the differing flex growth factors. Let’s consider the third scenario, where the growth factors are 1, 1, and 3. The factors are all added together to get a total of 5. Each factor is then divided by that total to get a proportion. So here, the three values are each divided by five, yielding 0.2, 0.2, and 0.6.

在第三种情况和第四种情况下,尽管增长因子不同,但子元素的宽度相同。让我们考虑第三种情况,增长因子分别为 1、1 和 3。将所有因子相加在一起得出的总数为 5。然后将每个因子除以该总数得出的比例。因此在这里,三个值分别除以 5,得出 0.2、0.2 和 0.6。

These proportions are each multiplied by the available space to get the amount of growth. Thus:

这些比例分别乘以可用空间即可得到增长量。从而:

  1. 450 px × 0.2 = 90 px
  2. 450 px × 0.2 = 90 px
  3. 450 px × 0.6 = 270 px

Those are the growth portions added to each flex item’s starting width of 100 pixels. Thus, the final widths are 190 pixels, 190 pixels, and 370 pixels, respectively.

这些是添加到每个 flex 子元素起始宽度 100 像素的增长部分。因此,最终宽度分别为 190 像素,190 像素和 370 像素。

The fourth scenario has the same result, because the proportions are the same. Imagine for a moment that we altered the growth factors to be 0.5, 1, and 1.5. Now the math works out such that the first flex item gets one-sixth of the available space, the second gets a third, and the third gets half. This results in the flex items’ final widths being 175, 250, and 425 pixels, respectively. Had we declared growth factors of 0.1, 0.1, and 0.3, or 25, 25, and 75, or really any combination of numbers with a 1:1:3 correspondence, the result would have been identical.

第四种情况具有相同的结果,因为比例相同。想象一下,我们将生长因子更改为 0.5、1 和 1.5。现在,数学计算得出,第一个 flex 子元素获得了可用空间的六分之一,第二个 flex 子元素获得了三分之一,第三个 flex 子元素得到了一半。这样一来,flex 子元素的最终宽度分别为 175、250 和 425 像素。如果我们声明了 0.1、0.1 和 0.3 或 25、25 和 75 的增长因子,或者实际上是具有 1:1:3 对应关系的数字的任何组合,结果将是相同的。

As noted in “Minimum Widths” on page 613, if no width or flex basis is set, the flex basis defaults to auto, meaning each flex item basis is the width of its nonwrapped content. auto is a special value: it defaults to content unless the item has a width set on it, at which point the flex-basis becomes that width. The auto value is discussed in “Automatic Flex Basis” on page 635. Had we not set the width, in this example scenario, with our smallish font size, we would had more than 450 pixels of distributable space along the main axis.

如第 613 页的“最小宽度”中所述,如果未设置宽度或 flex 基础值,则 flex 单位默认为“自动”,这意味着每个 flex 子元素单位均为其未折行内容的宽度。 “ auto”是一个特殊值:除非项目上设置了宽度,否则默认为“ content”,此时 flex-basis 变为该宽度。在 635 页的“自动 flex 基础”中讨论了“自动”值。如果在本示例方案中,我们没有设置宽度,而字体尺寸很小,那么沿主轴行的可分配空间将超过 450 像素。

The main-axis size of a flex item is impacted by the available space, the growth factor of all the flex items, and the flex basis of the item. We have yet to cover flex basis, but that time is coming soon!

Now let’s consider a case where the flex items have different width values, as well as different growth factors. In Figure 12-43, in the second example, we have flex items that are 100 pixels, 250 pixels, and 100 pixels wide, with growth factors of 1, 1, and 3, respectively, in a container that is 750 pixels wide. This means we have 300 pixels of extra space to distribute among a total of 5 growth factors (since 750 - 450 = 300). Each growth factor is therefore 60 pixels (300 ÷ 5). This means the first and second flex items, with a flex-grow value of 1, will each grow by 60 pixels. The last flex item will grow by 180 pixels, since its flex-grow value is 3.

现在,考虑一种情况,其中 flex 子元素具有不同的“宽度”值以及不同的增长因子。在图 12-43 中,在第二个示例中,我们在 750 像素宽的容器中具有 100 像素,250 像素和 100 像素宽的 flex 子元素,分别具有 1、1、3 的增长因子。这意味着我们有 300 个像素的额外空间可分配到总共 5 个增长因子中(因为 750-450 = 300)。因此,每个增长因子均为 60 像素(300÷5)。这意味着“ flex-grow”值为“ 1”的第一和第二 flex 子元素将分别增长 60 像素。最后一个 flex 子元素将增加 180 像素,因为它的 flex-grow 值为 3。

Mixed widths and growth factors

To recap, the available space in the flex container, and the growth factors and final width of each flex item, are:

概括一下,flex 容器中的可用空间以及每个 flex 子元素的增长因子和最终宽度为:

Available space: 750px - (100px + 250px + 100px) = 300px
Growth factors: 1 + 1 + 3 = 5
Width of each growth factor: 300px ÷ 5 = 60px

When flexed, the width of the flex items, based on their original width and growth factors, become:

基于其原始宽度和增长因子应用后,子元素的宽度将变为:

item1 = 100px + (1 × 60px) = 160px
item2 = 250px + (1 × 60px) = 310px
item3 = 100px + (3 × 60px) = 280px

which adds up to 750 pixels.

总计 750 像素。

12.12.1 Growth Factors and the flex Property

The flex property takes up to three values—the growth factor, shrink factor, and basis. The first positive non-null numeric value, if there is one, sets the growth factor (i.e., the flex-grow value). When the growth and shrink factors are omitted in the flex value, the growth factor defaults to 1. However, if neither flex nor flex-grow are declared, the growth factor defaults to 0. Yes, really.

“ flex”属性最多包含三个值-生长因子,收缩因子和基数。第一个非空的正数值(如果有)设置增长因子(即“ flex-grow”值)。如果在“ flex”值中省略了增长因子和收缩因子,则增长因子默认为“ 1”。但是,如果未声明“ flex”或“ flex-grow”,则增长因子默认为“ 0”。是这样的。

Recall the second example in Figure 12-42, where the flex growth factors were 0, 0, and 1. Because we declared a value for flex-grow only, the flex basis was set to auto, as if we had declared:

回想一下图 12-42 中的第二个示例,其中 flex 增长因子为 0、0 和 1。因为我们仅声明了“flex 增长”的值,所以 flex 基础设置为“自动”,就好像我们有声明:

#example2 flex-item {
  flex: 0 1 auto;
}
#example2 flex-item:last-child {
  flex: 1 1 auto;
}

So that means the first two flex items had no growth factor, a shrink factor, and a flex basis of auto. Had we used flex in the examples in Figure 12-42 instead of illadvisedly using flex-grow, the flex basis in each case would be set to 0%, as if this had been done:

因此,这意味着前两个 flex 子元素没有增长因子,收缩因子和“自动”的 flex 基础。如果我们在图 12-42 的示例中使用了“ flex”,而不是偶然地使用了“ flex-grow”,那么每种情况下的 flex 基础都将被设置为“ 0%”,就像这样做了一样:

#example2 flex-item {
  flex: 0 1 0%;
}
#example2 flex-item:last-child {
  flex: 1 1 0%;
}

As the shrink factor defaults to 1 and the basis defaults to 0%, the following CSS is identical to the preceding snippet:

由于收缩因子默认为 1,基数默认为 0%,因此以下 CSS 与前面的代码段相同:

#example2 flex-item {
  flex: 0;
}
#example2 flex-item:last-child {
  flex: 1;
}

This would have the result shown in Figure 12-44. Compare this to Figure 12-42 to see how things have changed (or not).

结果将如图 12-44 所示。将此与图 12-42 进行比较,以了解情况如何变化(或没有变化)。

You may notice something odd in the first two scenarios: the flex basis been set to zero, and only the last flex item in the second scenario has a positive value for flex grow. Logic would seem that the widths of the 3 flex items should be 0, 0, and 750 pixels, respectively. But logic would also dictate that it makes no sense to have content overflowing its flex item if the flex container has the room for all the content, even if the basis is set to 0.

您可能会注意到在前两种情况下有些奇怪:将 flex 基准设置为零,并且只有第二种情况下的最后一个 flex 子元素的 flex 增长值为正。逻辑上,3 个 flex 子元素的宽度应该分别为 0、0 和 750 像素。但是逻辑上也会指出,如果 flex 容器具有容纳所有内容的空间,即使将基数设置为“ 0”,让内容溢出其 flex 子元素也没有意义。

The specification authors thought of this quandary. When the flex property declaration explicitly sets or defaults the flex-basis to 0% and a flex item’s growth factor is 0, the length of the main axis of the non-growing flex items will shrink to the smallest length the content allows, or smaller. In Figure 12-44, that minimum length is the width of the widest sequence of letters, “flex:” (including the colon).

规范的作者想到了这个难题。当flex属性声明将 flex-basis 显式设置或默认为'0%'且 flex 子元素的增长因子为'0'时,非增长 flex 子元素的主轴长度将缩小到内容允许的最小长度或更小。在图 12-44 中,最小长度是最宽字母序列“ flex:”(包括冒号)的宽度。

Flex sizing when using the flex shorthand

As long as a flex item has a visible overflow and no explicitly set value for min-width (or min-height for vertical main-axes), the minimum width (or minimum height) will be the smallest width (or height) that the flex item needs to be to fit the content or the declared width (or height), whichever is smaller.

只要 flex 子元素有可见的溢出并且没有为 min-width(或垂直主轴的 min-height)明确设置值,最小的 width(或最小的 height)就是 flex 子元素要适合内容或声明的宽度(或高度)的最小宽度(或高度),以较小者为准。

If all items are allowed to grow, and the flex basis for each flex item is 0%, then all of the space, rather than just excess space, is distributed proportionally based on the growth factors. In the third example in Figure 12-44, two flex items have growth factors of one, and one flex item has a growth factor of three. We thus have a total of five growth factors:

如果允许所有项目增长,并且每个 flex 子元素的 flex 基础为“ 0%”,则将根据增长因子按比例分配所有的空间,而不仅仅是多余的空间。在图 12-44 的第三个示例中,两个 flex 子元素的增长因子为 1,一个 flex 子元素的增长因子为 3。因此,我们共有五个增长因素:

(2 × 1) + (1 × 3) = 5

With 5 growth factors, and a total of 750 pixels, each growth factor is worth 150 pixels:

有 5 个生长因子,总共 750 像素,每个生长因子值 150 像素:

750px ÷ 5 = 150px

While the default flex item size was 100 pixels, the flex basis of 0% overrides that, leaving us with 2 flex items at 150 pixels each and the last flex item with a width of 450 pixels:

当默认的 flex 子元素大小为 100 像素时,“ 0%”的 flex 基础会覆盖它,从而为我们留出 2 个 flex 子元素,每个 flex 子元素分别为 150 像素,最后一个 flex 子元素的宽度为 450 像素:

1 × 150px = 150px
3 × 150px = 450px

Similarly, in the last example of Figure 12-44, with two flex items having growth factors of 0.5, and one flex item having a growth factor of 1.5, we have a total of 2.5 growth factors:

同样,在图 12-44 的最后一个示例中,两个 flex 子元素的生长因子为 0.5,一个 flex 子元素的生长因子为 1.5,我们总共有 2.5 个生长因子:

(2 × 0.5) + (1 × 1.5) = 2.5

With 2.5 grows factors, and a total of 750 pixels, each growth factor is worth 300 pixels:

有 2.5 个生长因子,和总共有 750 像素,每个生长因子 价值 300 像素。

750px ÷ 2.5 = 300px

While the default flex item size was 100 pixels, the flex basis of 0% overrides that, leaving us with 2 flex items at 150 pixels each and the last flex item with a width of 450 pixels:

虽然默认的 flex 子元素大小为 100 像素,但 0%的 flex 基础会覆盖该值,从而为我们提供 2 个 flex 子元素(每个 150 像素)和最后一个 flex 子元素(宽度为 450 像素):

0.5 × 300px = 150px
1.5 × 300px = 450px

Again, this is different from declaring only flex-grow, because that means the flex basis defaults to auto. In that case, only the extra space, not all the space, is distributed proportionally. When using flex, on the other hand, the flex basis is set to 0%, so the flex items grow in proportion to the total space, not just the leftover space. The difference is illustrated in Figure 12-45.

同样,这与仅声明“ flex-grow”不同,因为这意味着 flex 基础默认为“ auto”。在那种情况下,仅多余的空间而不是所有的空间按比例分配。另一方面,当使用“ flex”时,flex 基础设置为“ 0%”,因此 flex 子元素与总空间成比例增长,而不仅仅是剩余空间。差异如图 12-45 所示。

Flex sizing di�erences between using flex and flex-grow

Now let’s talk about flex shrinking factors, which are in some ways the inverse of flex growth factors, but are in other ways different.

现在,我们来讨论flex收缩因子,在某些方面与增长因子相反,但在其他方面则有所不同。

12.13 The flex-shrink Property

The <flex-shrink> portion of the flex shorthand property specifies the flex shrink factor. It can also be set via the flex-shrink property.

flex 简写属性的<flex-shrink>部分指定了“ flex 收缩系数”。也可以通过 flex-shrink 属性设置。

Declaring the shrink factor via the flex-shrink property is strongly discouraged by the authors of the specification itself. Instead, declare the shrink factor as part of the flex shorthand. We’re only discussing the property here in order to explore how shrinking works.

The shrink factor determines how much a flex item will shrink relative to the rest of its flex-item siblings when there isn’t enough space for them all to fit, as defined by their content and other CSS properties. When omitted in the shorthand flex property value or when both flex and flex-shrink are omitted, the shrink factor defaults to 1. Like the growth factor, the value of flex-shrink is always a number. Negative numbers are not valid. You can use non-integer values if you like, just as long as they’re greater than zero.

收缩系数决定了当没有足够的空间容纳所有 flex 子元素时,flex 子元素相对于其余同级的 flex 子元素会收缩多少,具体取决于其内容和其他 CSS 属性。如果在简写的“ flex”属性值中省略,或者同时省略了“ flex”和“ flex-shrink”,则收缩系数默认为“ 1”。像增长因子一样,“ flex-shrink”的值始终是一个数字。负数是无效的。您可以根据需要使用非整数值,只要它们大于零即可。

Basically, the shrink factor defines how “negative available space” is distributed when there isn’t enough room for the flex items and the flex container isn’t allowed to otherwise grow or wrap. This is illustrated in Figure 12-46.

基本上,收缩因子定义了当 flex 子元素没有足够的空间并且不允许 flex 容器增长或折行时,“负可用空间”的分配方式。如图 12-46 所示。

A variety of flex shrinking scenarios

Figure 12-46 is similar to Figure 12-42, except the flex items are set to width: 300px instead of 100 pixels. We still have a 750-pixels-wide flex container. The total width of the 3 items is 900 pixels, meaning the content starts out 150 pixels wider than the parent flex container. If the items are not allowed to shrink or wrap (see “Wrapping Flex Lines” on page 576), they will burst out from the fixed-size flex container. This is demonstrated in the first example in Figure 12-46: those items will not shrink because they have a zero shrink factor. Instead, they overflow the flex container.

图 12-46 与图 12-42 相似,不同之处在于 flex 子元素被设置为width:300px而不是 100 像素。我们还有一个 750 像素宽的 flex 容器。这 3 个项目的总宽度为 900 像素,这意味着内容开始时比父 Flex 容器宽 150 像素。如果不允许子元素收缩或折行(请参见第 576 页的“Wrapping Flex Lines”),它们将从固定尺寸的容器中溢出。这在图 12-46 的第一个示例中得到了证明:这些项目不会收缩,因为它们的收缩系数为零。相反,它们会使 flex 容器溢出。

In the second example in Figure 12-46, only the last flex item is set to be able to shrink. The last flex item is thus forced to do all the shrinking necessary to enable all the flex items to fit within the flex container. With 900 pixels worth of content needing to fit into our 750-pixel container, we have 150 pixels of negative available space. The 2 flex items with no shrink factor stay at 300 pixels wide. The third flex item, with a positive value for the shrink factor, shrinks 150 pixels, to end up 150 pixels wide. This enables the 3 items to fit within the container. (In this example the shrink factor was 1, but had it been 0.001 or 100 or 314159.65 or any other positive number the browser could understand, the result would be the same.)

在图 12-46 的第二个示例中,仅将最后一个 flex 子元素设置为能够收缩。因此,最后一个 flex 子元素被迫进行所有必要的收缩,以使所有 flex 子元素能够放入 flex 容器中。 750 像素的容器需要容纳 900 像素的内容,因此我们有 150 像素的负可用空间。没有收缩因子的 2 个 flex 子元素保持 300 像素宽。第三个 flex 子元素的收缩因子为正值,它会收缩 150 像素,最终达到 150 像素的宽度。这使 3 个项目可以放入容器中。 (在此示例中,收缩因子为“ 1”,但是如果它是“ 0.001”或“ 100”或“ 314159.65”或浏览器可以理解的任何其他正数,则结果将相同。)

In the third example, we have positive shrink factors for all three flex items:

在第三个示例中,我们对所有三个 flex 子元素都有正的收缩因子:

#example3 flex-item {
  flex-shrink: 1;
}
#example3 flex-item:last-child {
  flex-shrink: 3;
}

As this is the only one of the three flex shorthand properties we declared, this means the flex items will behave as if we had declared the following:

因为这是我们声明的三个flex简写属性中的唯一一个,所以这意味着 flex 子元素的行为就像我们声明了以下内容一样:

#example3 flex-item {
  flex: 0 1 auto; /* growth defaults to 0, basis to auto */
}
f#example3 flex-item:last-child {
  flex: 0 3 auto;
}

If all items are allowed to shrink, as is the case here, the shrinking is distributed proportionally based on the shrink factors. This means the larger a flex item’s shrink factor, as compared to the shrink factors of its sibling flex items, the more the item will shrink in comparison.

如果允许所有项目都缩小,就像此处的情况,则根据缩小因子按比例分配缩小。这意味着与其同级 flex 子元素的收缩因子相比, flex 子元素的收缩因子越大,该项目的收缩就越大。

With a parent 750 pixels wide, and 3 flex items with a width of 300 pixels, there are 150 “negative space” pixels that need to be shaved off the flex items that are allowed to shrink (which is all of them in this example). With two flex items having a shrink factor of 1, and one flex item having a shrink factor of 3, we have a total of five shrink factors:

父级宽度为 750 像素,而 3 个 flex 子元素的宽度为 300 像素,则需要去除 150 个“负空间”像素,在允许收缩的 flex 子元素上(在此示例中所有flex子元素全部包含) 。对于两个 flex 收缩系数为 1 的 flex 子元素,以及一个 flex 收缩系数为 3 的 flex 子元素,我们总共有五个 收缩系数:

(2 × 1) + (1 × 3) = 5

With 5 shrink factors, and a total of 150 pixels needing to be shaved off all the flex items, each shrink factor is worth 30 pixels:

有 5 个收缩因子,并且需要从所有 flex 子元素上去除总共 150 个像素,所以每个收缩因子值 30 像素:

150px ÷ 5 = 30px

The default flex item size was 300 pixels, leading us to have 2 flex items with a width of 270 pixels each and the last flex item having a width of 210 pixels, which totals 750 pixels:

默认的 flex 子元素大小为 300 像素,这使我们拥有 2 个每个 flex 子元素的宽度为 270 像素的 flex 子元素,最后一个 flex 子元素的宽度为 210 像素,总计 750 像素:

300px - (1 × 30px) = 270px
300px - (3 × 30px) = 210px

The following CSS produces the same outcome: while the numeric representation of the shrink factors are different, they are proportionally the same, so the flex item widths will be the same:

以下 CSS 产生相同的结果:虽然收缩系数的数字表示形式不同,但它们的比例相同,因此 flex 子元素宽度将相同:

flex-item {
  flex: 1 0.25 auto;
}
flex-item:last-child {
  flex: 1 0.75 auto;
}

Note that the flex items in these examples will shrink to 210, 210, and 270 pixels, respectively, as long as the content (like media objects or non-wrappable text) within each flex item is not wider than 210, 210, or 270 pixels, respectively. If the flex item contains content that cannot wrap or otherwise shrink in the main-dimension, the flex item will not shrink any further.

请注意,这些示例中的 flex 子元素将分别缩小到 210、210 和 270 像素,只要每个 flex 子元素中的内容(如媒体对象或不可折行的文本)不宽于 210、210 及 270 像素。如果 flex 子元素包含无法在主轴中折行或收缩的内容,则 flex 子元素将不会进一步收缩。

Suppose that the first flex items contain a 300-pixels-wide image. That first flex item can not shrink, and other flex items can shrink, therefore it will not shrink, as if it had a null shrink factor. In this case, the first item would be 300 pixels, with the 150 pixels of negative space distributed proportionally based on the shrink factors of the second and third flex items.

假设第一个 flex 子元素包含一个 300 像素宽的图像。该第一个 flex 子元素不能收缩,其他 flex 子元素可以收缩,因此它不会收缩,就好像它的收缩因子为空。在这种情况下,第一项将为 300 像素,负像素空间的 150 像素将根据第二和第三折行项的收缩因子成比例分布。

That being the case, we have 4 unimpeded shrink factors (one from the second flex item, and three from the third) for 150 pixels of negative space, with each shrink factor being worth 37.5 pixels. The flex items will end up 300, 262.5, and 187.5 pixels respectively, for a total of 750 pixels. The result is illustrated in Figure 12-47:

在这种情况下,对于 150 像素的负空间,我们有 4 个不受阻碍的收缩因子(一个来自第二个 flex 子元素,三个来自第三个 flex 子元素),每个收缩因子值 37.5 像素。 flex 子元素将最终为 300、262.5 和 187.5 像素,总共 750 像素。结果如图 12-47 所示:

item1 = 300px - (0 × 37.5px) = 300.0px
item2 = 300px - (1 × 37.5px) = 262.5px
item3 = 300px - (3 × 37.5px) = 187.5px

Shrinking being impeded by flex item content

Had the image been 296 pixels wide, that first flex item would have been able to shrink by 4 pixels. The remaining 146 pixels of negative space would then be distributed the among the 4 remaining shrink, yielding 36.5 pixels per factor. The flex items would then be 296, 263.5, and 190.5 pixels wide, respectively.

如果图像的宽度为 296 像素,则第一个 flex 子元素将能够缩小 4 像素。然后,将剩余的 146 个负空间像素分配给剩余的 4 个缩小区域,每个系数产生 36.5 个像素。然后,flex 子元素的宽度分别为 296、263.5 和 190.5 像素。

If all three flex items contained non-wrappable text or media 300 pixels or wider, the none of the three flex items would not shrink, appearing similar to the first example in Figure 12-46.

如果所有三个 flex 子元素都包含不可折叠的文本或媒体对象, 300 像素或更宽,则三个 flex 子元素都不会缩小,这类似于图 12-46 中的第一个示例。

12.13.1 Proportional Shrinkage Based on Width and Shrink Factor

The preceding code examples were fairly simple because all the flex items started with the same width. But what if the widths were different? What if the first and last flex items had a width of 250 pixels and the middle flex item had a width of 500 pixels, as shown in Figure 12-48?

前面的代码示例非常简单,因为所有 flex 子元素均以相同的宽度开头。但是如果宽度不同怎么办?如果第一个和最后一个 flex 子元素的宽度为 250 像素,中间的 flex 子元素的宽度为 500 像素,如图 12-48 所示,该怎么办?

Flex items shrink proportionally relative to their shrink factor

Flex items shrink proportionally relative to both the shrink factor and the flex item’s width, with the width often being the width of the flex item’s content with no wrapping. In Figure 12-48, we are trying to fit 1,000 pixels into a 750 pixels-width flex container. We have an excess of 250 pixels to be removed from 5 shrink factors.

flex 子元素相对于“收缩因子”和 flex 子元素的宽度均按比例缩小,宽度通常是 flex 子元素内容的宽度,没有折行的情况下。在图 12-48 中,我们尝试将 1,000 个像素放入 750 像素宽度的 flex 容器中。我们需要从 5 个缩小因子中删除 250 个像素。

If this were a flex-grow situation, we would simply divide 250 pixels by 5, allocating 50 pixels per growth factor. If we were to shrink that way, we would get flex items 200, 550, and 100 pixels wide, respectively. But that’s not how shrinking actually works.

如果这种情况有 flex-grow 值,我们可以简单的把250像素分成5份,每个增长因子值 50 像素。如果我们以这种方式收缩,我们可以得到200, 550, 100 像素宽的 flex 子元素。但这并不是收缩因子实际作用的方式。

Here, we have 250 pixels of negative space to proportionally distribute. To get the shrink factor proportions, we divide the negative space by the total of the flex items’ widths (more precisely, their lengths along the main axis) times their shrink factors:

在这里,我们有 250 个像素的负空间按比例分布。为了获得收缩因子的比例,我们将负值空间除以 flex 子元素宽度的总和(更确切地说,是它们沿主轴的长度)乘以其收缩因子:

// 公式

Using this equation, we find the shrink percentage:

使用以下公式,我们得出收缩百分比:

= 250px ÷ ((250px × 1) + (500px × 1) + (250px × 3))
= 250px ÷ 1500px
= 0.166666667 (16.67%)

When we reduce each flex item by 16.67% times the value of flex-shrink, we end up with flex items that are reduced by:

当我们将每个 flex 子元素减少“ flex-shrink”值的 16.67%时,最终得到的 flex 子元素减少了:

item1 = 250px × (1 × 16.67%) = 41.67px
item2 = 500px × (1 × 16.67%) = 83.33px
item3 = 250px × (3 × 16.67%) = 125px

Each reduction is then subtracted from the starting sizes of 250, 500, and 250 pixels, respectively. We thus end up with flex items that are 208.33, 416.67, and 125 pixels wide.

然后,分别从 250、500 和 250 像素的起始大小中减去每个缩小值。因此,我们最终得到了 208.33、416.67 和 125 像素宽的 flex 子元素。

12.13.2 Differing Bases

With zero shrink factor, if both the width and flex basis of a flex item at auto, its content will not wrap, even when you think it should. Conversely, any positive shrink value enables content to wrap. Because shrinking is proportional based on shrink factor, if all the flex items have similar shrink factors, the content should wrap over a similar number of lines.

如果收缩因子为零,则如果将 flex 子元素的宽度和 flex 基础都设置为“自动”,则即使您认为应该,其内容也不会收缩。相反,任何正收缩值都可以使内容收缩。因为收缩是基于收缩因子成比例的,所以如果所有 flex 子元素都具有相似的收缩因子,则内容应换行相似的行数。

In the three examples shown in Figure 12-49, the flex items do not have a declared width. Therefore, the width is based on the content, because width defaults to auto. The flex container has been made 520 pixels wide, instead of of our usual 750 pixels.

在图 12-49 所示的三个示例中,flex 子元素没有声明宽度。因此,宽度基于内容,因为“宽度”默认为“自动”。 flex 容器的宽度已设为 520 像素,而不是我们通常的 750 像素。

Flex items shrink proportionally relative to their shrink factor and content

Note that in the first example, where all the items have the same flex-shrink value, all content wraps over four lines. In the second example, the first flex item has a shrink factor half of value of the other flex items, so it wraps the content over (roughly) half the number of lines. This is the power of the shrink factor.

请注意,在第一个示例中,所有项目均具有相同的“ flex-shrink”值,所有内容均折成四行。在第二个示例中,第一个 flex 子元素的收缩因子是其他 flex 子元素的一半,因此它将内容收缩在(大约)行数的一半上。这就是收缩因子的力量。

In the third example, with no shrink factor, the text doesn’t wrap at all and the flex items overflow the container by quite a bit.

在第三个示例中,由于没有收缩因子,因此文本完全不会收缩,而 flex 子元素会大量溢出容器。

As of late 2017, this “line-balancing” and refusal-to-wrap behavior was not consistent across browsers. If you see different results when trying this out for yourself, that may be why.

Because the flex property’s shrink factor reduces the width of flex items proportionally, the number of lines of text in the flex items will grow or shrink as the width shrinks or grows, leading to similar height content within sibling flex items when the shrink factors are similar.

因为flex属性的收缩因子会按比例减小 flex 子元素的宽度,所以 flex 子元素中的文本行数会随着宽度的缩小或增长而增加或收缩,从而导致同级 flex 子元素中的相似高度内容相似。

In the examples, take the contents of the flex items to be 280, 995, and 480 pixels, respectively—which is the width of the non-wrapping flex items in the third example (as measured by the developer tools, then rounded to make this example a little simpler). This means we have to fit 1,755 pixels of content into a 520 pixels-wide flex container by shrinking the flex items proportionally based on their shrink factor. This means we have 1,235 pixels of negative available space to proportionally distribute.

在示例中,将 flex 子元素的内容分别设置为 280、995 和 480 像素-这是第三个示例中非收缩 flex 子元素的宽度(由开发人员工具测量,然后四舍五入为这个例子更简单)。这意味着我们必须根据其收缩因子按比例缩小 flex 子元素,以将 1755 像素的内容装入 520 像素宽的 flex 容器中。这意味着我们有 1,235 像素的负可用空间要按比例分配。

Remember that you can’t rely on web inspector tools to figure out shrink factors for production. We’re going through this exercise to understand how shrink factors work. If minutia isn’t your thing, feel free to jump to “The flex-basis Property” on page 633.

In our first example, the flex items will end up with the same, or approximately the same, number of text lines. This is because flex items shrink proportionally, based on the width of their content.

在我们的第一个示例中,flex 子元素将以相同或近似相同的文本行数结束。这是因为 flex 子元素根据其内容的宽度成比例地缩小。

We didn’t declare any widths, and therefore can’t simply use an explicit element width as the basis for our calculations, as we did in the previous examples. Rather, we distribute the 1,235 pixels of negative space proportionally based on the widths of the content—280, 995, and 480 pixels, respectively. We determine 520 is 29.63% of 1,755. To determine the width of each flex item with a shrink factor of 1, we multiply the content width of each flex item by 29.63%:

我们没有声明任何宽度,因此不能像前面的示例一样简单地使用显式元素宽度作为计算的基础。相反,我们根据内容的宽度(分别为 280、995 和 480 像素)按比例分配负空间的 1,235 像素。我们确定 520 是 1,755 的 29.63%。要确定收缩系数为 1 的每个 flex 子元素的宽度,我们将每个 flex 子元素的内容宽度乘以 29.63%:

item1 = 280px × 29.63% = 83px
item2 = 995px × 29.63% = 295px
item3 = 480px × 29.63% = 142px

With the default of align-items: stretch (see “Aligning Items” on page 596), a three-column layout will have three columns of equal height. By using a consistent shrink factor for all flex items, you can indicate that the actual content of these three flex items should be of approximately equal height—though, by doing this, the widths of those columns will not necessarily be uniform.

默认使用“ align-items:Stretch”(请参见第 596 页的“Aligning Items”),三列布局将具有三列等高的列。通过对所有 flex 子元素使用一致的收缩因子,可以指示这三个 flex 子元素的实际内容应该具有近似相等的高度,尽管这样做,这些列的宽度不一定是一致的。

In the second example in Figure 12-49, the flex items don’t all have the same shrink factor. The first flex item will, proportionally, shrink half as much as the others. We start with the same widths: 280, 995, and 480 pixels, respectively, but their shrink factors are 0.5, 1.0, and 1.0. As we know the widths of the content, the shrink factor (X) can be found mathematically:

在图 12-49 的第二个示例中,flex 子元素的收缩因子并不相同。第一个 flex 子元素将按比例缩小一半。我们以相同的宽度开始:分别为 280、995 和 480 像素,但它们的收缩因子分别为 0.5、1.0 和 1.0。我们知道内容的宽度,可以从数学上找到收缩率(X):

280px + 995px + 480px = 1615px
(0.5 × 280px) + (1 × 995px) + (1 × 480px) = 1235px
X = 1235px ÷ 1615px = 0.7647

We can find the final widths now that we know the shrink factor. If the shrink factor is 76.47%, it means that item2 and item3 will be shrink by that amount, whereas item1 will shrink by 38.23% (because its flex-shrink value is half the others). The amount of shrinkage in each case is, rounded off to the nearest whole number:

现在我们知道收缩因子,就可以找到最终宽度。如果收缩因子为 76.47%,则意味着“ item2”和“ item3”将缩小该数量,而“ item1”将缩小 38.23%(因为其“ flex-shrink”值为其他值的一半)。每种情况下的收缩量均四舍五入至最接近的整数:

item1 = 280px × 0.3823 = 107px
item2 = 995px × 0.7647 = 761px
item3 = 480px × 0.7647 = 367px

Thus, the final widths of the flex items is:

因此,flex 子元素的最终宽度为:

item1 = 280px - 107px = 173px
item2 = 995px - 761px = 234px
item3 = 480px - 367px = 113px

The total combined widths of these 3 flex items is 520 pixels.

这 3 个 flex 子元素的总合并宽度为 520 像素。

Adding in varying shrink and growth factors makes it all a little less intuitive. That’s why you likely want to always declare the flex shorthand, preferably with a width or basis set for each flex item. If this doesn’t make sense yet, don’t worry; we’ll cover a few more examples of shrinking as we discuss flex-basis.

加上各种不同的收缩和增长因子,使其变得不太直观。这就是为什么您可能希望始终声明 flex 简写的原因,最好为每个 flex 子元素设置宽度或基数。如果这还没有意义,请不要担心;我们将在讨论“flex 基础”时再介绍一些缩小的示例。

12.13.3 Responsive Flexing

Allowing flex items to shrink proportionally like this allows for responsive objects and layouts that can shrink proportionally without breaking.

像这样允许 flex 子元素按比例收缩,可以使响应对象和布局按比例收缩而不会破裂。

For example, you can create a three-column layout that smartly grows and shrinks without media queries, as shown on a wide screen in Figure 12-50 and narrow screen in Figure 12-51:

例如,您可以创建一个三列布局,无需媒体查询即可智能地增长和收缩,如图 12-50 的宽屏和图 12-51 的窄屏所示:

nav {
  flex: 0 1 200px;
  min-width: 150px;
}
article {
  flex: 1 2 600px;
}
aside {
  flex: 0 1 200px;
  min-width: 150px;
}

A wide flexbox layout

A narrow flexbox layout

In this example, if the viewport is greater than 1,000 pixels, only the middle column grows because only the middle column was provided with a positive growth factor. We also dictated that below the 1,000-pixels-wide mark, the columns all shrink.

在此示例中,如果视口大于 1,000 像素,则仅中间列会增长,因为只有中间列具有正的增长因子。我们还说明,在 1000 像素宽以下的标记下,所有列都会缩小。

Let’s take it bit by bit. The nav and aside elements have the following CSS:

让我们一点一点看。 nav 和 aside 元素具有以下 CSS:

flex: 0 1 200px;
min-width: 150px;

This means they don’t grow from their basis, but they can shrink at equal rates. This means they’ll have the width of their flex basis by default. If they do need to shrink, they’ll shrink down to a minimum width of 150px and then stop shrinking. However, if either one has an element that’s more than 150 pixels wide, whether it’s an image or a run of text, it will stop shrinking as soon as it reaches the width of that bit of content. Suppose a 180-pixel image got dropped into the aside element. It would stop shrinking as soon as it reached 180 pixels wide. The nav would keep shrinking down to 150 pixels.

这意味着它们不会从基础上增长,但是它们可以以相等的速度收缩。这意味着默认情况下,它们将具有其 flex 基础的宽度。如果确实需要缩小,则将其缩小到最小宽度“ 150px”,然后停止缩小。但是,如果其中一个元素的宽度超过 150 像素(无论是图像还是文本),则一旦达到该内容宽度,它就会停止缩小。假设将一个 180 像素的图像放入了“ aside”元素中。一旦达到 180 像素宽,它将停止缩小。 但nav 将继续缩小到 150 像素。

The main element, on the other hand, has these styles:

另一方面,main元素具有以下样式:

flex: 1 2 600px;

Thus, the main element can grow if there’s space for it to do so. Since it’s the only flex item that can grow, it gets all the growth. That means that, given a browser window 1,300 pixels wide, the two side columns will be 200 pixels wide each, leaving 900 pixels of width for the center column. In shrinking situations, the center column will shrink twice as fast as the other two elements. Thus, if the browser window is 900 pixels wide, the side columns will each be 175 pixels wide, and the center column 550 pixels wide.

因此,如果有足够的空间可以容纳main元素,那么它可以增长。由于它是唯一可以增长的 flex 子元素,因此可以实现所有增长。这意味着,如果浏览器窗口的宽度为 1300 像素,则两个侧栏的宽度将分别为 200 像素,中间栏的宽度为 900 像素。在缩小的情况下,中心列的缩小速度是其他两个元素的两倍。因此,如果浏览器窗口的宽度为 900 像素,则侧栏的宽度均为 175 像素,中间栏的宽度为 550 像素。

Once the windows reaches 800 pixels wide, the side columns will reach their min-width values of 150px. From then on, any narrowing will all be taken up by the center column.

一旦窗口达到 800 像素宽,边栏将达到其“最小宽度”值“ 150px”。从那时起,任何缩小都将由中间列承担。

Just to be clear, you are not require to use pixels in these situation. You don’t even have to use the same unit measures for various flex bases. The previous example could be rewritten like this:

请注意,在这种情况下不需要使用像素。您甚至不必为各种 flex 底座使用相同的单位度量。前面的示例可以这样重写:

nav {
  flex: 0 1 20ch;
  min-width: 15vw;
}
article {
  flex: 1 2 45ch;
}
aside {
  flex: 0 1 20ch;
  min-width: 10ch;
}

We won’t go through all the math here, but the general approach is to set flex bases on character widths for improved readability, with some lower limits based on character widths and others on viewport width.

我们不会在这里进行所有数学运算,但是一般的方法是基于字符宽度设置 flex 基础以提高可读性,其中一些下限基于字符宽度,而另一些则基于视口宽度。

Flexbox can be useful for one-dimensional page layout like the one shown in this section, where there are only three columns in a line. For anything more complex, or for a more powerful set of options, use Grid layout. (See Chapter 13.)

12.14 The flex-basis Property

As we’ve already seen, a flex item’s size is impacted by its content and box-model properties and can be reset via the three components of the flex property. The <flex-basis> component of the flex property defines the initial or default size of flex items, before extra or negative space is distributed—before the flex items are allowed to grow or shrink according to the growth and shrink factors. It can also be set via the flex-basis property.

正如我们已经看到的,flex 子元素的大小受其内容和框模型属性的影响,可以通过“flex”属性的三个组成部分进行重置。 “ flex”属性的“ ”组件定义了 flex 子元素的初始大小或默认大小,然后才分配额外的空间或负的空间-在允许 flex 子元素根据增长和收缩因素进行增长或收缩之前。也可以通过 flex-basis 属性设置。

Declaring the flex basis via the flex-basis property is strongly discouraged by the authors of the specification itself. Instead, declare the flex basis as part of the flex shorthand. We’re only discussing the property here in order to explore flex basis.

The flex basis determines the size of a flex item’s element box, as set by box-sizing. By default, when a block-level element is not a flex item, the size is determined by the size of its parent, content, and box-model properties. When no size properties are explicitly declared or inherited, the size defaults to its individual content, border, and padding, which is 100% of the width of its parent for block-level elements.

flex 基础决定 flex 子元素的元素框的大小,该尺寸由“ box-sizing”设置。默认情况下,当块级元素不是 flex 子元素时,其大小由其父项,内容和框模型属性的大小确定。如果没有显式声明或继承任何大小属性,则大小默认为其单独的内容,边框和填充,这是块级父元素大小的 100%。

The flex basis can be defined using the same length value types as the width and height properties; for example, 5vw, 12%, and 300px.

可以使用与 width 和 height 属性相同的长度值类型来定义 flex 基础。例如“ 5vw”,“ 12%”和“ 300px”。

The universal keyword initial resets the flex basis to the initial value of auto, so you might as well declare auto. In turn, auto evaluates to the width (or height), if declared. If the value of width (or height) is set to auto, then the value of flex-basis is evaluated to content.

通用关键字“ initial”将 flex 基础重置为“ auto”的初始值,因此您最好声明“ auto”。反之,如果声明,auto将求值为width(或height)。如果将 width 或 height 的值设置为 auto,那么 flex-basis 的值将评估为 content。

12.14.1 The content Keyword

The content keyword is not supported in most browsers at the time of this writing (late 2017), with the exception of Microsoft Edge 12+, but is equal to the width or height of the content. When content is used and supported, the basis is the size of the flex item’s content; that is, the length of the main-axis size of the longest line of content or widest (or tallest) media object.

在撰写本文时(2017年末),大多数浏览器均不支持content关键字,但Microsoft Edge 12+除外,但它等于内容的宽度或高度。使用和支持content时,基础是弹性项目内容的大小;也就是说,最长的内容行或最宽(或最高)的媒体对象的主轴大小的长度。

Until support is complete, flex-basis: content; can be easily polyfilled, as it is the equivalent of declaring flex-basis: auto; width: auto; on that flex item, or flex-basis: auto; height: auto; if the main-dimension is vertical. Unfortunately, using content in the flex shorthand in nonsupporting browsers invalidates the entire declaration (see “Understanding axes” on page 579).

直到完成支持之后,可以轻松地填充“ flex-basis:content;”,因为这相当于声明 flex-basis: auto; width: auto;在该 flex 子元素上,或如果主尺寸是垂直的,相当于flex-basis: auto; height: auto;。不幸的是,在不支持的浏览器中使用flex简写中的content会使整个声明无效(请参见第 579 页的 “Understanding axes”)。

The value of content is basically what we saw in the third example in Figure 12-49, and is shown in Figure 12-52.

“ content”的值基本上是我们在图 12-49 的第三个示例中看到的值,如图 12-52 所示。

Sizing flex items on a content basis

In the first and third examples in Figure 12-52, the width of the flex item is the size of the content; and the flex basis is that same size. In the first example, the flex items’ width and basis are approximately 132 pixels. The total width of the 3 flex items side by side is 396 pixels, fitting easily into the parent container.

在图 12-52 的第一个和第三个示例中,flex 子元素的宽度是内容的大小;而 flex 的基础是相同的尺寸。在第一个示例中,flex 子元素的宽度和基础约为 132 像素。并排放置的 3 个 flex 子元素的总宽度为 396 像素,可轻松装入父容器。

In the third example, we have set a null shrink factor (0): this means the flex items cannot shrink, so they won’t shrink or wrap to fit into the fixed-width flex container. Rather, they are the width of their nonwrapped text. That width is also the value of the flex basis. The flex items’ width and basis are approximately 309, 1,037 pixels, and 523 pixels, respectively. You can’t see the full width of the second flex item or the third flex item at all, but they’re in the chapter files.

在第三个示例中,我们设置了一个空的收缩因子(0):这意味着 flex 子元素无法收缩,因此它们不会收缩或折行以适合固定宽度的 flex 容器。相反,它们是未折行文本的宽度。该宽度也是 flex 基础的值。flex 子元素的宽度和基础分别约为 309、1,037 像素和 523 像素。您根本看不到第二个 flex 子元素或第三个 flex 子元素的完整宽度,但它们在章节文件中。

The second example contains the same content as the third example, but the flex items are defaulting to a shrink factor of 1, so the text in this example wraps because the flex items can shrink. Thus, while the width of the flex item is not the width of the content, the flex basis—the basis by which it will proportionally shrink—is the width of the items’ contents.

第二个示例包含与第三个示例相同的内容,但是 flex 子元素的默认收缩因子为 1,因此此示例中的文本自动换行,因为 flex 子元素可以收缩。因此,flex 子元素的宽度不是内容的宽度,而 flex 基础(将按比例缩小的基础)是项目内容的宽度。

12.14.2 Automatic Flex Basis

When set to auto, whether explicitly or by default, flex-basis is the same as the main-axis size of the element, had the element not been turned into a flex item. For length values, flex-basis resolves to the width or height value, with the exception that when the value of the width or height is auto, the flex basis value falls back to content.

当设置为“ auto”时,无论是显式还是默认设置,“ flex-basis”与元素的主轴尺寸相同,前提是该元素未转换为 flex 子元素。对于长度值,flex-basis 解析为widthheight值,不同之处在于,当widthheight的值为 auto 时,flex 基础值回落为`content'。

When the flex basis is auto, and all the flex items can fit within the parent flex container, the flex items will be their pre-flexed size. If the flex items don’t fit into their parent flex container, the flex items within that container will shrink proportionally based on their non-flexed main-axis sizes (unless the shrink factor is zero).

当flex基础为auto且所有flex项目都可以放入父flex容器中时,flex子元素将为其预先的大小。如果flex 子元素无法放入其父级弹性容器中,则该容器中的 flex 子元素将根据其非弹性主轴尺寸按比例收缩(除非收缩因子为零)。

When there are no other properties setting the main-axis size of the flex items (that is, there’s no width or even min-width set on these flex items), and flex-basis: auto or flex: 0 1 auto is set, the flex items will only be as wide as they need to be for the content to fit, as seen in the first example in Figure 12-53. In this case, they are the width of the text “flex-basis: auto;”, which is approximately 110 pixels. The flex items are their pre-flexed size, as if set to display: inline-block. In this example, they’re grouped at main-start because the flex container’s justify-content defaults to flex-start.

当没有其他属性设置 flex 子元素的主轴尺寸时(即,在这些 flex 子元素上没有设置“宽度”甚至“最小宽度”),以及没有“ flex-basis:auto”或“ flex” :0 1 auto`被设置,flex 子元素将仅与内容适合所需的宽度一样,如图 12-53 中的第一个示例所示。在这种情况下,它们是文本“ flex-basis:auto;”的宽度,大约为 110 像素。flex 子元素是其预先的大小,就像设置为“ display:inline-block”一样。在此示例中,它们是在主轴起始端时分组的,因为 flex 容器的“ justify-content”默认为“ flex-start”。

In the second example in Figure 12-53, each of the flex items has flex basis of auto and an explicitly declared width. The main-axis size of the elements, had they not been turned into flex items, would be 100, 150, and 200 pixels, respectively. And so they are here, since they fit into the flex container without any overflow along the main axis.

在图 12-53 的第二个示例中,每个 flex 子元素都具有“ auto”的 flex 基础和一个显式声明的宽度。如果不将元素变成 flex 子元素,则元素的主轴尺寸将分别为 100、150 和 200 像素。因此它们就在这里,因为它们可以装入 flex 容器,而沿主轴没有任何溢出。

Auto flex basis and flex item widths

In the third example in Figure 12-53, each of the flex items has flex basis of auto and a very large explicitly declared width. The main-axis size of the elements, had they not been turned into flex items, would be 2,000, 3,000, and 4,000 pixels, respectively. Since they could not possibly fit into the flex container without overflowing along the main axis, and their flex shrink factors have all defaulted to 1, they shrink until they fit into the flex container. You can do the math to find out how big they are using the process outlined in a previous section; as a hint, the third flex item should be reduced from four thousand pixels down to a width of 240 pixels.

在图 12-53 的第三个示例中,每个 flex 子元素都具有“ auto”的 flex 基础和一个非常大的显式声明的宽度。如果不将元素转换为 flex 子元素,元素的主轴尺寸将分别为 2,000、3,000 和 4,000 像素。由于它们不可能沿着主轴溢出而无法装入 flex 容器中,并且它们的 flex 收缩因子都默认为 1,因此它们会收缩直到适合 flex 容器。您可以使用上一节中概述的过程进行数学运算以找出它们的大小。作为提示,第三个 flex 子元素应从 4000 像素减少到 240 像素的宽度。

12.14.3 Default Values

When neither a flex-basis nor a flex is set, the flex item’s main-axis size is the preflex size of the item, as their default value is auto.

如果既未设置“ flex-basis”又未设置“ flex”,则 flex 子元素的主轴尺寸为该项目的预先的尺寸,因为它们的默认值为“ auto”。

In Figure 12-54, two things are happening: the flex bases are defaulting to auto, the growth factor is defaulting to 0, and the shrink factor of each item is defaulting to 1. For each flex item, the flex basis is their individual width value. That means the flex bases are being set to the values of the width properties: 100, 200, and 300 pixels in the first example, and 200, 400, and 200 pixels in the second example. As the combined widths of the flex items are 600 pixels and 800 pixels, respectively, both of which are both greater than the main-axis size of the 540-pixel-wide containers, they are all shrinking proportionally to fit.

在图 12-54 中,发生了两件事:flex base 默认为 auto,增长因子默认为 0,每一项的收缩因子默认为 1。对于每个 flex 子元素,flex 基础是其各自的“宽度”值。这意味着将 flex base 设置为“ width”属性的值:在第一个示例中为 100、200 和 300 像素,在第二个示例中为 200、400 和 200 像素。由于 flex 子元素的组合宽度分别为 600 像素和 800 像素,两者均大于 540 像素宽的容器的主轴尺寸,因此它们都按比例缩小以适合。

Default sizing of flex items

In the first example, we are trying to fit 600 pixels in 540 pixels, so each flex item will shrink by 10% to yield flex items that are 90, 180, and 270 pixels wide. In the second example, we are trying to fit 800 pixels into 540 pixels, so they all shrink 32.5%, making the flex items’ widths 135, 270, and 135 pixels.

在第一个示例中,我们试图在 540 个像素中容纳 600 个像素,因此每个 flex 子元素将缩小 10%,以产生 90、180 和 270 像素宽的 flex 子元素。在第二个示例中,我们尝试将 800 像素调整为 540 像素,以使它们全部缩小 32.5%,从而使 flex 子元素的宽度分别为 135、270 和 135 像素。

12.14.4 Length Units

In the previous examples, the auto flex bases defaulted to the declared widths of the various flex items. There are other options; for example, we can use the same length units for our flex-basis value as we do for width and height.

在前面的示例中,auto 的 flex 基础 默认为各种 flex 子元素声明的宽度。还有其他选择;例如,我们可以为 flex-basis 值使用与“ width”和“ height”相同的长度单位。

Sizing flex items with length-unit flex bases

When there are both flex-basis and width (or height, for vertical main axes) values, the basis trumps the width (or height). Let’s add bases values to the first example from Figure 12-54. The flex items include the following CSS:

如果同时具有“ flex-basis”和“ width”(或垂直轴的“ height”)值,则基数优先于宽度(或高度)。让我们将基值添加到图 12-54 中的第一个示例中。flex 子元素包括以下 CSS:

flex-container {
  width: 540px;
}
item1 {
  width: 100px;
  flex-basis: 300px; /* flex: 0 1 300px; */
}
item2 {
  width: 200px;
  flex-basis: 200px; /* flex: 0 1 200px; */
}
item3 {
  width: 300px;
  flex-basis: 100px; /* flex: 0 1 100px; */
}

The widths are overridden by the bases. The flex items shrink down to 270 pixels, 180 pixels, and 90 pixels, respectively. Had the container not had a constrained width, the flex items would have been 300 pixels, 200 pixels, and 100 pixels, respectively.

宽度被基数覆盖。flex 子元素分别缩小到 270 像素,180 像素和 90 像素。如果容器没有受限制的宽度,则 flex 子元素分别为 300 像素,200 像素和 100 像素。

While the declared flex basis can override the main-axis size of flex items, the size can be affected by other properties, such as min-width, min-height, max-width, and max-height. These are not ignored. Thus, for example, an element might have flex-basis: 100px and min-width: 500px. The minimum width of 500px will be respected, even though the flex basis is smaller.

虽然声明的 flex 基础可以覆盖 flex 子元素的主轴尺寸,但是尺寸可能会受到其他属性的影响,例如“最小宽度”,“最小高度”,“最大宽度”和“最大高度” 。这些不容忽视。因此,例如,一个元素可能具有“ flex-basis:100px”和“ min-width:500px”。即使 flex 基础较小,也要遵守最小宽度“ 500px”。

Percentage units

Percentage values for flex-basis are calculated relative to the size of the main dimension of the flex container.

“ flex-basis”的百分比值是相对于 flex 容器主轴方向的大小计算的。

We’ve already seen the first example in Figure 12-56; it’s included here to recall that the width of the text “flex-basis: auto” in this case is approximately 110 pixels wide. In this case only, declaring flex-basis: auto looks the same as writing flex-basis: 110px:

我们已经看到了图 12-56 中的第一个示例;此处包含的内容是,“ flex-basis:auto”,在这种情况下的宽度约为 110 像素。仅在这种情况下,声明flex-basis:auto看起来与编写flex-basis:110px相同:

flex-container {
  width: 540px;
}
flex-item {
  flex: 0 1 100%;
}

In the second example in Figure 12-56, the first two flex items have a flex basis of auto with a default width of auto, which is as if their flex basis were set to content.

在图 12-56 的第二个示例中,前两个 flex 子元素的 flex 基础为“自动”,默认“宽度”为“自动”,就好像其 flex 基础设置为“内容”一样。

As we’ve noted previously, the flex-basis of the first 2 items ends up being the equivalent of 110 pixels, as the content in this case happens to be 110 pixels wide. The last item has its flex-basis set to 100%.

如我们前面所述,前 2 个项目的“ flex-basis”最终等于 110 像素,因为在这种情况下,内容恰好为 110 像素宽。最后一项的“ flex-basis”设置为“ 100%”。

Sizing flex items with percentage flex bases

The percentage value is relative to the parent, which is 540 pixels. The third flex item, with a basis of 100%, is not the only flex item within the non-wrapping flex container. Thus, it will not grow to be 100% of the width of the parent flex container unless its shrink factor is set with a null shrink factor, meaning it can’t shrink, or if it contains non-wrappable content that is as wide or wider than the parent container.

百分比值相对于父像素为 540 像素。以'100%'为基础的第三个 flex 子元素并不是非折行 flex 容器中的唯一 flex 子元素。因此,它不会增长到父级 flex 容器宽度的 100%,除非它的收缩因子设置为空收缩因子,这意味着它不能收缩,或者包含不可收缩的内容,例如比父容器一样宽或更宽。

Remember: when the flex basis is a percent value, the main-axis size is relative to the parent, which is the flex container.

With our 3 flex bases, if the content is indeed 110 pixels wide, and the container is 540 pixels wide (ignoring other box-model properties for simplicity’s sake), we have a total of 760 pixels to fit in a 540-pixel space. Thus we have 220 pixels of negative space to distribute proportionally. The shrink factor is:

如果使用 3 个 flex 基础,则如果内容确实为 110 像素宽,并且容器为 540 像素宽(为简单起见,忽略其他盒型属性),则我们总共有 760 像素可以容纳在 540 像素的空间里。因此,我们有 220 个像素的负空间按比例分布。收缩系数为:

Shrink factor = 220px ÷ 760px = 28.95%

Each flex item will be shrunk by 28.95%, becoming 71.05% of the width they would have been had they not been allowed to shrink. We can figure the final widths:

每个 flex 子元素将收缩 28.95%,变成其宽度(如果不允许收缩)的 71.05%。我们可以算出最终的宽度:

item1 = 110px × 71.05% = 78.16px
item2 = 110px × 71.05% = 78.16px
item3 = 540px × 71.05% = 383.68px

These numbers hold true as long as the flex items can be that small; that is, as long as none of the flex items contain media or nonbreaking text wider than 78.16 pixels or 383.68 pixels. This is the widest these flex items will be as long as the content can wrap to be that width or narrower. We say “widest” because if one of the other two flex items can’t shrink to be as narrow as this value, they’ll have to absorb some of that negative space.

只要 flex 子元素可以这么小,这些数字就成立。也就是说,只要所有 flex 子元素都不包含宽度超过 78.16 像素或 383.68 像素的媒体或不间断文本。只要内容可以折行为该宽度或更窄,这就是这些 flex 子元素的最大宽度。之所以说“最宽”,是因为如果其他两个 flex 子元素之一不能缩小到该值那么窄,则它们将不得不吸收一些负空间。

In the third example in Figure 12-56, the flex-basis: auto item wraps over three lines. The CSS for this example is the equivalent of:

在图 12-56 的第三个示例中,“ flex-basis:auto”项包裹了三行。此示例的 CSS 等效于:

flex-container {
  width: 540px;
}
item1 {
  flex: 0 1 70%;
}
item2 {
  flex: 0 1 auto;
}
item3 {
  flex: 0 1 80%;
}

We declared the flex-basis of the 3 flex items to be 70%, auto, and 80%, respectively. Remembering that in our scenario auto is the width of the non-wrapping content, which in this case is approximately 110 pixels, and our flex container is 540 pixels, the bases are equivalent to:

我们宣布 3 个 flex 子元素的“ flex-basis”分别为“ 70%”,“ auto”和“ 80%”。请记住,在我们的场景中,“ auto”是非折行内容的宽度,在这种情况下约为 110 像素,而我们的 flex 容器为 540 像素,基数等于:

item1 = 70% × 540px = 378px
item2 = widthOfText(“flex-basis: auto”) = 110px
item3 = 80% × 540px = 432px

When we add the widths of these 3 flex items’ bases, they have total combined width of 920 pixels, which needs to fit into a flex container 540 pixels wide. Thus we have 380 pixels of negative space to remove proportionally among the 3 flex items. To figure out the ratio, we divide the available width of our flex container by the sum of widths of the flex items that they would have if they couldn’t shrink:

当我们添加这 3 个 flex 子元素的基础的宽度时,它们的总合并宽度为 920 像素,这需要适合 540 像素宽的 flex 容器。因此,我们有 380 个负空间像素,可以在 3 个 flex 子元素之间按比例删除。为了弄清楚比率,我们将 flex 容器的可用宽度除以 flex 子元素无法收缩时所具有的 flex 子元素的宽度之和:

Proportional Width = 540px ÷ 920px = 0.587

Because the shrink factors are all the same, this is fairly simple. Each item will be 58.7% of the width it would be if it had no flex item siblings:

因为收缩因子都相同,所以这很简单。如果没有同级 flex 子元素,则每个项目的宽度将是宽度的 58.7%:

item1 = 378px × 58.7% = 221.8px
item2 = 110px × 58.7% = 64.6px
item3 = 432px × 58.7% = 253.6px

What happens when the container is a different width? Say, 1,000 pixels? The flex basis would be 700 pixels (70% × 1,000 pixels), 110 pixels, and 800 pixels (80% × 1,000 pixels), respectively, for a total of 1,610 pixels:

如果容器的宽度不同,会发生什么?说 1,000 个像素?flex 基础分别为 700 像素(70%×1,000 像素),110 像素和 800 像素(80%×1,000 像素),总共 1,610 像素:

Proportional Width = 1000px ÷ 1610px = 0.6211

item1 = 700px × 62.11% = 434.8px
item2 = 110px × 62.11% = 68.3px
item3 = 800px × 62.11% = 496.9px

Because with a basis of 70% and 80%, the combined bases of the flex items will always be wider than 100%, no matter how wide we make the parent, all 3 items will always shrink.

因为使用 70%和 80%的基数,flex 子元素的合并基数将始终大于 100%,无论我们将父级设置为多大,这 3 个项目都将始终缩小。

If the first flex item can’t shrink for some reason—whether due to unshrinkable content, or another bit of CSS setting its flex-shrink to 0— it will be 70% of the width of the parent—378 pixels in this case. The other 2 flex items must shrink proportionally to fit into the remaining 30%, or 162 pixels. In this case, we expect widths to be 378 pixels, 32.875 pixels, and 129.125 pixels. As the text “basis:” is wider than that—assume 42 pixels—we get 378 pixels, 42 pixels, and 120 pixels. This result is shown in Figure 12-57.

如果第一个 flex 子元素由于某种原因而不能收缩(无论是由于内容不可收缩,还是由于 CSS 的另一部分将其“ flex-shrink”设置为“ 0”),在这种情况下,第一个 flex子元素则将是父级宽度的 70%(378 个像素)。其他 2 个 flex 子元素必须按比例缩小以适合剩余的 30%或 162 像素。在这种情况下,我们希望宽度为 378 像素,32.875 像素和 129.125 像素。由于文本的“ basis:”比较宽,为 42 像素,我们得到 378 像素,42 像素和 120 像素。结果如图 12-57 所示。

While the percentage value for flex-basis is relative to the width of the flex container, the main-axis size is impacted by its siblings

Testing this out on your device will likely have slightly different results, as the width of the text “flex-basis: auto” may not be the same for you, depending on the font that actually gets used to render the text. (We used Myriad Pro, with fallbacks to Helvetica and any generic sans-serif font.)

在您的设备上进行测试可能会产生稍微不同的结果,因为文本“ flex-basis:auto”的宽度可能对您而言并不相同,具体取决于实际用于呈现文本的字体。 (我们使用了 Myriad Pro,具有 Helvetica 的后备版本和任何通用的 sans-serif 字体。)

12.14.5 Zero Basis

If neither the flex-basis property nor the flex shorthand is included at all, the flex basis defaults to auto. When the flex property is included, but the flex basis component of the shorthand is omitted from the shorthand, the basis defaults to 0. While on the surface you might think the two values of auto and 0 are similar, the 0 value is actually very different, and may not be what you expect.

如果根本没有包括“ flex-basis”属性和“ flex”简写,则 flex base 默认为 auto。当包含flex属性,但简写中省略了简写的 flex 基础部分时,基础默认为 0。从表面上看,您可能会认为 auto 和 0 的两个值相似,但 0 值实际上是非常不同的,并且可能与您的预期不同。

In the case of flex-basis: auto, the basis is the main size of the flex items’ contents. If the basis of each of the flex items is 0, the “available” space is the main-axis size of the entire flex container. In either case, the “available” space is distributed proportionally, based on the growth factors of each flex item.

在“ flex-basis:auto”的情况下,基础是 flex 子元素内容的主轴方向尺寸。如果每个 flex 子元素的基础是“ 0”,则“可用”空间是整个 flex 容器的主轴尺寸。无论哪种情况,“可用”空间都是根据每个 flex 子元素的增长因素成比例分配的。

In the case of a basis of 0, the size of the flex container is divided up and distributed proportionally to each flex item based on their growth factors—their default original main-axis size as defined by height, width, or content, is not taken into account, though min-width, max-width, min-height, and max-height do impact the flexed size.

在基数为“ 0”的情况下,将 flex 容器的大小进行划分,并根据它们的增长因子按比例分配给每个 flex 子元素-它们的默认原始主轴大小由“高度”,“宽度”定义,但并未考虑“内容”,尽管“最小宽度”,“最大宽度”,“最小高度”和“最大高度”确实会影响 flex 尺寸。

As shown in Figure 12-58, when the basis is auto, it is just the extra space that is divided up proportionally and added to each flex item set to grow. Again, assuming the width of the text “flex: X X auto” is 110 pixels, in the first examples we have 210 pixels to distribute among 6 growth factors, or 35 pixels per growth factor. The flex items are 180, 145, and 215 pixels wide, respectively.

如图 12-58 所示,当基础是“自动”时,只是多余的空间按比例分配并添加到每个可 flex 的 flex 子元素。同样,假设文本“ flex:X X auto”的宽度为 110 像素,在第一个示例中,我们有 210 个像素可分布在 6 个增长因子中,或每个增长因子 35 个像素。flex 子元素分别为 180、145 和 215 像素宽。

Flex growth in auto and zero flex bases

In the second example, when the basis is 0, all 540 pixels of the width is distributable space. With 540 pixels of distributable space between 6 growth factors, each growth factor is worth 90 pixels. The flex items are 180, 90, and 270 pixels wide, respectively.

在第二个示例中,当基数为 0 时,宽度的所有 540 像素都是可分配空间。 6 个增长因子之间有 540 像素可分配空间,每个增长因子值 90 像素。flex 子元素的宽度分别为 180、90 和 270 像素。

While the middle flex item is 90 pixels wide, the content in this example is narrower than 110 pixels, so the flex item didn’t wrap.

尽管中间的 flex 子元素宽为 90 像素,但此示例中的内容比 110 像素窄,因此该 flex 子元素没有折行。

12.15 The flex Shorthand

Now that we have a fuller understanding of the properties that make up the flex shorthand, remember: always use the flex shorthand. It accepts the usual global property values, including initial, auto, none; and the use of an integer, usually 1, meaning the flex item can grow. Let’s go over all these values.

既然我们对构成flex简写的属性有了更全面的了解,请记住:始终使用flex简写。它接受通常的全局属性值,包括“ initial”,“ auto”,“ none”;以及通常为 1 的整数的使用,表示 flex 子元素可以增长。让我们来看看所有的这些值。

12.15.1 Common Flex Values

The common flex values are four flex values providing the most commonly desired effects:

常见的 flex 值是四个 flex 值,可提供最常见的效果:

flex: initial

This value sizes flex items based on the width or height property, depending on the main-axis direction, while allowing shrinking.

该值根据主轴的方向,根据“ width”或“ height”属性来调整 flex 子元素的尺寸,同时允许收缩。

flex: auto

This flex value also sizes flex items based on the width or height property, but makes them fully flexible, allowing both shrinking and growing.

这个 flex 值也基于widthheight属性来调整 flex 子元素的大小,但是使它们完全灵活,既可以收缩也可以增长。

flex: none

This value again sizes flex items based on the width or height property, but makes them completely inflexible: they can’t shrink or grow.

该值再次根据“ width”或“ height”属性调整 flex 子元素的大小,但使它们完全不灵活:它们无法收缩或增长。

flex: <number>

This value sets the flex item’s growth factor to the <number> provided. It thus sets the shrink factor to 0, and the basis to 0 as well. This means the width or height value acts as a minimum size, but the flex item will grow if there is room to do so.

此值将 flex 子元素的增长因子设置为提供的“ <数字>”。因此,它将收缩因子设置为“ 0”,将基数也设置为“ 0”。这意味着widthheight值是最小尺寸,但是 flex 子元素会在有空间的情况下增长。

Let‘s consider each of these in turn.

让我们依次考虑这些。

Flexing with initial

initial is a global CSS keyword, which means initial can be used on all properties to represent a property’s initial value; that is, its specification default value. Thus, the following lines are equivalent:

“ initial”是 CSS 的全局关键字,这意味着“ initial”可用于所有属性,以表示属性的初始值;即其规格默认值。因此,以下几行是等效的:

flex: initial;
flex: 0 1 auto;

Declaring flex: initial sets a null growth factor, a shrink factor of 1, and sets the flex bases to auto. In Figure 12-59, we can see the effect of the auto flex bases. In the first two examples, the basis of each flex item is content—with each flex item having the width of the single line of letters that make up their content. In the last 2 examples, the flex bases of all the items are equal at 50 pixels, since width: 50px has been applied to all the flex items. The flex: initial declaration sets the flex-basis to auto, which we previously saw is the value of the width (or height), if declared, or content if not declared.

声明“ flex:initial”将设置空增长因子,将收缩因子设置为“ 1”,并将 flex base 设置为“ auto”。在图 12-59 中,我们可以看到auto 的 flex base 的效果。在前两个示例中,每个 flex 子元素的基础都是“内容”,每个 flex 子元素的宽度都是组成其内容的单行字母的宽度。在最后两个示例中,所有项目的 flex 基数都等于 50 像素,因为已将'width:50px'应用于所有 flex 子元素。 “ flex:initial”声明将“ flex-basis”设置为“ auto”,我们之前看到的是“ width”(或“ height”)(如果声明)或“ content”(如果未声明)的值。

Flex items shrink but won’t grow when flex: initial is set

In the first and third examples in Figure 12-59, we see that when the flex container is too small to fit all the flex items at their default main-axis size, the flex items shrink so that all the flex items fit within the parent flex container. In these examples, the combined flex bases of all the flex items is greater than the main-axis size of the flex container. In the first example, the width of teach flex item varies based on the width of each item’s content and its ability to shrink. They all shrink proportionally based on their shrink factor, but not narrower than their widest content. In the third example, with each flex item’s flex-basis being 50 pixels (due to the value of width), all the items shrink equally.

在图 12-59 的第一个和第三个示例中,我们看到当 flex 容器太小而无法以其默认主轴大小容纳所有 flex 子元素时,flex 子元素会收缩,以使所有 flex 子元素都适合父对象 flex 容器。在这些示例中,所有 flex 子元素的组合 flex 基础大于 flex 容器的主轴尺寸。在第一个示例中,示教 flex 子元素的宽度根据每个项目内容的宽度及其收缩能力而变化。它们均基于其收缩因子按比例收缩,但不比其最宽的内容窄。在第三个示例中,每个 flex 子元素的 flex-basis 为 50 像素(由于width的值),所有项均等收缩。

Flex items, by default, are grouped at main start, as flex-start is the default value of for the justify-content property. This is only noticeable when the combined mainaxis sizes of the flex items in a flex line are smaller than the main-axis size of the flex container, and none of the flex items are able to grow.

默认情况下,flex 子元素在主轴开始处进行分组,因为“ flex-start”是“ justify-content”属性的默认值。这仅在行中的 flex 子元素的组合主轴尺寸小于 flex 容器的主轴尺寸且所有 flex 子元素均无法增长时才能被注意到。

Flexing with auto

flex: auto is similar to flex: initial, but makes the flex items flexible in both directions: they’ll shrink if there isn’t enough room to fit all the items within the container, and they’ll grow to take up all the extra space within the container if there is distributable space. The flex items absorb any free space along the main axis. The following two statements are equivalent:

flex:autoflex:initial类似,但是使 flex 子元素在两个方向上都具有灵活性:如果没有足够的空间容纳容器中的所有项,它们会收缩,如果有可分配的空间,它们会成长占用容器中所有多余的空间。flex 子元素会吸收主轴上的所有自由空间。以下两个语句是等效的:

flex: auto;
flex: 1 1 auto;

A variety of scenarios using auto flexing are shown in Figure 12-60.

图 12-60 显示了使用 flex:auto; 的各种场景。

Flex items can grow and shrink when flex: auto is set

The first and third examples of Figure 12-60 are identical to the examples in Figure 12-59, as the shrinking and bases are the same. However, the second and fourth examples are different. This is because when flex: auto is set, the growth factor is 1, and the flex items therefore can grow to incorporate all the extra available space.

图 12-60 的第一个和第三个示例与图 12-59 的示例相同,因为收缩和基数相同。但是,第二和第四示例是不同的。这是因为设置了“ flex:auto”时,增长因子为“ 1”,因此 flex 子元素可以增长以合并所有额外可用空间。

Preventing flexing with none

Any flex: none flex items are inflexible: they can neither shrink nor grow. The following two lines of CSS are equivalent:

任何“ flex:none” flex 子元素都是不灵活的:它们既不能收缩也不能增长。以下两行 CSS 是等效的:

flex: none;
flex: 0 0 auto;

The effects of none are shown in Figure 12-61.

图 12-61 中没有显示任何效果。

With flex: none, flex items will neither grow nor shrink

As demonstrated in the first and third examples of Figure 12-61, if there isn’t enough space, the flex items overflow the flex container. This is different from flex: initial and flex: auto, which both set a positive shrink factor.

如图 12-61 的第一个和第三个示例所示,如果没有足够的空间,则 flex 子元素会溢出 flex 容器。这与“ flex:initial”和“ flex:auto”不同,它们都设置了正的收缩系数。

The basis resolves to auto, meaning each flex item’s main-axis size is determined by the main-axis size of the element had it not been turned into a flex item. The flex-basis resolves to the width or height value of the element. If that value is auto, the basis becomes the main-axis size of the content. In the first two examples, the basis—and the width, since there is no growing or shrinking—is the width of the content. In the third and fourth examples, the width and basis are all 50 pixels, because that’s the value of the width property applied to them.

基础解析为“自动”,这意味着每个 flex 子元素的主轴尺寸由元素的主轴尺寸确定,前提是该元素未转换为 flex 子元素。 flex-basis 解析为元素的 width 或 height 值。如果该值为“ auto”,则基础将成为内容的主轴尺寸。在前两个示例中,基础以及宽度,因为没有增长或缩小,是内容的宽度。在第三个和第四个示例中,width 和 base 均为 50 像素,因为这是应用于它们的width属性的值。

Numeric flexing

When the value of the flex property is a single, positive numeric value, that value will be used for the growth factor, while the shrink factor will default to 0 and the basis will default to 0. The following two CSS declarations are equivalent:

当 flex 属性的值为单个正数值时,该值将用作增长因子,而收缩因子将默认为 0,基数默认为 0。以下两个 CSS 声明是等效的:

flex: 3;
flex: 3 0 0;

This makes the flex item on which it is set flexible: it can grow. The shrink factor is actually moot: the flex basis is set to 0, so the flex item can only grow from that basis.

这使在其上设置的 flex 子元素变得灵活:它可以增长。收缩因子实际上是没有意义的:flex 基础设置为 0,因此 flex 子元素只能在该基础上增长。

In the first two examples in Figure 12-62, all the flex items have a flex growth factor of 3. The flex basis is 0, so they don’t “shrink”; they just grew equally from zero pixels wide until the sum of their main-axis sizes grew to fill the container along the main axis. With all the flex items having a basis of 0, 100% of the main dimension is distributable space. The main-axis size of the flex items are wider in this second example because the wider flex container has more distributable space.

在图 12-62 的前两个示例中,所有 flex 子元素的 flex 增长因子均为 3。flex 基数为“ 0”,因此它们不会“缩小”;它们只是从零像素宽开始平均增长,直到它们的主轴大小之和增长到沿着主轴填充满容器为止。在所有 flex 子元素都以'0'为基准的情况下,主要维度的 100%是可分配空间。在第二个示例中,flex 子元素的主轴尺寸更宽,因为较宽的flex容器具有更多的可分配空间。

Flexing using a single numeric value

Any numeric value that is greater than 0, even 0.1, means the flex item can grow. When there is available space to grow, if only one flex item has a positive growth factor, that item will take up all the available space. If there are multiple flex items that can grow, the available extra space will be distributed proportionally to each flex item based on to their growth factor.

任何大于 0 甚至 0.1 的数值都表示 flex 子元素可以增长。当有可用空间增长时,如果只有一个 flex 子元素具有正增长因子,则该项目将占用所有可用空间。如果有多个 flex 子元素可以增长,则可用的额外空间将根据它们的增长因子按比例分配给每个 flex 子元素。

In the last three examples of Figure 12-62, there are six flex items with flex: 0, flex: 1, flex: 2, flex: 3, flex: 4, and flex: 5 declared, respectively. These are the growth factors for the flex items, with each having a shrink factor of 1 and a flex basis of 0. The main-axis size of each is proportional to the specified flex growth factor. You might assume that the flex: 0 item with the text “flex: 0” in the third and fourth examples will be zero pixels wide, like in the fourth and fifth examples—but, by default, flex items won’t shrink below the length of the longest word or fixed-size element.

在图 12-62 的最后三个示例中,有六个 flex 子元素,分别声明了flex:0flex:1flex:2flex:3flex:4flex :5。这些是 flex 子元素的增长因子,每一个的收缩因子均为 1,flex 基础为 0。每个的主轴尺寸与指定的增长因子成比例。您可能会假设第三和第四示例中带有文本“ flex:0”的“ flex:0”项的宽度为零像素,就像第四和第五示例中一样,但是默认情况下,flex 子元素不会缩小小于最长字或固定大小元素的长度。

A bit of padding, margins, and borders were added in the figures to make the visuals more pleasing. For this reason, the leftmost flex item, with flex: 0 declared, is visible: it has a one-pixel border making it visible, even though it’s zero pixels wide.

在图中添加了一些填充,边距和边框,以使视觉效果更令人愉悦。因此,最左侧的 flex 子元素(声明为 flex:0)是可见的:即使边框的宽度为零像素,它的边框也有一个像素,因此可见。

12.16 The order property

Flex items are, by default, displayed and laid out in the same order as they appear in the source code. The order of flex items and flex lines can be reversed with flex-direction, but sometimes you want a little more complicated rearrangment. The order property can be used to change the ordering of individual flex items.

默认情况下,flex 子元素的显示和布局顺序与它们在源代码中的显示顺序相同。flex 子元素和 flex 行的顺序可以通过“ flex-direction”颠倒,但是有时您需要更复杂的重排。 “ order”属性可用于更改各个 flex 子元素的顺序。

By default, all flex items are assigned the order of 0, with the flex items all assigned to the same ordinal group and displayed in the same order as their source order, along the direction of the main axis. (This has been the case for all the examples seen throughout this chapter.)

默认情况下,所有 flex 子元素均被分配为“ 0”的顺序,所有 flex 子元素均被分配给相同的序数组,并沿其主轴方向按与它们的源顺序相同的顺序显示。 (本章中看到的所有示例都是这种情况。)

To change the visual order of a flex item, set the order property value to a nonzero integer. Setting the order property on elements that are not children of a flex container has no effect on such elements.

要更改 flex 子元素的视觉顺序,请将order属性值设置为非零整数。在不是 flex 容器的子元素的元素上设置order属性不会对此类元素产生影响。

The value of the order property specifies an ordinal group to which the flex item belongs. Any flex items with a negative value will appear to come before those defaulting to 0 when drawn to the page, and all the flex items with a positive value will appear to come after those defaulting to 0. While visually altered, the source order remains the same. Screen readers and tabbing order remains as defined by the source order of the HTML.

“ order”属性的值指定 flex 子元素所属的序数组。绘制到页面上时,任何具有负值的 flex 子元素都将出现在默认值“ 0”之前,而所有具有正值的 flex 子元素将出现在默认值为“ 0”之后。在视觉上进行更改后,源顺序保持不变。屏幕阅读器和制表顺序保持不变,如 HTML 的源顺序所定义。

For example, if you have a group of 12 items, and you want the 7th to come first and the 6th to be last, you would declare:

例如,如果您有 12 个项目的组,并且希望第 7 位排在最前面,而第 6 位排在最后,那么您可以声明:

ul {
  display: inline-flex;
}
li:nth-of-type(6) {
  order: 1;
}
li:nth-of-type(7) {
  order: -1;
}

In this scenario, we are explicitly setting the order for the sixth and seventh list items, while the other list items are defaulting to order: 0. The result is shown in Figure 12-63.

在这种情况下,我们显式设置第六和第七个列表项的顺序,而其他列表项默认为“ order:0”。结果如图 12-63 所示。

Reordering flex items with the order property

The seventh flex item is the first to be laid out, due to the negative value of the order property, which is less than the default 0, and is also the lowest value of any of its sibling flex items. The sixth flex item is the only item with a value greater than zero, and therefore has the highest order value out of all of its siblings. This is why it’s laid out after all the other flex items. All the other items, all having the default order of 0, are drawn between those first and last items, in the same order as their source order, since they are all members of the same ordinal group (0).

第七个 flex 子元素是第一个被布置的项目,这是由于order属性的负值,它小于默认的'0',并且也是其所有同级 flex 子元素中的最低值。第六个 flex 子元素是唯一一个值大于零的项目,因此在所有同级项中具有最高的序列值。这就是为什么将其放置在所有其他 flex 子元素之后的原因。所有其他项目的默认“顺序”均为“ 0”,它们以与源顺序相同的顺序绘制在这些第一项和最后一项之间,因为它们都是同一序数组(“ 0”)的成员。

The flex container lays out its content in order-modified document order, starting from the lowest numbered ordinal group and going up. When you have multiple flex items having the same value for the order property, the items share an ordinal group. The items in each ordinal group will appear in source order, with the group appearing in numeric order, from lowest to highest. Consider the following:

flex 容器按order修改后的文档顺序排列其内容,从编号最低的顺序组开始,然后向上。当多个 flex 子元素的 order 属性值相同时,这些商品共享一个序数组。每个顺序组中的项目将按源顺序显示,并且该组按从最低到最高的数字顺序显示。考虑以下:

ul {
  display: inline-flex;
  background-color: rgba(0, 0, 0, 0.1);
}
li:nth-of-type(3n-1) {
  order: 3;
  background-color: rgba(0, 0, 0, 0.2);
}
li:nth-of-type(3n + 1) {
  order: -1;
  background-color: rgba(0, 0, 0, 0.4);
}

By setting the same order value to more than one flex item, the items will appear by ordinal group, and by source order within each individual ordinal group. This has the result shown in Figure 12-64.

通过为多个 flex 子元素设置相同的order值,这些子元素将按序数组显示,并按每个序数组中的源顺序显示。结果如图 12-64 所示。

Flex items appear in order of ordinal groups, by source order within their group

Here’s what happened:

这是发生了什么:

  • Items 2, 5, 8, and 11 were selected to share ordinal group 3, and get a 20% opaque background.
  • Items 1, 4, 7, and 10 were selected to share ordinal group -1, and get a 40% opaque background.
  • Items 3, 6, 9, and 12 were not selected at all. They default to the ordinal group 0.
  • 选择项目 2、5、8 和 11 共享顺序组“ 3”,并获得 20%的不透明背景。
  • 选择项目 1、4、7 和 10 共享顺序组“ -1”,并获得 40%的不透明背景。
  • 根本没有选择项目 3、6、9 和 12。它们默认为序数组“ 0”。

The three ordinal groups, then, are -1, 0, and 3. The groups are arranged in that order. Within each group, the items are arranged by source order.

那么,三个序数组分别是“ -1”,“ 0”和“ 3”。组按该顺序排列。在每个组中,项目按源顺序排列。

This reordering is purely visual. Screen readers should read the document as it appeared in the source code, though they may not. As a visual change, ordering flex items impacts the painting order of the page: the painting order of the flex items is the order in which they appear, as if they were reordered in the source document, even though they aren’t.

这种重新排序纯粹是视觉上的。屏幕阅读器应该阅读文档在源代码中显示的顺序,尽管可能没有。作为一种视觉上的变化,flex 子元素的排序会影响页面的绘制顺序:flex 子元素的绘制顺序是它们显示的顺序,就好像它们在源文档中已被重新排序一样,即使它们没有。

Changing the layout with the order property has no effect on the tab order of the page. If the numbers in Figure 12-64 were links, tabbing through the links would go through the links in the order of the source code, not in the order of the layout.

使用order属性更改布局不会影响页面的制表符顺序。如果图 12-64 中的数字是链接,则在链接之间进行制表将按源代码的顺序浏览这些链接,而不是按布局的顺序。

12.16.1 Tabbed Navigation Revisited

Adding to our tabbed navigation bar example in Figure 12-2, we can make the currently active tab appear first, as Figure 12-65 shows:

添加到图 12-2 的选项卡式导航栏示例中,我们可以使当前活动的选项卡首先出现,如图 12-65 所示:

nav {
  display: flex;
  justify-content: flex-end;
  border-bottom: 1px solid #ddd;
}
a {
  margin: 0 5px;
  padding: 5px 15px;
  border-radius: 3px 3px 0 0;
  background-color: #ddd;
  text-decoration: none;
  color: black;
}
a:hover {
  background-color: #bbb;
  text-decoration: underline;
}
a.active {
  order: -1;
  background-color: #999;
}
<nav>
  <a href="/">Home</a>
  <a href="/about">About</a>
  <a class="active">Blog</a>
  <a href="/jobs">Careers</a>
  <a href="/contact">Contact Us</a>
</nav>

Changing the order will change the visual order, but not the tab order

The currently active tab has the .active class added, the href attribute removed, and the order set to -1, which is less than the default 0 of the other sibling flex items, meaning it appears first.

当前活动的选项卡添加了.active 类,删除了 href 属性,并将 order 设置为-1,这比其他同级 flex 子元素的默认值 0 少,这意味着首先出现。

Why did we remove the href attribute? As the tab is the currently active document, there is no reason for the document to link to itself. But, more importantly, if it was an active link instead of a placeholder link, and the user was using the keyboard to tab through the navigation, the order of appearance is Blog, Home, About, Careers, and Contact Us, with the Blog appearing first; but the tab order would have been Home, About, Blog, Careers, and Contact Us, following the source order rather than the visual order, which can be confusing.

为什么我们要删除href属性?由于选项卡是当前活动的文档,因此没有理由将文档链接到其自身。但是,更重要的是,如果它是活动链接而不是占位符链接,并且用户使用键盘在导航中切换,则显示顺序为“博客”,“主页”,“关于”,“职业”。以及“联系我们”,其中“博客”首先出现;但是制表符的顺序是“首页”,“关于”,“博客”,“职业介绍”和“联系我们”,遵循的是源顺序而不是视觉顺序,这可能会造成混淆。

The order property can be used to enable marking up the main content area before the side columns for mobile devices and those using screen readers and other assistive technology, while creating the appearance of the common three-column layout: a center main content area, with site navigation on the left and a sidebar on the right, as shown way back in Figure 12-50.

“ order”属性可用于在移动设备以及使用屏幕阅读器和其他辅助技术的侧边栏之前标记主要内容区域,同时创建常见的三列布局外观:中央为主要内容区域,左侧为网站导航,右侧为侧边栏,如图 12-50 所示。

While you can put your footer before your header in your markup, and use the order property to reorder the page, this is an inappropriate use of the property. order should only be used for visual reordering of content. Your underlying markup should always reflect the logical order of your content:

尽管您可以将页脚放在标记中的页眉之前,并使用order属性对页面进行重新排序,但这是对属性的不当使用。 “ order”只能用于内容的视觉重排。基础标记应始终反映内容的逻辑顺序:

<header></header>
<header></header>
<main>
  <main>
    <article></article>
    <nav></nav>
    <aside></aside>
    <article></article>
    <nav></nav>
    <aside></aside>
  </main>
</main>
<footer></footer>
<footer></footer>

We’ve been marking up websites in the order we want them to appear, as shown on the right in the preceding code example, which is the same code as in our threecolumn layout example (Figure 12-50). It really would make more sense if we marked up the page as shown on the left, with the article content, which is the main content, first in the source order: this puts the article first for screen readers, search engines, and even mobile device, but in the middle for our sighted users on larger screens:

我们按照希望它们出现的顺序标记了网站,如前面的代码示例中的右侧所示,该代码与我们的三栏布局示例中的代码相同(图 12-50)。如果我们将页面标记为左侧,页面的内容首先是原始内容,那将是更有意义的事情,这是文章的主要内容,它是按源顺序排列的:这将文章放在屏幕阅读器,搜索引擎和甚至是移动设备,但对于大屏幕用户来说,这是中间的位置:

main {
  display: flex;
}
main > nav {
  order: -1;
}

By using the order: -1 declaration we are able to make the nav appear first, as it is the lone flex item in the ordinal group of -1. The article and aside, with no order explicitly declared, default to order: 0.

通过使用 order:-1 声明,我们可以使 nav 首先出现,因为它是-1 序数组中唯一的 flex 子元素。没有明确声明order的article和aside,默认为order:0。

Remember, when more than one flex item is in the same ordinal group, the members of that group are displayed in source order in the direction of main-start to main-end, so the article is displayed before the aside.

请记住,当同一序数组中有多个 flex 子元素时,该组中的成员将按照源顺序从主轴开始到结束的方向显示,因此,article显示在aside之前。

Some developers, when changing the order of at least one flex item, like to give all flex items an order value for better markup readability. We could have also written:

一些开发人员在更改至少一个 flex 子元素的顺序时,喜欢为所有 flex 子元素赋予“ order”值,以提高标记的可读性。我们还可以写:

main {
  display: flex;
}
main > nav {
  order: 1;
}
main > article {
  order: 2;
}
main > aside {
  order: 3;
}

In previous years, before browsers supported flex, all this could have been done with floats: we would have set float: right on the nav. While doable, flex layout makes it much simpler, especially if we want all three columns—the aside, nav, and article —to be of equal heights.

在过去的几年中,浏览器支持 flex 之前,所有这些操作都可以通过 float 来完成:我们会在 nav 上设置“ float:right”。尽管可行,但 flex 布局使其简单得多,尤其是如果我们希望所有三列(aside,nav 和 article)具有相同的高度。