Bootstrap

重写 CSS Flexible Box

一、是什么?

FlexFlexible Box 的缩写, 意为 弹性布局, 用来为盒状模型提供更为灵活的布局能力, 它给 Flexbox子元素 之间提供了强大的 空间分布(伸缩)对齐 能力

二、基础概念

2.1 容器

采用 Flex 布局的元素 (设置了 display: flex | inline-flex 的元素) 称之为 Flex 容器 (flex container), 在后面我们统称为 容器, 如下代码: box-blockbox-inline 元素我们称之为 容器, 其中 box-block 为块级元素 box-inline 为行类元素

<style>
  .box-block {
    display: flex;
  }
  .box-inline {
    display: inline-flex;
  }
</style>
<div class="box-block"></div>
<div class="box-inline"></div>

2.2 项目

容器内所有 子元素, 我们称之为 Flex 项目 (flex item), 在后面我们统称为 项目, 如下代码所示: child 元素我们称之为 项目

<style>
  .box {
    display: flex;
  }
</style>
<div class="box">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>

将容器设为 Flex 布局以后, 容器内的块级元素 (例: display: block) 将不再具有 块级元素 的特性, 有如下演示代码, 图中 item 元素都不再具有块级元素的特性了

<style>
  #wrapper {
    display: flex;
    background: #eee;
    padding: 10px;
  }
  .item {
    width: 50px;
    height: 50px;
    text-align: center;
    line-height: 50px;
  }
  .item-1 { background:brown; }
  .item-2 { background:pink; }
  .item-3 { background:orchid; }
</style>
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在弹性容器中项目的 margin垂直方向 上的值不会进行合并了, 如下代码: box 容器是常规的布局, 子元素在垂直方向的 margin 发生合并, 但是在 flex-box 中子元素在垂直方向的 margin 则不会发生合并

<style>
  #box {
    left: 0;
    position: fixed;
  }

  #flex-box {
    display: flex;
    width: 230px;
    flex-wrap: wrap;

    left: 200px;
    position: fixed;
  }

  .item {
    width: 90px;
    height: 90px;
    margin: 10px;
    background: red;
    line-height: 40px;
    text-align: center;
  }
</style>
<div id="box">
  <div class="item">box 1</div>
  <div class="item">box 2</div>
</div>

<div id="flex-box">
  <div class="item">flex-box 1</div>
  <div class="item">flex-box 2</div>
  <div class="item">flex-box 3</div>
  <div class="item">flex-box 4</div>
</div>

image

布局重置: 当将容器设为 Flex 布局以后, 容器内的所有项目的 floatclearvertical-align 属性都将失效, 这里姑且理解为 布局重置

2.3 一维布局

Flexbox 布局, 是一种 一维 布局, 因为它 一次 只能处理 一个维度 上的元素布局, 一行 或者 一列, 作为对比的是另外一个二维布局 CSS Grid Layout, 它可以同时处理 多行多列 上的布局, 当然这里不对 Grid 进行展开

虽然 Flexbox一维模型, 但我们可以通过 flex-wrap 实现多行(列) Flex 容器, 可以将我们的 flex 项目应用到多行(列)中, 在这种情况下我们应该把 每一行(列) 看作一个新的 flex 容器, 任何空间分布都将在该行(列)上发生, 而不影响该空间下的其他行(列)

image

2.4 主轴和交叉轴

  • 容器默认存在两根轴: 主轴 (项目沿主轴进行一一排列)、交叉轴 (垂直于主轴)

  • 主轴的开始位置 (与边框的交叉点) 叫做 main start(起始), 结束位置叫做 main end(终止)

  • 交叉轴的开始位置叫做 cross start(起始), 结束位置叫做 cross end(终止)

  • 单个项目占据的主轴空间叫做 main size, 占据的交叉轴空间叫做 cross size

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

三、容器属性

属性描述
flex-direction决定 主轴 的方向 (即项目的排列方向)
flex-wrap决定当一条轴线排不下所有项目时, 要如何进行 换行
flex-flowflex-direction 属性和 flex-wrap 属性的 简写形式
justify-content定义项目在 主轴 方向上的对齐方式
align-content项目一一进行排列必然形成行, 该属性则定义了 行(轴线)交叉轴 上的对齐方式
align-items定义 行内(单行内) 的所有 项目交叉轴方向上 的对齐方式

3.1 设置主轴方向「flex-direction」

