65.9K
CodeProject 正在变化。 阅读更多。
Home

Bootstrap 4 网格解析

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2020年4月20日

CPOL

18分钟阅读

viewsIcon

14941

downloadIcon

163

关于 Bootstrap 4 网格(基于 flex)可以做什么以及它与 Bootstrap 3 实现有什么不同的更新文章。

目录

引言

几年前,我写了一篇文章,Bootstrap 网格系统剖析,在其中我研究了网格系统到底是如何工作的。

与此同时,我的注意力转向了其他主题,但 Bootstrap 的网格系统也进行了彻底的重写。新的网格系统基于新的 flex 布局 CSS 系统。

在升级我的技能并实现一个基于 Angular 的网站时,我再次研究了 Bootstrap 网格系统,并决定深入研究它,看看它是如何工作的。

我将使用我最初的文章作为本文结构的模板,并有时引用其中解释的内容。我还会假设你具备 HTML 和 CSS 的基本知识。例如,你知道 <div><span> 等是什么……你知道 CSS 继承规则……我还假设你已经阅读了关于 Bootstrap 3 网格系统的文章,因此你熟悉响应式断点之类的概念。

免责声明:本文讨论的是 Bootstrap 网格系统,而不是 CSS flexbox 系统。这意味着我将解释 Bootstrap 网格系统使用的 flexbox 系统,因此绝非对 flexbox 系统的完整研究。我将介绍理解 Bootstrap 网格系统如何工作以及为什么在此选择某些 CSS 属性值所必需的概念。

那么,让我们开始吧。

构建基础:我们可以做什么

网格:仍然是关于行和列

这里没有什么变化:我们仍然需要定义一个包含行的容器,而行又包含列。但是,在 Bootstrap 3 网格中,你总是需要指定列的宽度并使其总和为 12,而在 Bootstrap 4 网格中,情况不再如此。

Bootstrap 4 网格定义了一个简单的 col 类,它允许你在页面宽度上平均分布你的列,同时占用尽可能多的空间以使内容匹配列。

当然,你仍然拥有带 col-xx-yy 结构的 col CSS 类的响应式版本。

  • xx:指定断点。也就是说:对应的跨度从哪个屏幕尺寸生效。
  • yy:指定列的跨度。也就是说:它在行中占用多少空间。

一些有效的标记是

<div  class="container">
    <div  class="row el-frame bg-gray">
        <div  class="col bg-red">First</div>
        <div  class="col bg-green">Second</div>
        <div  class="col bg-blue">Third</div>
    </div>
</div>

<div  class="container">
    <div  class="row el-frame bg-gray">
        <div  class="col-md-4 bg-red">First</div>
        <div  class="col-md-4 bg-green">Second</div>
        <div  class="col-md-4 bg-blue">Third</div>
    </div>
</div>

<div  class="container">
    <div  class="row el-frame bg-gray">
        <div  class="col-md-8 bg-red">The first column</div>
        <div  class="col-md-4 bg-green">The second column</div>
    </div>
</div>

查看实际效果.

这里变化不大:跨度之和仍然为 12,名称中的 xx 部分仍然定义了从哪个屏幕宽度开始列转换为行。

响应式:定义响应式断点

当然,网格的关键在于响应式:我们希望根据我们用于查看页面的设备的屏幕尺寸,将我们网页的某些部分的布局重新排列到不同的位置。

如果我们有一个大屏幕,我们可能希望将某些部分并排显示。但是,如果我们有一个窄屏幕,我们可能考虑将它们逐一下面显示,并能够指定哪个部分应该在哪个其他部分之上/之下。

这就是 CSS 类名中“xx”部分发挥作用的地方。

让我们试试以下方法

<div  class="container">
    <div  class="row el-frame bg-gray">
        <div  class="col-sm-8 bg-red">The first column</div>
        <div  class="col-sm-4 bg-green">The second column</div>
    </div>
</div>
 
<div  class="container">
    <div  class="row el-frame bg-gray">
        <div  class="col-md-8 bg-orange">The first column</div>
        <div  class="col-md-4 bg-blue">The second column</div>
    </div>
</div>

查看实际效果.

