动画展示 Flexbox 布局


原文链接: 动画展示 Flexbox 布局

玩游戏玩转FlexBox布局

Flexbox 布局将我们从CSS的邪恶(如垂直对齐)中拯救了出来。

很好,Flexbox 确实实现了这个目标。
但掌握新的弹性模型可能还是具有一点挑战性的。

所以,让我们以动图的形式来看看 Flexbox
的工作原理,这样我们可以使用它来构建更好的布局。

Flexbox 的基本原理是让布局变得灵活和直观。

为了实现这个目标,它让容器自己决定如何均匀分配它的子元素 --
包括子元素的大小和相互之间的间隔。

这听起来是很不错的原则。 但让我们看看它在实践中又会是什么样子的呢。

Flexbox 的布局

在本文中,我们将探讨 5 个最常见的 Flexbox
属性。我们将探索他们究竟做什么,如何使用它们,以及它们会产生什么实际效果。

注:对于基本的感念建议你先阅读 CSS3 Flexbox属性可视化指南

属性 1: display:flex

这是我们的示例页面,如图:

display:flex
示例

你有 1 个灰色的 div 容器,包含了 4 个不同大小和颜色的 div 子元素。
到目前为止,每个 div子元素都是默认的 display: block
因此,每个矩形子元素(flex项)都占据了一整行的宽度。

为了开始使用 Flexbox ,你需要将你的容器(container)变成一个 flex 容器。
这很简单:

#container {
  display: flex;
}

display:flex
示例

注:首先请搞懂几个概念:
flex container(flex 容器)是父元素,也就是上图中灰色的容器元素;flex
item(flex项)是flex
容器的直接子元素,也就是上图中彩色的矩形元素。原文中用了矩形元素表述,本文用
矩形子元素(flex项) 或者 flex item(flex项) 来表述。

不用很多的改变 -- 你的 div 子元素现在已经显示为内联形式了。
但在对于布局来说,已经发生了很大的变化。
你其实给你的每个矩形子元素(flex项)添加了 flex context (上下文)

现在,您可以开始在这个上下文中 定位 它们,这样与传统 CSS
相比会简单很多。

属性 2: Flex Direction(排列方向)

Flexbox 容器有两根轴线:主轴(main axis)和与之垂直的交叉轴(cross
axis),默认情况如下图所示:

Flexbox 容器 的主轴(main axis)和 交叉轴(cross
axis)

默认情况下,flex item(flex项)沿着主轴从左到右排列。这就是为什么 flex
容器应用了 display: flex
属性后,你的矩形子元素(flex项)就会默认排列在一条水平线上的原因。

然而,Flex-direction属性可以改变主轴方向。

#container {
  display: flex;
  flex-direction: column;
}

Flexbox 容器
的主轴方向

这里有一个重要的区别:flex-direction: column
并不是把矩形子元素(flex项)从主轴移到交叉轴上对齐,而是让主轴自身从水平变成垂直。

对于flex-direction,还有一些其他选项值:row-reverse
column-reverse。效果看图就明白了:

Flexbox 容器
的主轴方向

属性 3: Justify Content(flex 项在主轴上的对齐)

justify-content控制 flex item(flex项) 在主轴上的对齐方式。

在这里,你将深入了解一下主轴和交叉轴的区别。 首先,让我们回到
flex-direction: row

#container {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
}

justify-content 属性有 5 个值可供你使用:

  1. flex-start
  2. flex-end
  3. center
  4. space-between
  5. space-around

每个属性值的显示效果请看图片:

Justify
Content(对齐方式)

space-aroundspace-between
这两个值的区别不能很直观的理解。space-between
是两端对齐,使每个矩形子元素(flex项)之间的间隔是相等的,但两端的矩形子元素(flex项)不会和容器之间产生间隔。

space-around
则会在每个矩形子元素(flex项)的两边产生一个相同大小的间隔,也就是说两端的矩形子元素(flex项)和容器之间的间隔大小正好是两个矩形子元素(flex项)之间间隔大小的一半(每个矩形子元素产生的间隔不会重叠,所以间隔变成两倍)。

最后一点:请记住,justify-content 决定 flex
item(flex项)沿主轴的对齐方式,flex-direction 决定了主轴的方向。
当看到下一个属性的时候就会发现这两点很重要...