flex-direction 属性决定主轴的方向 (即项目的排列方向), 主轴的方向又决定了交叉轴的方向, 因为交叉轴总是垂直于主轴, 该属性具有四个属性值, 对应四个主轴方向, 需要特别注意的是交叉轴只有两个方向要么 从左向右 要么就是 从上到下

属性值描述
row默认值, 从左向右
row-reverserow 属性相反, 即从右向左
column从上到下
column-reversecolumn 相反, 即从下到上

下图展示了 flex-direction 属性不同取值, 容器内项目的排列顺序

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下面是上图演示代码: 通过修改容器 flex-direction 属性的取值, 将得到上图演示结果

#wrapper {
  display: flex;
  flex-direction: row;
  width: 200px;
  height: 200px;
  background: #eee;
  padding: 10px;
}
.item {
  width: 50px;
  height: 50px;
  text-align: center;
  line-height: 50px;
}
.item-1 { background: brown; }
.item-2 { background: pink; }
.item-3 { background: orchid; }
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>

3.2 设置换行「flex-wrap」

默认情况下, 项目都在 一行 上进行排列, flex-wrap 属性决定了当一行内排不下所有项目时, 如何进行换行

属性值描述
nowrap默认值, 不进行换行
wrap允许换行, 每行 沿着 交叉轴方 向进行排列
wrap-reverse允许换行, 每行 沿着 交叉轴 相反 方向进行排列

如下图, 默认情况 (flex-wrap: nowrap) 下项目都在 一行 内排列着, 即使一行无法排下所有的项目, 也会对项目在主轴方向上的大小进行压缩, 迫使所有项目都能够在一行进行排列, 如下代码所示 item 在主轴上的宽度实际上是被压缩了

<style>
  #wrapper {
    display: flex;
    flex-direction: row;
    width: 200px;
    height: 200px;
    background: #eee;
    padding: 10px;
  }
  .item {
    width: 100px;
    height: 50px;
    text-align: center;
    line-height: 50px;
  }
  .item-1 { background: brown; }
  .item-2 { background: pink; }
  .item-3 { background: orchid; }
</style>
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

flex-wrap: wrap: 当所有项目无法在一行排列时, 允许进行换行, 并且 每行 的排列顺序为 交叉轴方向, 如下代码所示

<style>
  #wrapper {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    width: 200px;
    background: #eee;
    padding: 10px;
  }
  .item {
    width: 100px;
    height: 50px;
    text-align: center;
    line-height: 50px;
  }
  .item-1 { background:brown; }
  .item-2 { background:pink; }
  .item-3 { background:orchid; }
</style>
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>

image

flex-wrap: wrap-reverse: 当所有项目无法在一行排列时, 允许进行换行, 并且 每行 的排列顺序和 交叉轴方向相反, 如下代码所示

<style>
  #wrapper {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap-reverse;
    width: 200px;
    background: #eee;
    padding: 10px;
  }
  .item {
    width: 100px;
    height: 50px;
    text-align: center;
    line-height: 50px;
  }
  .item-1 { background: brown; }
  .item-2 { background: pink; }
  .item-3 { background: orchid; }
</style>
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>

image

3.3 简写属性「flex-flow」

flex-flow 属性是 flex-direction 属性和 flex-wrap 属性的简写形式, 默认值为 row nowrap

<style>
  #wrapper {
    display: flex;
    flex-flow: row-reverse wrap;
    width: 200px;
    background: #eee;
    padding: 10px;
  }
  .item {
    width: 100px;
    height: 50px;
    text-align: center;
    line-height: 50px;
  }
  .item-1 { background: brown; }
  .item-2 { background: pink; }
  .item-3 { background: orchid; }
</style>
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>

image

3.4 设置项目在主轴对齐方式「justify-content」

如题 justify-content 属性定义了项目在主轴上的对齐方式, 或者说是排列方式, 所有属性值如下:

属性值描述
flex-start默认值, 项目在主轴上向主轴开始方向靠拢
flex-end项目在主轴上向主轴结束方向靠拢
center项目在主轴上全部往中间靠拢
space-between设置主轴方向多余空间的处理方式 (具体看图)
space-around设置主轴方向多余空间的处理方式 (具体看图)
space-evenly设置主轴方向多余空间的处理方式 (具体看图)

下图演示了 justify-content 所有可选值对应的排列演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

修改下列代码中 justify-content 属性值, 将得到上图对应值的演示效果