如果你现在拉伸和收缩你的浏览器窗口,你会注意到在某个宽度以下,列将转换为行。对于“sm”列,这与“md”列在不同宽度发生。Bootstrap 4 的断点定义了一个额外的断点,因此断点应用的宽度也不同。

  • none:如果你没有为断点指定任何内容,那么你将始终拥有列(小于 576px)
  • sm:大于或等于 576px
  • md:大于或等于 768px
  • lg:大于或等于 992px
  • xl:大于或等于 1200px

因此,在上面,当我们使用以“sm”作为断点的类时,我们的意思是:如果你的浏览器窗口宽度大于或等于 576px,则使用列,否则使用行。

当然,我们可以在单个元素上使用具有不同断点的类。

<div  class="container">

    <div  class="row">
        <div  class="col-sm-2 col-lg-5">1 First</div>
        <div  class="col-sm-8 col-lg-2">1 Second</div>
        <div  class="col-sm-2 col-lg-5">1 Third</div>
    </div>

    <div  class="row">
        <div  class="col-4 col-md-5">2 First</div>
        <div  class="col-4 col-md-2">2 Second</div>
        <div  class="col-4 col-md-5">2 Third</div>
    </div>

    <div  class="row">
        <div  class="col-4">3 First</div>
        <div  class="col-4">3 Second</div>
        <div  class="col-4">3 Third</div>
    </div>

</div>

查看实际效果.

在第一行,我们告诉 Bootstrap:

  • 如果屏幕宽度大于 992px,则使用比例为 5、2、5 的列宽
  • 如果屏幕宽度在 576px 和 992px 之间,则使用比例为 2、8、2 的列宽
  • 屏幕宽度小于 576px 时使用所有行

对于最后两行,我们始终都有列。它们永远不会转换为行,因为我们使用了 none 断点,该断点始终有效。

剖析基础:它是如何工作的?

所以,虽然我们在 Bootstrap 4 中并没有真正获得任何新的东西,但它的工作方式与 Bootstrap 3 完全不同。让我们找出它是如何工作的。

剖析网格

它在 CSS 中是如何定义的?

网格的基本结构仍然相同

  • 我们有一个 div 作为容器。
  • 在这个容器中,我们有行。
  • 最后,我们将行填充到列中。

容器的定义与 Bootstrap 3 相比没有太大区别。

.container {
  width: 100%;
  padding-right: 15px;
  padding-left: 15px;
  margin-right: auto;
  margin-left: auto;
}

但是,我们的 row 类现在看起来像这样:

row {
  display: flex;
  flex-wrap: wrap;
  margin-right: -15px;
  margin-left: -15px;
}

这里需要注意的属性是 display: flex 和 flew-wrap: wrap 属性。我们很快会回到这些。

接下来是 col 类。它们分为两部分:

  1. 当没有应用响应式断点时使用的常量部分。
  2. 由响应式断点定义的变量部分。

让我们看看常量部分。

.col-md-4 {
   position: relative;
   width: 100%;
   padding-right: 15px;
   padding-left: 15px;
 }

虽然我上面为 .col-md-4 说明符定义了这一点,但对于所有其他类,如 .col.col-1、...、.col-lg-1 等,使用方式相同。

这里已经有一个区别:我们将列宽明确设置为 100%。

接下来是由响应式断点驱动的变体部分。

.col-md-4 {
   flex: 0 0 33.333333%;
   max-width: 33.333333%;
 }

而在 Bootstrap 3 中我们只是在这里指定宽度,而在 Bootstrap 4 中,我们有这个 flex 规范和一个附加的 max-width 属性。

那么,这一切是怎么回事?你可能已经读过 Bootstrap 4 网格系统使用 CSS flex 系统。好吧,这就是它。让我们进一步研究。

CSS Flex 布局系统

让我们从简单开始,研究 display: flex CSS 属性。

<style>
.my-flex {
    display: flex;
    flex-wrap: wrap;
}
</style>

<div>
    <div>My first item in a regular DIV</div>
    <div>My second item a regular DIV</div>
    <div>My third item a regular DIV</div>
</div>

<div  class="my-flex">
    <div>My first item in the flexbox</div>
    <div>My second item in the flexbox</div>
    <div>My third item in the flexbox</div>
</div>

在行动中查看:常规 vs Flexbox DIV.