属性 4: Align Items (flex 项在交叉轴上的对齐)

如果你掌握了 justify-content属性,那么掌握 align-items
属性也就变得轻而易举了。

前面讲到 justify-content 定义了 flex item(flex项) 在主轴(main
axis)上的对齐方式,而 align-items 属性则定义了 flex item(flex项)
在交叉轴(cross axis)上的对齐方式。

Flexbox 容器 的主轴(main axis)和 交叉轴(cross
axis)

让我们将 flex-direction 属性重置为 row,我们看到的 主轴(main axis)
和 交叉轴(cross axis) 与上图是一致。

然后,让我们深入的了解下 align-items 属性的值:

  1. flex-start
  2. flex-end
  3. center
  4. stretch
  5. baseline

前三个值与 justify-content
属性中的值是完全一样的,所以这里就不再解释了。

但是,接下来的两个值却有点不一样。

stretch值会使每个 flex item(flex项) 的高度占据整个 交叉轴(cross
axis),而 baseline 使每个 flex item(flex项)
按照他们段落标签的文本基线(baseline)对齐。

flex
项在交叉轴上的对齐

(注意 对于 align-items: stretch
来说,必须将每一个矩形子元素(flex项)的高度设置为 auto,否则 height
属性将会覆盖该 stretch

对于 align-items: baseline
来说,要注意如果去掉段落标签或者没内容,矩形子元素(flex项)就会按照每个矩形的底部对齐,如下图所示:

align-items:
baseline没内容的情况

注:
科普:文本基线(英语:Baseline)指的是多数字母排列的基准线。详细说明请查看[维基百科中关于Baseline的说明]
原文中关于 `align-items: baseline`
的文字和图片表述不是非常清晰,看看下图或许更容易理解:{.alignnone
.size-full .wp-image-6480 width="1255" height="300"}

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

主轴和交叉轴的区别

flex-direction 取值为 row
时,每个矩形子元素(flex项)会沿着水平的主轴排列,而取值为 column
时,它们就会沿着垂直主轴的向下排列。

虽然这些矩形子元素 (flex 项)
在两种情况下都可以水平或者垂直居中,但对于这些矩形子元素来说,一个是水平排列,一个垂直排列。

属性 5: Align Self (flex 项的自身对齐)

align-self 允许你单独设置每个 flex item(flex项) 的对齐方式。

它会覆盖 flex container(flex 容器) 的 align-items
属性。默认情况下,所有 flex item(flex项) 的 align-self 属性均为
auto,他们继承了 flex 容器的 align-items 属性。

#container {
  align-items: flex-start;
}
.square#one {
  align-self: center;
}
// 只有这个矩形元素会居中。

下面你将设置两个矩形子元素(flex项) 的 align-self 属性,其余的应用
align-items: centerflex-direction: row,让我们看看会发生什么:

flex项的align-self属性

Flexbox 的缩放

用大彩图和GIF动画解释Flexbox布局是如何工作我们入门了几个基本的
Flexbox
属性:flex-directionjustify-contentalign-itemsalign-self

这些属性对于创建基本布局非常有用。
但是一旦你开始使用Flexbox构建网页的时候,你需要更深入学习Flexbox
属性,以发挥它的潜力。

现在让我们深入了解 Flexbox 的缩放 --
以及如何利用它来构建漂亮的自适应布局。

属性 1: Flex-Basis