<style>
  #wrapper {
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    width: 200px;
    height: 200px;
    background: #eee;
  }
  .item {
    width: 50px;
    height: 50px;
    text-align: center;
    line-height: 50px;
  }
  .item-1 { background: brown; }
  .item-2 { background: pink; }
  .item-3 { background: orchid; }
</style>
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>

3.5 设置每行的对齐方式「align-content」

当项目沿主轴排列成一行(列)或者多行(列)时, 可通过 align-content 属性设置这些 在交叉轴上的对齐方式, 该属性可选值如下:

属性值描述
stretch默认值, 每行都在交叉轴方法进行均匀伸缩, 企图占满交叉轴上所有剩余的空间
flex-start每行都向交叉轴起点靠拢
flex-end每行都向交叉轴终点靠拢
center每行都向交叉轴中间靠拢
space-between设置交叉轴方向多余空间的处理方式 (具体看图)
space-around设置交叉轴方向多余空间的处理方式 (具体看图)
space-evenly设置交叉轴方向多余空间的处理方式 (具体看图)

下图演示了 align-content 所有可选值对应的排列演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

修改下列代码中 align-content 属性值, 将得到上图对应值的演示效果

<style>
  #wrapper {
    width: 200px;
    height: 200px;
    background: #eee;
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
  }
  .item {
    width: 40px;
    line-height: 40px;
    margin: 1px;
    background: red;
    text-align: center;
  }
  .item-50h { line-height: 50px; }
  .item-70h { line-height: 70px; }
  .item-30h { line-height: 30px; }
</style>
<div id="wrapper">
  <div class="item item-50h">1</div>
  <div class="item item-70h">2</div>
  <div class="item item-30h">3</div>
  <div class="item item-50h">4</div>
  <div class="item item-70h">5</div>
  <div class="item item-30h">6</div>
</div>

3.6 设置行内项目在交叉轴上的对齐方式「align-items」

已知项目沿主轴进行排列成 一行 或者 多行, 上文提到我们可以通过 align-content 设置 每行 在交叉轴方向的对齐方式, 那么通过 align-items 我们则可以设置 行内 所有 项目 在该 行内 沿着 交叉轴方法对齐方式, 该属性可能值如下:

属性值描述
stretch默认值, 行内项目(在未给项目设置高度或者设为 auto 情况下)该项目将在交叉轴方法自动撑开, 占满该行在交叉轴上的所有剩余空间
flex-start行内项目在交叉轴上向开始位置靠拢
flex-end行内项目在交叉轴上向结束位置靠拢
center行内项目在交叉轴上向中间位置靠拢
basline行内项目按照文字基线进行对齐 (用于不同字体大小、行高的文字布局上特别好用)

下图演示了 align-items 所有可选值对应的排列演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

修改下列代码中 align-items 属性值, 将得到上图对应值的演示效果

<style>
  #wrapper {
    width: 200px;
    height: 200px;
    background: #eee;
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    align-items: stretch;
  }
  .item {
    width: 40px;
    line-height: 40px;
    margin: 1px;
    background: red;
    text-align: center;
  }
  .item-50h { line-height: 50px; }
  .item-70h { line-height: 70px; }
  .item-30h { line-height: 30px; }
</style>
<div id="wrapper">
  <div class="item item-50h">1</div>
  <div class="item item-70h">2</div>
  <div class="item item-30h">3</div>
  <div class="item item-50h">4</div>
  <div class="item item-70h">5</div>
  <div class="item item-30h">6</div>
</div>

对比代码和示意图, 会发现 baslinecenter 效果貌似一样, 但实际上是因为所有项目字体大小相同原因导致, 下面例子修改了每个项目的字体大小, 从效果图就能够直观看出 basline 的效果了

<style>
  #wrapper {
    width: 200px;
    height: 200px;
    background: #eee;
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
+   align-items: baseline;
  }
  .item {
    width: 40px;
+   line-height: 1;
    margin: 1px;
    background: red;
    text-align: center;
  }
+ .item-50h { font-size: 50px; }
+ .item-70h { font-size: 70px; }
+ .item-30h { font-size: 30px; }
</style>
<div id="wrapper">
  <div class="item item-50h">1</div>
  <div class="item item-70h">2</div>
  <div class="item item-30h">3</div>
  <div class="item item-50h">4</div>
  <div class="item item-70h">5</div>
  <div class="item item-30h">6</div>