如果你看看它是如何显示的,你会注意到与常规 div 相比,应用了 display: flexdiv 的项目是水平排列的。另外,当你拉伸和收缩浏览器窗口时,子 div 会垂直换行。这是因为 flex-wrap: wrap 属性。如果你不设置它,项目会收缩以适应 div。还要注意示例页面上,所有子项都具有相同的高度。

CSS Flexbox 模型允许你轻松指定如何布局应用于容器的子项(在这些容器上应用了 CSS display: flex 属性)。默认情况下是水平布局,不换行。你可以通过使用 flex-direction 属性来更改布局方向,该属性可以具有 rowrow-reversecolumn column-reverse 的值。默认值是 row ,这就是为什么在我们的示例中子项是水平排列的原因。

为了演示 flex-wrap 属性,我明确设置了子 div 的宽度,但如果你不设置它,它们只会占用必要的可用空间。然而,在 Bootstrap 4 网格中,列会填充整个行。这时 col 定义中的 `flex` 和 max-width 属性就派上用场了。

首先,flex 属性的语法。

.col-md-4 {
   flex: 0 0 33.333333%;
 }

语法实际上是三个其他属性的快捷语法。

  1. 第一个数字用于 flex-grow 属性。
  2. 第二个用于 flex-shrink 属性。
  3. 第三个用于 flex-basis 属性。

让我们从第三个开始:flex-basis 属性。它指定了应用于它的元素的初始宽度。在上面,它指定元素应占用父 flex 容器(在本例中为带有 row 类的 div 元素)宽度的 33.333333%。但等等!我们还将元素的 width 指定为 100%!好吧,flex-basis 属性优先于 width 属性。

默认值是 auto,它使元素使用其 size 属性。

一些示例

<!-- flexbox DIV with width specification for flex items: use flex-basis percentage-->
<div  class="my-flex el-frame">
    <div  style="flex-basis:20%; background-color:red;">My first item with flex width</div>
    <div  style="flex-basis:30%; background-color:green;">My second item with flex width</div>
    <div  style="flex-basis:50%; background-color:blue;">My third item with flex width</div>
</div>

<!-- flexbox DIV with width specification for flex items: also specify a size-->
<div  class="my-flex el-frame">
    <div  style="flex-basis:auto; width:30%; background-color:red;">
          My first item with flex width and size</div>
    <div  style="flex-basis:50%; width:25%; background-color:blue;">
          My second item with flex width and size</div>
</div>

在行动中查看:具有 flex 项宽度规范的 Flexbox DIV.

第一个示例指定了三个宽度总计恰好为 100% 的子项。我们在这里使用百分比,但也可以使用像素宽度或任何其他单位。
第二个示例也指定了一个大小:width 属性。请注意:

  • 对于 flex-basis: auto,将使用 width 属性的宽度。
  • 对于 flex-basis: 50%,将使用此 flex-basis 的宽度,而不是 width 属性的宽度。

好的,那么 flex-growflex-shrink 呢?它们都控制分别处理剩余空间或空间不足的情况,以及如何将它们分配给子项。

首先是 flex-grow。如果为子元素指定的宽度总和小于 flex 容器的总宽度,那么 flex-grow 属性指定了将使用多少可用额外空间来扩展/增长它所应用的元素的大小。如果应用于多个子元素,这些数字的比例告诉如何分配额外空间。

一个例子(随附的代码中有更多示例)。

<!-- flexbox DIV with width specification for flex items: also specify a size-->
<div  class="my-flex el-frame">
    <div  style="flex-basis:30%; background-color:red;">
          My first item with flex width and size</div>
    <div  style="flex-basis:50%; background-color:blue;">
          My second item with flex width and size</div>
</div>
<!-- flexbox DIV with width specification for flex items: also specify growth-->
<div  class="my-flex el-frame">
    <div  style="flex-basis:30%; flex-grow:1; background-color:red;">
          My first item with growth</div>
    <div  style="flex-basis:50%; flex-grow:2; background-color:blue;">
          My second item with double growth</div>
</div>
<!-- flexbox DIV with width specification for flex items: growth calculation-->
<div  class="my-flex el-frame">
    <div  style="width:30%; background-color:red;">My first item original width</div>
    <div  style="width:6.666666%; background-color:orange;">growth</div>
    <div  style="width:50%; background-color:blue;">My second item original width</div>
    <div  style="width:13.333337%; background-color:orange;">growth</div>