在上一篇文章中,我们主要了解了适用于容器元素的属性。这一次,我们专门介绍如何控制子元素(flex项)的大小。[]{#more-7236}

我想,我们这次介绍的第一个属性是 Flexbox 教程中最不好解释的属性之一。

但 -- 不要担心。 它实际上很简单。

flex-basis 控制一个子元素(flex项)的默认大小,但是它可以被其他的
Flexbox 属性影响(稍后详细介绍)。

在下面的 GIF 中,你会发现它可以与 width 属性互换(等价):

然而,flex-basis 和 width 有什么不同呢?flex-basis 对应于 flex
轴线而言的:

flex-basis 影响元素在主轴(main axis)上的大小。

让我们看看当保持 flex-basis 不变的情况下,改变主轴方向,会发生什么。

注意,我们必须从手动将 height 切换到设置 width 属性。
因此,flex-basis 是根据 flex-direction 的不同来确定 width
height 的。

属性 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

属性 3: Flex Shrink(收缩)

flex-shrink 正好和 flex-grow
相反,它是决定矩形子元素允许收缩多少的。

它的主要用途是指定哪些 flex项 要缩小,哪些 flex项
不要缩小。默认情况下,每个矩形子元素(flex项)都为 1 --
这意味着每个矩形子元素将随着容器收缩而收缩。

让我们看看实际情况。 在下面的 GIF 中,每个矩形子元素(flex项)的
flex-grow1,所以他们填充满了整个容器,并且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: Flex

flexflex-growflex-shrinkflex-basis 的缩写 --
所有这些都放在一起。

它的默认值是0(grow),1(shrink)和 auto(basis)。

我们把上一个例子简化成只有两个矩形子元素(flex项)。

下面是它们的属性:

.square#one {
  flex: 2 1 300px;
}
.square#two {
  flex: 1 2 300px;
}

两个矩形子元素(flex项)具有着相同的
flex-basis。这意味着如果它们有足够的空间(容器的空间是 600px 加上
marginpadding ),它们的宽度都是 300px 。

但随着容器的拉伸,第 1 个矩形子元素(flex项)(具有更高的 flex-grow
)将以两倍于第 2 个矩形子元素的速度增长。 随着容器的收缩,第 2
个矩形子元素(具有更高的柔性收缩)将会以两倍于第 1
个矩形子元素的的速度收缩。

实际效果如下图:

flex项如何收缩和拉伸

这里有什么可能会混淆:当第 1 个矩形子元素拉伸时,并没有拉伸到第 2
个矩形子元素的两倍大小。同样,当第 2 个矩形子元素缩小时,它不缩小到第 1
个矩形子元素的一半大小 -- 即使flex-shrink(理解为收缩比率)为21

这两个属性并不是说它们的大小比例是 2:1 或者
1:2,而是说它们的收缩或拉伸速度的比率。

简单的数学计算

容器的初始大小为 640px 。在容器的每一边占用 20px 的 padding
,剩下的空间足够让两个矩形子元素满足 flex-basis 等于 300px。

当容器设置为 430px 时,空间收缩了 210px 。(注:两个矩形子元素的
flex-shrink 加起来为 3 ,那么, ) 第 1 个矩形子元素的 flex-shrink
1, 也就是收缩了 70px 。 第 2 个矩形子元素的 flex-shrink1
也就是收缩了 140px 。

当容器收缩到 340px 时,空间收缩了 300px。第 1
个矩形子元素的收缩了100px,第 2 个矩形子元素的收缩了 200px 。

容器收缩的空间根据它们各自的 flex-shrink 收缩率(2:1)的比率来分割。

这对于 flex-grow 也是同样的。 当容器拉伸到 940px 时,也就是说空间拉伸
300px ,第 1 个矩形子元素被拉伸 200px ,,第 2 个矩形子元素被拉伸 100px

当涉及到 flex 属性时,其实它们说的都是比例。

在上面的GIF中,您可以看到宽度是如何根据比率进行调整的,增量(Δ)显示与
flex-basis 相比的差异。

结论

作为最后的总结:flex-basis
是控制元素在发生缩放之前,沿着主轴方向的大小。flex-grow
指的是在元素拉伸时,和兄弟元素之间相比的拉伸比例。而 flex-shrink
指的是在元素收缩时,和兄弟元素之间相比的收缩比例。

我们还有更多的 Flexbox 属性要介绍 -- 在接下来的几周里请密切关注。

非常感谢阅读! 如果你有一些特定的概念( Flexbox
或其他),你想看到在类似的文章中解释,请留言。

更多关于 Flexbox 的优秀文章:

更多关于 CSS Grid 布局的优秀文章

原文地址:https://medium.freecodecamp.com/even-more-about-how-flexbox-works-explained-in-big-colorful-animated-gifs-a5a74812b053#.9hknw1qpd

原文地址:https://medium.freecodecamp.com/an-animated-guide-to-flexbox-d280cf6afc35#.pr7928unu

`