</div>

image

四、项目属性

属性描述
order定义项目的排列顺序
flex-grow定义项目的放大比例
flex-shrink定义项目的缩小比例
flex-basis定义了在分配多余空间之前, 项目占据的主轴空间
flexflex-grow flex-shrink flex-basis 的简写属性
align-self允许单个项目有与其他项目不一样的对齐方式, 可覆盖 align-items 属性 (重新设置该项目的 align-items 属性 )

4.1 设置项目的排列属性「order」

order 属性定义项目的排列顺序, 该属性值是一个 integer(整型数字) 类型, 数值越小, 排列越靠前, 默认为 0 同时该属性也支持一个 负数, 如下代码: 为每个项目设置了 order, 会发现项目按照 order 的顺序(从小到大)进行排列

<style>
  #wrapper {
    display: flex;
    flex-direction: row;
    width: 200px;
    height: 200px;
    background: #eee;
  }
  .item {
    width: 50px;
    line-height: 50px;
    height: 50px;
    text-align: center;
  }
  .item-1 { background: brown; order: 3; }
  .item-2 { background: pink; order: 1; }
  .item-3 { background: orchid; order: -1; }
</style>
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.2 设项目增长比例「flex-grow」

  • 已知项目是沿着主轴的方向进行排列的, 当项目依次排列后主轴方法存在剩余的空间时, 我们可通过 flex-grow 来约定项目在自适应情况下占 剩余空间比例
  • 主轴上剩余空间的计算则取决于 flex-basis (下面介绍)
  • 该属性值是一个 number 类型数据, flex-grow 属性的 默认值 则为 0 即如果存在剩余空间, 也不进行放大, 不进行任何处理
  • 如果所有项目的 flex-grow 属性值都相等(假如都为 1), 则它们将 等分 剩余空间
  • 如果一个项目的 flex-grow 属性为 2, 其他项目都为 1, 则前者占据的剩余空间将比其他项多一倍, 即按 2:1 的比例来 分配 剩余空间
  • 需要特别注意的是 负值 对该属性是无效的

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在下面代码中, 可通过修改每个项目的 flex-grow 属性值, 得到上述效果

<style>
  #wrapper {
    display: flex;
    flex-direction: row;
    width: 400px;
    height: 200px;
    background: #eee;
  }
  .item {
    width: 50px;
    line-height: 50px;
    height: 50px;
    text-align: center;
  }
  .item-1 { background: brown; flex-grow: 2; }
  .item-2 { background: pink; flex-grow: 1; }
  .item-3 { background: orchid; flex-grow: 1; }
</style>
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>

4.3 设置项目缩小比例「flex-shrink」

  • 已知在项目沿主轴进行排序时, 当主轴无法容下所有项目, 并且在不允许进行换行的情况下所有项目会被 压缩, 而每个项目被 压缩比例 则是由 flex-shrink 属性进行控制的, 也就是说 flex-shrink 属性用于定义每个项目的 压缩 比例

  • 该属性值是一个 number 类型数据, flex-shrink 属性的默认值则为 1 即当空间不足时, 所有项目 等比例 缩小

  • 如果所有项目的 flex-shrink 属性都为 1, 当空间不足时, 将 等比例 缩小(这也是默认情况)

  • 如果一个项目的 flex-shrink 属性为 0, 其他项目都为 1, 则空间不足时, 前者不缩小, 后者 等比例 进行压缩

  • 如果一个项目的 flex-shrink 属性为 2, 其他项目都为 1, 则空间不足时, 前者和后者按照 2:1 进行压缩

  • 需要特别注意的是 负值 对该属性是无效的

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在下面代码中, 可通过修改每个项目的 flex-shrink 属性值, 得到上述效果

<style>
  #wrapper {
    display: flex;
    flex-direction: row;
    width: 400px;
    height: 200px;
    background: #eee;
  }
  .item {
    width: 200px;
    line-height: 50px;
    height: 50px;
    text-align: center;
  }
  .item-1 { background: brown; flex-shrink: 2; }
  .item-2 { background: pink; flex-shrink: 1; }
  .item-3 { background: orchid; flex-shrink: 1; }
</style>
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>

需要注意是的: 默认情况下, 元素不会缩短至小于 内容框尺寸, 若想改变这一状况, 需要设置元素的 min-widthmin-height 属性