</div>

在行动中查看:具有 flex 项增长规范的 Flexbox DIV.

  • 第一个 div 显示了当我们*不*指定任何增长时得到的结果:子项占用它们被分配的空间。
  • 第二个 div 显示了当我们指定增长并将其不均匀地分配给子项时会发生什么:第一个子项可以增长为第二个子项的两倍。
  • 第三个 div 显示了第二个示例的额外空间如何分配给具有 flex-growth 属性的子项。

用于分配额外空间的计算很简单:取额外空间,并根据 flex-grow 因子按比例分配给子项。因此:

  1. 额外空间:100 - (30+50) = 20
  2. 所有增长因子的总和:1+2 = 3
  3. 对于增长因子为 1:1 x (20/3) = 6.666667
  4. 对于增长因子为 2:2 x (20/3) = 13.333333

接下来是 flex-shrink。如果为子元素指定的宽度总和超过了 flex 容器的总宽度,那么 flex-shrink 属性就会起作用。它控制着空间不足必须在子元素之间分配的量。

示例

<!-- flexbox DIV with width specification for flex items: specify size-->
<div  style="display: flex; flex-wrap: nowrap;">
    <div  style="flex-basis:60%; flex-shrink:0; background-color:red;">First no shrink</div>
    <div  style="flex-basis:50%; flex-shrink:0; background-color:blue;">Second no shrink</div>
    <div  style="flex-basis:20%; flex-shrink:0; background-color:green;">Third no shrink</div>
</div>

<!-- flexbox DIV with width specification for flex items: also specify shrink-->
<div  style="display: flex; flex-wrap: nowrap;">
    <div  style="flex-basis:60%; flex-shrink:2; background-color:red;">
          First with double shrink</div>
    <div  style="flex-basis:50%; flex-shrink:1; background-color:blue;">
          Second with shrink</div>
    <div  style="flex-basis:20%; flex-shrink:1; background-color:green;">
          Third with shrink</div>
</div>

<!-- flexbox DIV with width specification for flex items: shrink calculation-->
<div  class="my-flex el-frame">
    <div  style="width:41.052632%; background-color:red;">
          My first item after double shrink</div>
    <div  style="width:18.947368%; background-color:orange;">shrink</div>
</div>

在行动中查看:具有 flex 项收缩规范的 Flexbox DIV.

  • 第一个 div 显示了当我们没有收缩时得到的结果。请注意,为了将没有收缩作为参考,我们需要显式设置 flex-shrink: 0。另外,要使子项一个接一个地排列,我们必须在父 flexbox 上显式设置 flex-wrap: nowrap 属性。否则,将应用换行。
  • 第二个 div 显示了当收缩不均匀地分配给子项时会发生什么:第一个子项可以收缩为其他子项的两倍。
  • 第三个 div 显示了空间不足如何从子项中减去。

空间不足的分配计算如下:

  1. 空间不足为:(60 + 50 + 20) - 100 = 30
  2. 总加权空间为 (2 x 60) + (1 x 50) + (1 x 20) = 190
  3. 对于第一个子 `div` 的加权空间(2 x 60),收缩为:30 x ((2 x 60) / 190) = 18.947368
  4. 第一个子 `div` 的剩余空间为 60 - 18.947368 = 41.052632

好的,现在我们对 flex-basisflex-growflex-shrink 属性的含义有了一定的了解。如我们所见,Bootstrap 列的定义使用了快捷 flex 属性。

.col-md-4 {
   flex: 0 0 33.333333%;
 }

所以,Bootstrap 只是防止任何增长或收缩,并将元素宽度固定为父 flex 容器宽度的 33.333333%。

所以,我上面一直写到元素的宽度是父 flex 容器的百分比。这确实是直接父级!因此,如果你将 flex 属性应用于嵌套在父 flexbox 中的两层深度的元素,而不是直接子元素,那么此属性将*不*被应用。

<!-- flexbox div with flex children two levels deep -->
<div  class="my-flex el-frame">
    <div>
        <div  style="flex-basis:20%; background-color:red;">My first item 2 deep</div>
    </div>
    <div  style="flex-basis:30%; background-color:green;">My second item with flex width</div>
    <div  style="flex-basis:50%; background-color:blue;">My third item with flex width</div>
