乐趣区

弹性布局(display:flex;)

一、Flex 布局 - 前言
Flex 是 Flexible Box 的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性, 旨在提供一个更有效地布局、对齐方式,并且能够使容器中的子元素大小未知或动态变化情况下仍然能够分配好子元素之间的空间。
Flex 布局的主要思想是使父容器能够调节子元素的宽度 / 高度(和排列顺序),从而能够最好地填充可用空间(主要是为了适应所有类型的显示设备和屏幕尺寸)。flex 布容器能够放大子元素使之尽可能填充可用空间,也可以收缩子元素使之不溢出。
最重要的是,flexbox 布局与方向无关,不同于常规布局(基于垂直的块(block)和基于水平的内联(inline))。虽然传统布局适用于页面,但它们对于大型或复杂的应用程序布局来说缺乏灵活性(特别是在改变方向,调整大小,拉伸,收缩等方面)。
注:

Flexbox 布局最适合应用程序的组件和小规模布局,而 Gird 布局则适用于较大规模的布局。
设为 Flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效。

二、基本概念
采用 Flex 布局的元素,称为 Flex 容器(flex container),简称 ” 容器 ”。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称 ” 项目 ”。

三、容器的属性

display:flex;

flex-direction

justify-content

space-around 和 space-between 这两个值的区别不能很直观的理解。space-between 是两端对齐,使每个矩形子元素 (flex 项) 之间的间隔是相等的,但两端的矩形子元素 (flex 项) 不会和容器之间产生间隔。
space-around 则会在每个矩形子元素 (flex 项) 的两边产生一个相同大小的间隔,也就是说两端的矩形子元素 (flex 项) 和容器之间的间隔大小正好是两个矩形子元素 (flex 项) 之间间隔大小的一半(每个矩形子元素产生的间隔不会重叠,所以间隔变成两倍)。
align-items

(注意 对于 align-items: stretch 来说,必须将每一个矩形子元素 (flex 项) 的高度设置为 auto,否则 height 属性将会覆盖该 stretch)
对于 align-items: baseline 来说,要注意如果去掉段落标签或者没内容,矩形子元素 (flex 项) 就会按照每个矩形的底部对齐,如下图所示:

为了更好地演示主轴和交叉轴的区别,让我们结合 justify-content 和 align-items,看看在 flex-direction 两个不同属性值的作用下,轴心有什么不同:

四、项目的属性
以下 6 个属性设置在项目上

order
flex-grow
flex-shrink
flex-basis
flex
align-self

4.1 order
order 属性定义项目的排列顺序。数值越小,排列越靠前,默认为 0。
.item {
order: <integer>;
}

4.2 flex-grow(拉伸)
首先,让我们将所有的矩形子元素 (flex 项) 设置为相同的 width,120px:

现在,涉及到名为 flex-grow 的属性,其默认值为 0。这意味着矩形子元素 (flex 项) 不允许自动占据容器中剩余的空间。
这意味着什么呢?好吧,让我们尝试把为每个矩形子元素 (flex 项) 的 flex-grow 设置为 1:
所有矩形子元素 (flex 项) 共同占据了整个容器的宽度,它们之间的间隔也都是均匀分布。flex-grow 值覆盖了 width 值。
然而,关于 flex-grow 令人困惑的是其值实际上意味着什么呢?flex-grow: 1 是什么意思呢?
嗯,如果设置每个矩形子元素 (flex 项) 的 flex-grow 属性值为 999,让我们来看一下效果:
正如你所看到的,完全一样。
这是因为 flex-grow 不是绝对值 – 它是一个相对值。
对于每个矩形子元素(flex 项) 来说,重要的不是其 flex-grow 值有多大,而是这个值与其他矩形子元素(flex 项) 的 flex-grow 值相比较,相对值有多大。
如果我们将每个矩形子元素(flex 项) 设置为 flex-grow: 1,然后调整第 3 个矩形子元素的 flex-grow 值,那么我们可以看到改变,如图:

要真正理解这里到底发生了什么,让我们快速过一边简单的数学知识。
每个矩形子元素 (flex 项) 的 flex-grow 初始值都是 1。如果我们将每个矩形子元素 (flex 项) 的 flex-grow 相加起来,总和为 6。因此容器的总宽度被平均分成了 6 份。每个矩形子元素 (flex 项) 增长到填充容器可用空间的 1 /6。
当我们将第 3 个矩形子元素的 flex-grow 设置为 2 时,容器现在被分成了 7 等份,因为所有 flex-grow 属性是:1 + 1 + 2 + 1 + 1 + 1。
第 3 个矩形子元素占了整个容器空间的 2/7,其他的占了 1/7。
同理,当设置第 3 个矩形子元素的 flex-grow: 3 的时候,整个容器宽度被分成了 8 等份(1 + 1 + 3 + 1 + 1 + 1),第 3 个矩形子元素占了 3/8,其他的占了 1/8。
以此类推。
flex-grow 只和比例相关,如果我们设置第 3 个矩形子元素 flex-grow: 12,其余每个方块的 flex-grow: 4;跟第三个设置成 3,其他的设置成 1 得到同样的效果,见下图:

重要的是每个矩形子元素的 flex-grow 与其他矩形子元素成比例的。
最后一点,请记住,就像 flex-basis 一样,flex-grow 只适用于主轴(main axis)。我们的矩形子元素只会影响宽度,除非我们将 flex-direction 设置为 column。
4.3 flex-shrink(收缩)
flex-shrink 正好和 flex-grow 相反,它是决定矩形子元素允许收缩多少的。
它的主要用途是指定哪些 flex 项 要缩小,哪些 flex 项 不要缩小。默认情况下,每个矩形子元素 (flex 项) 都为 1 – 这意味着每个矩形子元素将随着容器收缩而收缩。
让我们看看实际情况。在下面的 GIF 中,每个矩形子元素 (flex 项) 的 flex-grow 为 1,所以他们填充满了整个容器,并且 flex-shrink 为 1,所以他们被允许收缩。

现在让我们将第 3 个矩形子元素的 flex-shrink 设置为 0。它是禁止收缩,所以它会随着容器拉伸而拉伸,但是当容器收缩的时候,当其宽度收缩至设置的 120px 时,它不再允许收缩。
flex-shrink 的默认值是 1 – 这意味着你的元素默认允许收缩,除非你告诉他们不允许收缩!
同样,flex-shrink 约为比例。如果一个矩形子元素的 flex-shrink 为 6,并且其余 flex-shrink 为 2,那么这个矩形子元素随着容器空间的收缩,将以 3 倍于其他矩形子元素的速度缩小。
注意这里的措辞:3x(3 倍)flex-shrink 的矩形子元素将缩小 3 倍。这并不是收缩 1 / 3 的宽度。
稍后,我们将深入了解元素是如何收缩和拉伸的。但首先,让我们了解最后一个属性,把这些东西都串起来。
4.4 flex-basis
flex-basis 属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为 auto,即项目的本来大小。
4.5 flex
flex 是 flex-grow,flex-shrink 和 flex-basis 的缩写 – 所有这些都放在一起。
它的默认值是 0(grow),1(shrink)和 auto(basis)。
4.5 align-self
align-self 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖 align-items 属性。默认值为 auto,表示继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

退出移动版