4.4 设置项目基础大小「flex-basis」

  • flex-basis 可用于设置项目在主轴方向的 基础大小, 该属性支持所有 CSS 尺寸值, 值默认为 auto 取项目自身的大小(widthheight)
  • 上文提到 flex-grow 属性会按比例分配主轴的 剩余空间, 那么这个 剩余空间 又是怎么算的呢? 主轴上的剩余空间其实就等于 主轴长度 扣除 所有项目基础大小
  • 需要注意的是当一个元素同时被设置了 flex-basiswidth(height) flex-basis 将具有更高的优先级

如下代码所示, 我们为容器设置了总宽度、并且为第一个项目设置了 flex-basis: 400px; 那么剩余项目将会按比例分配 剩余空间(800px - 400px)

<style>
  #wrapper {
    display: flex;
    flex-direction: row;
    width: 800px;
    height: 200px;
    background: #eee;
  }
  .item {
    width: 50px;
    line-height: 50px;
    height: 50px;
    text-align: center;
  }
  .item-1 { background: brown; flex-grow: 1; flex-basis: 400px; }
  .item-2 { background: pink; flex-grow: 1;; }
  .item-3 { background: orchid; flex-grow: 1;; }
</style>
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.5 简写属性「flex」

flex 属性是 flex-grow, flex-shrinkflex-basis 的简写, 默认值为 0 1 auto, 这里我们可以使用一个、两个或三个值来指定 flex 属性:

  1. 单值语法, 该值满足以下规则:
  • 一个无单位的数值: 该值会被作为 flex-grow 的值, 同时 flex-shrink 的值将会被设置为 1, flex-basis 的值将被设置为 0%, 即: flex: <number> 1 0%
  • 一个有效的尺寸值: 它会被当作 flex-basis 的值, 同时 flex-growflex-shrink 都会被设置为 1, 即: flex: 1 1 <size>
  • 关键字 noneautoinitial, 具体取值参考下文表格
  1. 双值语法, 第一个值必须为一个 无单位数值, 并且它会被当作 flex-grow 的值, 第二个值满足以下规则:
  • 一个无单位数值: 它会被当作 flex-shrink 的值, 此时 flex-basis 会被设置为 0%
  • 一个有效的尺寸值: 它会被当作 flex-basis 的值, 此时 ``flex-shrink会被设置为1`
  1. 三值语法
  • 第一个值必须为一个无单位数值, 并且它会被当作 flex-grow 的值
  • 第二个值必须为一个无单位数值, 并且它会被当作 flex-shrink的值
  • 第三个值必须为一个有效的尺寸值, 并且它会被当作 flex-basis 的值

在实际开发中我们更 推荐 使用 单值缩写, 而不是完整的 3 个属性值, 因为 CSS 对于单值属性的 flex 从实用角度进行了优化:

简写等价于备注
flex: initialflex: 0 1 auto初始值, 常用, 适用场景少, 元素会根据自身宽高来设置尺寸, 不增长、自动压缩
flex: 0flex: 0 1 0%适用场景少, 不设置元素尺寸, 不增长、自动压缩
flex: 1flex: 1 1 0%推荐, 不设置元素尺寸, 自动增长、自动压缩
flex: noneflex: 0 0 auto推荐, 元素会根据自身宽高来设置尺寸, 不增长、不压缩
flex: autoflex: 1 1 auto适用场景少, 元素会根据自身的宽度与高度来确定尺寸, 等比增长、压缩

4.6 指定项目在交叉轴上对齐方式「align-self」

还记得在 flex 容器中我们可以通过 align-items 属性来设置 行内项目 在交叉轴上的对齐方式吗? 如果我们需要行内 某个项目 具有鹤立独行的对齐方式时就可以通过, 为项目设置 align-self 来修改(覆盖)行内项目在交叉轴上的对齐方式

属性值描述
auto默认值, 等于为父元素的 align-items
flex-start行内项目在交叉轴上向开始位置靠拢
flex-end行内项目在交叉轴上向结束位置靠拢
center行内项目在交叉轴上向中间位置靠拢
basline行内项目按照文字基线进行对齐 (用于不同字体大小、行高的文字布局上特别好用)
stretch(默认) 行内项目(在未为项目设置高度或者设为 auto 情况下)在交叉轴方法进行伸缩, 占满该行在交叉轴上的所有剩余空间

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上图演示代码:

<style>
  #wrapper {
    width: 200px;
    height: 200px;
    background: #eee;
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    align-items: flex-start;
  }
  .item {
    width: 40px;
    line-height: 40px;
    margin: 1px;
    background: red;
    text-align: center;
  }
  .item-50h { line-height: 50px; }
  .item-70h { line-height: 70px; }
  .item-30h { line-height: 30px; align-self: flex-end; }
</style>
<div id="wrapper">
  <div class="item item-50h">1</div>
  <div class="item item-70h">2</div>
  <div class="item item-30h">3</div>
  <div class="item item-50h">4</div>
  <div class="item item-70h">5</div>
  <div class="item item-30h">6</div>
</div>

五、flex 布局的一些小例子

5.1 文字组合布局

不同大小的文字组合布局, 使用 align-items: baseline; 实现文本的基线对齐

image

上图演示代码

<style>
  body { padding: 50px; } 
  #wrapper {
    display: inline-flex;
    padding: 0 10px;
    height: 60px;
    background-image: linear-gradient(120deg, #84fab0 0%, #8fd3f4 100%);
  }
  .no { font-size: 30px; }
  .order { font-size: 60px; }
  .line {
    border-left: 2px solid #333;
    height: 40px;
    margin: 0 10px;
    align-self: center;
  }
  .row-left {
    display: flex;
    line-height: 1;
    align-items: baseline;
  }
  .row-right {
    height: 100%;
    font-size: 18px;
    text-align: center;
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
  }
</style>
<div id="wrapper">
  <div class="row-left">
    <div class="no">No.</div>
    <div class="order">14</div>
  </div>
  <div class="line"></div>
  <div class="row-right">
    <div>五月</div>
    <div>2023</div>
  </div>
</div>

5.2 单个项目在容器内的各种可能布局

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上面的效果实际上是对 justify-contentalign-items 属性的 flex-start center flex-end 三个属性的组合, 通过依次修改 flex 容器 justify-contentalign-items 属性值, 将实现上诉布局

<style>
  body { padding: 50px; }
  #wrapper {
    background: #eee;
    margin: 5px;
    width: 240px;
    height: 240px;
  }
  .item {
    width: 80px;
    height: 80px;
    background: red;
  }
  .flex {
    display: flex;
    justify-content: flex-start;
    align-items: flex-start;
  }
</style>
<div id="wrapper" class="flex">
  <div class="item"></div>
</div>

5.3 网格布局

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为每个项目设置 flex-grow 属性, 来平均分配容器的剩余空间

<style>
  body { padding: 50px; }
  #wrapper {
    background: #eee;
    padding: 5px;
  }
  .item {
    height: 50px;
    line-height: 50px;
    text-align: center;
    background: red;
  }
  .grid {
    display: flex;
  }
  .grid-cell {
    /* 推荐使用简写属性 flex: 1 */
    flex-grow: 1;
    margin: 5px;
  }
</style>
<div id="wrapper">
  <div class="grid">
    <div class="grid-cell item">1/2</div>
    <div class="grid-cell item">1/2</div>
  </div>
  <div class="grid">
    <div class="grid-cell item">1/3</div>
    <div class="grid-cell item">1/3</div>
    <div class="grid-cell item">1/3</div>
  </div>
  <div class="grid">
    <div class="grid-cell item">1/4</div>
    <div class="grid-cell item">1/4</div>
    <div class="grid-cell item">1/4</div>
    <div class="grid-cell item">1/4</div>
  </div>
  <div class="grid">
    <div class="grid-cell item">1/5</div>
    <div class="grid-cell item">1/5</div>
    <div class="grid-cell item">1/5</div>
    <div class="grid-cell item">1/5</div>
    <div class="grid-cell item">1/5</div>
  </div>
</div>

5.4 网格布局: 指定项目具有固定宽度

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

个别子项通过 flex-basis 来设置固定宽度, 其余项目通过 flex-grow 来平均分布剩余空间

<style>
  body { padding: 50px; }
  #wrapper {
    background: #eee;
    padding: 5px;
  }
  .grid {
    display: flex;
  }
  .grid-cell {
    height: 50px;
    margin: 5px;
    line-height: 50px;
    text-align: center;
    background: red;
  }
  .grid:nth-child(1) .grid-cell { flex: 1; }
  .grid:nth-child(1) .grid-cell:nth-child(1) {
    flex: 0 0 50%;
  }

  .grid:nth-child(2) .grid-cell { flex: 1; }
  .grid:nth-child(2) .grid-cell:nth-child(1) {
    flex: 0 0 400px;
  }

  .grid:nth-child(3) .grid-cell { flex: 1; }
  .grid:nth-child(3) .grid-cell:nth-child(1) {
    flex: 0 0 20%;
  }
  .grid:nth-child(3) .grid-cell:nth-child(4) {
    flex: 0 0 20%;
  }

  .grid:nth-child(4) .grid-cell { flex: 1; }
  .grid:nth-child(4) .grid-cell:nth-child(1) {
    flex: 0 0 200px;
  }
  .grid:nth-child(4) .grid-cell:nth-child(5) {
    flex: 0 0 200px;
  }
</style>
<div id="wrapper">
  <div class="grid">
    <div class="grid-cell">50%</div>
    <div class="grid-cell">平均分布</div>
    <div class="grid-cell">平均分布</div>
  </div>
  <div class="grid">
    <div class="grid-cell">400px</div>
    <div class="grid-cell">平均分布</div>
    <div class="grid-cell">平均分布</div>
  </div>
  <div class="grid">
    <div class="grid-cell">20%</div>
    <div class="grid-cell">平均分布</div>
    <div class="grid-cell">平均分布</div>
    <div class="grid-cell">20%</div>
  </div>
  <div class="grid">
    <div class="grid-cell">200px</div>
    <div class="grid-cell">平均分布</div>
    <div class="grid-cell">平均分布</div>
    <div class="grid-cell">平均分布</div>
    <div class="grid-cell">200px</div>
  </div>
</div>

5.5 圣杯布局

  • 圣杯布局 (Holy Grail Layout) 指的是一种最常见的网站布局, 页面从上到下, 分成三个部分: 头部 (header)、躯干 (body)、尾部 (footer); 其中躯干又水平分成三栏, 从左到右为: 导航、主栏、副栏

  • 同时这里我们满足当屏幕宽度小于 785px 时躯干从水平布局变为垂直分布, 从上到下依次是: 航、主栏、副栏。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下面是实现代码

<style>
  body { padding: 50px; }
  #wrapper {
    display: flex;
    flex-direction: column;
  }
  .row{ flex-grow: 1;}
  .header, .footer{ background: #eee; line-height: 50px; text-align: center; }
  .body{ display: flex; height: 400px; }
  .left{ flex: 0 0 12em; background: red; }
  .content{ flex: 1;background: brown; }
  .right{ flex: 0 0 12em; background: blue; }
  @media (max-width: 768px) {
    .body{ display: flex; height: 400px; flex-direction: column; }
    .left{ flex: auto; background: red; }
    .content{ flex: auto;background: brown; }
    .right{ flex: auto; background: blue; }
  }
</style>
<div id="wrapper">
  <div class="row header">#header</div>
  <div class="row body">
    <div class="left">#left</div>
    <div class="content">#content</div>
    <div class="right">#right</div>
  </div>
  <div class="row footer">#footer</div>
</div>

5.6 输入框布局

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下面代码实现了上图所示输入框, 输入框带有前后缀, Input 区域将自适应撑开

<style>
  body {
    padding: 50px;
  }
  #wrapper {
    display: flex;
    border: 1px solid #eee;
    border-radius: 6px;
    line-height: 50px;
  }
  .prefix, .suffix {
    padding: 0 20px;
    background: #eee;
  }
  .input { flex:1; padding: 0 10px; }

</style>
<div id="wrapper">
  <div class="prefix">prefix</div>
  <div class="input">input</div>
  <div class="suffix">suffix</div>
</div>

5.7 图文左右布局

image

下面代码实现了上图所示图文布局, 图片区域固定大小, 文本居右

<style>
  #wrapper {
    display: flex;
    align-items: flex-start;
  }
  .img {
    flex: none;
    width: 50px;
    height: 50px;
    background: red;
    margin-right: 10px;
  }
</style>
<div id="wrapper">
  <div class="img">img</div>
  <div class="">
    Ubuntu Phone has been designed with obsessive attention to detail.
    Form follows function throughout, from the ever-changing welcome
    screen to essentials like messaging and alarms. And the Launcher
    puts it all at your fingertips, whatever you’re doing with your phone.
    Canonical is the global software vendor that provides commercial, design
    and engineering support to the Ubuntu project. Today, our hardware
    enablement team supports the pre-installation of Ubuntu on more
    than 10% of all new PCs shipped, worldwide.
  </div>
</div>

image

;