</div>
<div  class="my-flex el-frame">
    <div>
        <div  style="flex-basis:200px; background-color:red;">My first item 2 deep</div>
    </div>
    <div  style="flex-basis:30%; background-color:green;">My second item with flex width</div>
    <div  style="flex-basis:50%; background-color:blue;">My third item with flex width</div>
</div>

在行动中查看:具有两层深度 flex 项的 Flexbox DIV

剖析响应式断点

关于这个,我将参考我关于 Bootstrap 3 网格系统的文章:剖析响应式断点

构建复杂网格

嵌套行

你也可以在列内嵌套行。

<div  class="container-fluid">
    <div  class="row">
        <div  class="col-md-6">
            <!-- nested rows inside -->
            <div  class="row">
                <div  class="col-6">RowAColARow1Col1</div>
                <div  class="col-6">RowAColARow1Col2</div>
            </div>
            <div  class="row">
                <div  class="col-sm-6">RowAColARow2Col1</div>
                <div  class="col-sm-6">RowAColARow2Col2</div>
            </div>
        </div>
        <!-- the above rows are nested inside a row which is the sibling of the following row
        When we collapse the rows, the following row will float underneath the nested rows -->
        <div  class="col-md-6">RowAColB with a very long text 
         with lots of nonsense and much repeating, with lots of nonsense and 
         much repeating, with lots of nonsense and much repeating, 
         with lots of nonsense and much repeating</div>
    </div>
</div>

查看实际效果.

这里有几点需要注意

  • 嵌套行中的列也加起来总宽度为 12。这是因为 Bootstrap 中列的定义方式:宽度被定义为父容器的百分比。对于嵌套行,父行位于一个列内部,该列在上面的示例中宽度为 6 个单位。但行仍然被视为其子列的 100%。
  • 当达到响应式断点时,RowAColB 列将出现在嵌套列下方。这是可以预期的,因为它是嵌套行父行的同级。
  • 在 Bootstrap 3 框架中,同一行中列的高度由其内容定义,而在 Bootstrap 4 框架中,它们都具有相等的高度。如果你打开 嵌套行的 Bootstrap 3 演示页面 并缩小宽度,使得长文本高于嵌套行的高度,你就可以看到这一点。带有嵌套行的列的背景是完全灰色的。文本的背景是嵌套行的灰色。但是,这些行下方的空白区域也是灰色的:顶层行的背景。如果你在上面的示例中尝试同样的操作,你会注意到空白区域是橙色的:包含嵌套行的列的背景。

重排下列

当然,上述重排当响应式断点命中时的解释方式有一个缺点:如果列转换为行,第二列总是变成第二行,第三列变成第三行,依此类推。

(事实上,这并不完全正确:它取决于你浏览器的阅读方向。但我想你明白了。)

但这可能不是你想要的。你可能希望最左边的列出现在右边列下方的行中。在 Bootstrap 3 中,有 pull 和 push CSS 类用于此目的,但这些在 Bootstrap 4 中已不再存在。Bootstrap 4 代之以用于显式排列列和偏移的 CSS 类。

这也意味着你必须开始考虑你想要的默认布局以及在较大屏幕上查看页面时你想要的布局。假设你有两个 div,在移动屏幕上你想将它们显示为行。但是,在较大屏幕上,你想将第一个 div 显示在左侧。

你会写类似下面的内容:

<div  class="row">
    <div  class="col-md-6 order-md-2">RowAColA_FirstAndOrder2</div>
    <div  class="col-md-6 order-md-1">RowAColB_SecondAndOrder1</div>
</div>

查看实际效果.

请注意

  • 虽然我们使用了 order-md-2order-md-1 CSS 类,但排列也正确应用了。无需指定 order-md-6 的排列。这是因为在 flexbox 世界中子项的排列方式。我们将在剖析部分中对此进行研究。

在 Bootstrap 3 中可以(见前一篇文章)将列拉出或推出来,但在 Bootstrap 4 中已不再可能。

偏移列

你可能还想做的另一件事(我没有在 Bootstrap 3 文章中处理过)是偏移列。

你可以写类似下面的内容:

<div  class="row">
    <div  class="col-md-3">RowAColA_FirstAndOrder2</div>
    <div  class="col-md-3 offset-md-3">RowAColB_Offset3</div>
