CSS 学习之 flexbox

2018/09/25 FrontEnd

弹性盒子感觉有些像 Android 布局中的 LinearLayoutweight 的组合,可以实现居中、按权重分配长宽等,但貌似比 Android 里的要复杂的多了,可能是因为我还不够熟悉吧!

Flexbox 弹性盒子

(MDN 原话)以下简单的布局要求是难以或不可能用这样的工具( floats 和 positioning)方便且灵活的实现的:

  1. 在父内容里面垂直居中一个块内容。
  2. 使容器的所有子项占用等量的可用宽度/高度,而不管有多少宽度/高度可用。
  3. 使多列布局中的所有列采用相同的高度,即使它们包含的内容量不同。

Flexbox 可以实现。


      article {
        /*至少宽度*/
        flex: 200px;
        padding: 10px;
        margin: 10px;
        background: aqua;
      }

      section {
        display: flex;
        /*排列方向*/
        flex-direction: row;
        /*自动换行*/
        flex-wrap: wrap;
      }

flex 容器与子项

  • 设置了 display:flex 的父元素被称为 “flex 容器”
  • 在 flex 容器中表现为 flex 的被称为 “flex 项”

排列方向及是否多行

flex-direction 决定 flex 排列方向,默认为 row 即水平的行方向,可以修改为 column 即垂直方向,也可以修改为水平方向的逆向和垂直方向的逆向排列。

flex-direction: column

flex-wrap 表示 flex 元素是单行还是多行显示,可选的值有:

  • nowrap 单行显示,这样可能导致 flex 元素溢出 flex 容器
  • wrap 元素被打断到多行显示
  • wrap-reversewrap 一样多行,但 cross-startcross-end 互换

flex-directionflex-wrap 的缩写是:flex-flow

flex-flow 接收两个值,第一个表示方向,第二个表示是否多行:

flex-flow: row wrap;

每个 flex 子项的可用大小

flex 属性表示大小权重,类似安卓的 weight

article {
  flex: 1;
}

无单位的比例值,这表示每个元素占用空间都是相等的。

可以先指定所有元素的权重为 1,然后指定其中某一个元素的权重是他们的几倍:

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

如果有三个 article 元素,这样第二个元素占的比例就是五分之三。

我们还可以在声明权重的基础上,再指定一下最小宽度:


article {
  flex: 1 200px;
}

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

上面的代码意味着,每个元素的宽度首先分配到 200px,然后把剩余的可用空间按比例进行分配。

flex其实是三个属性的缩写

  1. 第一个是 flex-grow, 值是没有单位的比例,表示子项所占的权重
  2. 第二个是 flex-shrink,值是没有单位的比例。flex 元素仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink 的值
  3. 第三个是 flex-basis,值是有单位的数值,表示至少拥有的值

对齐与居中

关键属性:align-items, justify-content.

align-items 属性用于批量设置当前元素的所有直接元素的 align-self 属性。

align-self 属性表示当前元素在 cross 轴(即交叉轴/垂直轴)上的对齐方式。

align-itemsalign-self 支持的值有:

  • 默认的值是 stretch,表示沿着交叉轴的方向拉伸以填充父容器。如果父容器在交叉轴方向上没有固定宽度(即高度),则所有 flex 项将变得与最长的 flex 项一样长(即高度保持一致)
  • center,元素高度不变,在交叉轴居中
  • start,使所有元素位于交叉轴 start 端
  • end,使所有元素位于交叉轴 end 端
  • flex-startflex-end,使** flex 元素**在交叉轴的开始或结束处对齐

我们也可以使用 align-self 单独指定某个元素的垂直对齐效果:

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

justify-content 属性用于控制 flex 元素在主轴(即水平轴)上的位置。

支持的值:

  • 默认值 flex-start,所有的 flex 项位于主轴的开始处,所有元素间不会有额外的空隙
  • flex-end,让 flex 元素位于主轴的结尾
  • center 让 flex 元素在主轴居中,元素间不会有额外的空隙
  • space-around,使所有 flex 元素沿着主轴均匀的分布,左右两端都会有空间
  • space-between,类似 space-around,但左右两端不会有额外空间

使用 flexbox 的整体居中布局:

.vertical-container {
  height: 300px;
  display: -webkit-flex;
  display:         flex;
  -webkit-align-items: center;
          align-items: center;
  -webkit-justify-content: center;
          justify-content: center;
}

改变元素的顺序

弹性盒子元素可以使用 order 属性值改变它的布局位置。

所有 flex 元素的默认 order 是 0,order 值越大,显示顺序越靠后。相同 order 的按在源码中的顺序显示。

如果想让某个元素放到最前面,可以给它设置低 order,负数都可以;想让某个元素放到后面,可以给它设置高的 order.

flex 嵌套

flex 可以进行嵌套以实现一些复杂的布局,比如这样:

想要让孩子具有弹性,就得设置父布局为 display:flex

比如上图中的布局,首先三个青色大块的父布局需要设置为 display:flex,然后给第三块也设置 display:flex,接着第三块的第一个 button 列表的父布局也得设置为 display:flex

浏览器兼容性

大多数浏览器都支持 弹性盒子,诸如 Firefox, Chrome, Opera, Microsoft Edge 和 IE 11,较新版本的 Android/iOS 等等。

如果您正在考虑在真实网站中使用弹性盒子,则需要进行测试,并确保在尽可能多的浏览器中您的用户体验仍然可以接受。

弹性盒子相较其他一些 CSS 特性可能更为棘手。 例如,如果浏览器缺少 CSS 阴影,则该网站可能仍然可用。 但是假如不支持 弹性盒子功能就会完全打破布局,使其不可用。

Search

    Table of Contents