</div>
<div  class="row">
    <div  class="col-md-3">RowBColA_First</div>
    <div  class="col-md-3 offset-md-9">RowBColB_Offset9</div>
</div>

查看实际效果.

请注意

  • 对于第一行,第二列在第一列之后被推迟 3 个单位。
  • 对于第二行,我们定义了 9 个单位的偏移。你可能认为第二列会屏幕外,但事实并非如此。实际上:它被推到了下一行的开头!一旦我解释了它是如何工作的,你就会明白。

列的可见性

你可能还想做的另一件事是隐藏某些列。

你可以写以下内容:

<div  class="row">
    <div  class="col-md-6">RowAColA</div>
    <div  class="col-md-6">RowAColB</div>
</div>
<div  class="row">
    <div  class="col-md-6 d-none d-md-block">RowBColA</div>
    <div  class="col-md-6 ">RowBColB</div>
</div>
<div  class="row">
    <div  class="col-md-6 d-md-none">RowCColA</div>
    <div  class="col-md-6 ">RowCColB</div>
</div>

查看实际效果.

关于显示类的行为与 Bootstrap 3 相比,有很多变化。

首先,可见性不再通过 hiddenvisible CSS 类来管理。相反,我们需要使用新的 d-none 类来隐藏,并使用一系列 CSS 类来管理元素的 display 属性。

其次,虽然 Bootstrap 3 的 hiddenvisible CSS 类通过最大和最小媒体查询来管理,因此只在两个连续断点之间有效,但 Bootstrap 4 的等效类采用了通常的方法:为断点定义的类从该断点向上有效。

剖析复杂网格:它是如何工作的?

剖析嵌套行

这基本上与 Bootstrap 3 中的工作方式相同,但使用了 CSS flexbox 系统。因为我们在列中定义了一个行来包含嵌套列,所以我们实际上定义了一个新的 flexbox 容器,它作为子列的父容器。

<style>
.my-flex {
    display: flex;
    flex-wrap: wrap;
}
</style>

<div  class="my-flex el-frame">
    <div  style="flex-basis:75%;">
        <div  class="my-flex el-frame">
            <div  style="flex-basis:10%; background-color:red;">
                  My first item with flex width</div>
            <div  style="flex-basis:30%; background-color:green;">
                  My second item with flex width</div>
        </div>
    </div>
    <div  style="flex-basis:25%; background-color:blue;">My third item with flex width</div>
</div>

查看实际效果.

关于这一点其实没什么可说的:我们有一个顶层 div,其 display 值为 flex,并且其直接子项嵌套在其中,flex-basis 已设置,我们现在知道它充当列。其中一个子项中,我们再次放置了一个 flexbox 元素,我们在其中放置了具有 flex-basis 的直接子项。这些子项相对于嵌套的 flexbox 元素(它们是它们的直接父项)来获取它们的 flex-basis

剖析重排下列

列的重排也变得简单了很多:flexbox 模型通过提供 order 属性来直接支持重排。(老实说,其实是反过来的:有一个*通用* order 属性,flexbox 模型支持它,其中之一。)

<div  class="my-flex el-frame">
    <div  style="flex-basis:20%; background-color:red;">
          My first item followed by repeating text, followed by repeating text, 
          followed by repeating text</div>
    <div  style="flex-basis:30%; background-color:green;">My second item</div>
    <div  style="flex-basis:50%; background-color:blue;">My third item</div>
</div>

<div  class="my-flex el-frame">
    <div  style="flex-basis:20%; order:1000; background-color:red;">
          My first item with largest order followed by repeating text, 
          followed by repeating text, followed by repeating text</div>
    <div  style="flex-basis:30%; order:-5; background-color:green;">
          My second item with negative order</div>
    <div  style="flex-basis:50%; background-color:blue;">My third item with no order</div>
</div>

<div  class="my-flex el-frame">
    <div  style="flex-basis:20%; order:1000; background-color:red;">
          My first item with largest order followed by repeating text, 
          followed by repeating text, followed by repeating text</div>
    <div  style="flex-basis:15%; order:-5; background-color:green;">
          My second item with negative order -5</div>
    <div  style="flex-basis:15%; order:-5; background-color:yellow;">
          My third item with negative order -5</div>
    <div  style="flex-basis:50%; background-color:blue;">My fourth item with no order</div>
</div>

查看实际效果.

它的工作原理很简单:所有子元素都按其 `order` 属性排序,然后进行渲染。

请注意

  • 指定无序行为为 0 的 order 值。
  • 当两次指定相同的 order 值时,元素将按照它们的定义顺序渲染。

剖析偏移列

列的偏移是通过向代表列的 `div` 添加边距来完成的。

<div  class="my-flex el-frame">
<div  style="flex-basis:33%; background-color:red;">
 My first item followed by repeating text, followed by repeating text, 
 followed by repeating text</div>
<div  style="flex-basis:33%; background-color:green;">My second item</div>
<div  style="flex-basis:34%; background-color:blue;">My third item</div>
</div>

<div  class="my-flex el-frame">
<div  style="flex-basis:33%; background-color:red;">My first item with 
      largest order followed by repeating text, followed by repeating text, 
      followed by repeating text</div>
<div  style="flex-basis:34%; margin-left:33%; background-color:blue;">
      My third item with no order</div>
</div>

<div  class="my-flex el-frame">
<div  style="flex-basis:33%; background-color:red;">My first item with 
      largest order followed by repeating text, followed by repeating text, 
      followed by repeating text</div>
<div  style="flex-basis:34%; margin-left:45%; ; background-color:blue;">
      My fourth item with no order</div>
</div>

查看实际效果.

通过在左侧添加边距,我们将列推向右侧。当然,如果边距变得太大,div 会被推到下一行。你可能期望它从开头开始,但由于边距仍然存在,它不会。

剖析列的可见性

对于可见性和 visibility:hiddendisplay:none CSS 属性之间的区别的初步介绍,我将转到我关于 Bootstrap 3 网格的上一篇文章:剖析列的可见性

除了类的命名和响应式断点的处理方式之外,这里没有太多新内容。

<div  class="my-flex el-frame">
    <div  style="display:none;">none</div>
    <div  style="visibility:hidden;">hidden</div>
</div>

<div  class="el-frame">
    <div  style="background:green;width:25%;display:block">Fourth width, display block</div>
    <div  style="background:blue;display:inline;width:50%">Half width, display inline</div>
    <div  style="background:green;width:25%;display:flex">Fourth width, display flex</div>
</div>

<div  class="my-flex el-frame">
    <div  style="background:green;width:25%;display:block">Fourth width, display block</div>
    <div  style="background:blue;display:inline;width:50%">Half width, display inline</div>
    <div  style="background:green;width:25%;display:flex">Fourth width, display flex</div>
</div>

<div  class="el-frame">
    <div  class="showit-always">Show it always</div>
    <div  class="showit hideit">Show it always, unless I hide it</div>
    <div  class="showit hideit-later">Show it always, unless I hide it later</div>
    <div  class="showit-always hideit">Show it always, even if I hide it</div>
</div>

查看实际效果.

隐藏仍然通过将 display 属性设置为 none 来完成。但是,在 Bootstrap 3 中有 visiblehidden CSS 类,而在 Bootstrap 4 中,我们只有一组根据 `display` 属性的可能值命名的类。

要使内容不可见,选择很简单:我们将 `display` 属性设置为 `none`。

但是,对于使内容可见,你选择所有可能值中的哪个?大多数情况下,d-xx-block CSS 类之一就足够了。它们将 display 属性设置为 block 值。md-xx-inline 作为 flex 元素的子项没有意义,正如你在上面的示例中所看到的。

如上一篇文章所述,inline 值使通常表现得像 `blocks` 的元素表现得像 inline 元素(例如 <span>)。内联元素在同一行上继续,并且只占用它们需要的空间,而 block 元素占用全部宽度。这就是你在上面第二个父 `div` 中看到的:内联蓝色 div ,尽管其宽度设置为占用父级的 25%,但它只占用所需空间。然而,像第三个 div 这样的 flex 父级使其子项表现得像 block 元素,这就是为什么在这种情况下蓝色元素会占用指定宽度。

参考文献

版本历史

  • 版本 1.0:初始版本
  • 版本 1.0.1:更正了第一个示例链接中的错误(正如评论中所报告的那样)
© . All rights reserved.