动画展示 Flexbox 布局
Flexbox Cheatsheet Cheatsheet
玩游戏玩转FlexBox布局
Flexbox 布局将我们从CSS的邪恶(如垂直对齐)中拯救了出来。
很好,Flexbox 确实实现了这个目标。
但掌握新的弹性模型可能还是具有一点挑战性的。
所以,让我们以动图的形式来看看 Flexbox
的工作原理,这样我们可以使用它来构建更好的布局。
Flexbox 的基本原理是让布局变得灵活和直观。
为了实现这个目标,它让容器自己决定如何均匀分配它的子元素 --
包括子元素的大小和相互之间的间隔。
这听起来是很不错的原则。 但让我们看看它在实践中又会是什么样子的呢。
Flexbox 的布局
在本文中,我们将探讨 5 个最常见的 Flexbox
属性。我们将探索他们究竟做什么,如何使用它们,以及它们会产生什么实际效果。
注:对于基本的感念建议你先阅读 CSS3 Flexbox属性可视化指南
属性 1: display:flex
这是我们的示例页面,如图:
你有 1 个灰色的 div
容器,包含了 4 个不同大小和颜色的 div
子元素。
到目前为止,每个 div
子元素都是默认的 display: block
。
因此,每个矩形子元素(flex项)都占据了一整行的宽度。
为了开始使用 Flexbox ,你需要将你的容器(container)变成一个 flex 容器。
这很简单:
#container {
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),默认情况如下图所示:
默认情况下,flex item(flex项)沿着主轴从左到右排列。这就是为什么 flex
容器应用了 display: flex
属性后,你的矩形子元素(flex项)就会默认排列在一条水平线上的原因。
然而,Flex-direction
属性可以改变主轴方向。
#container {
display: flex;
flex-direction: column;
}
这里有一个重要的区别:flex-direction: column
并不是把矩形子元素(flex项)从主轴移到交叉轴上对齐,而是让主轴自身从水平变成垂直。
对于flex-direction,还有一些其他选项值:row-reverse
和column-reverse
。效果看图就明白了:
属性 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 个值可供你使用:
- flex-start
- flex-end
- center
- space-between
- space-around
每个属性值的显示效果请看图片:
space-around
和 space-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)上的对齐方式。
让我们将 flex-direction
属性重置为 row
,我们看到的 主轴(main axis)
和 交叉轴(cross axis) 与上图是一致。
然后,让我们深入的了解下 align-items
属性的值:
- flex-start
- flex-end
- center
- stretch
- baseline
前三个值与 justify-content
属性中的值是完全一样的,所以这里就不再解释了。
但是,接下来的两个值却有点不一样。
stretch
值会使每个 flex item(flex项) 的高度占据整个 交叉轴(cross
axis),而 baseline
使每个 flex item(flex项)
按照他们段落标签的文本基线(baseline)对齐。
(注意 对于 align-items: stretch
来说,必须将每一个矩形子元素(flex项)的高度设置为 auto
,否则 height
属性将会覆盖该 stretch
)
对于 align-items: baseline
来说,要注意如果去掉段落标签或者没内容,矩形子元素(flex项)就会按照每个矩形的底部对齐,如下图所示:
注:
科普:文本基线(英语:Baseline)指的是多数字母排列的基准线。详细说明请查看[维基百科中关于Baseline的说明]
原文中关于 `align-items: baseline`
的文字和图片表述不是非常清晰,看看下图或许更容易理解:{.alignnone
.size-full .wp-image-6480 width="1255" height="300"}
为了更好地演示主轴和交叉轴的区别,让我们结合justify-content
和align-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: center
和 flex-direction: row
,让我们看看会发生什么:
Flexbox 的缩放
用大彩图和GIF动画解释Flexbox布局是如何工作我们入门了几个基本的
Flexbox
属性:flex-direction
,justify-content
,align-items
和align-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-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: Flex
flex
是 flex-grow
,flex-shrink
和 flex-basis
的缩写 --
所有这些都放在一起。
它的默认值是0
(grow),1
(shrink)和 auto
(basis)。
我们把上一个例子简化成只有两个矩形子元素(flex项)。
下面是它们的属性:
.square#one {
flex: 2 1 300px;
}
.square#two {
flex: 1 2 300px;
}
两个矩形子元素(flex项)具有着相同的flex-basis
。这意味着如果它们有足够的空间(容器的空间是 600px 加上margin
和 padding
),它们的宽度都是 300px 。
但随着容器的拉伸,第 1 个矩形子元素(flex项)(具有更高的 flex-grow
)将以两倍于第 2 个矩形子元素的速度增长。 随着容器的收缩,第 2
个矩形子元素(具有更高的柔性收缩)将会以两倍于第 1
个矩形子元素的的速度收缩。
实际效果如下图:
flex项如何收缩和拉伸
这里有什么可能会混淆:当第 1 个矩形子元素拉伸时,并没有拉伸到第 2
个矩形子元素的两倍大小。同样,当第 2 个矩形子元素缩小时,它不缩小到第 1
个矩形子元素的一半大小 -- 即使flex-shrink
(理解为收缩比率)为2
比1
。
这两个属性并不是说它们的大小比例是 2:1
或者1:2
,而是说它们的收缩或拉伸速度的比率。
简单的数学计算
容器的初始大小为 640px 。在容器的每一边占用 20px 的 padding
,剩下的空间足够让两个矩形子元素满足 flex-basis
等于 300px。
当容器设置为 430px 时,空间收缩了 210px 。(注:两个矩形子元素的flex-shrink
加起来为 3
,那么, ) 第 1 个矩形子元素的 flex-shrink
为 1
, 也就是收缩了 70px 。 第 2 个矩形子元素的 flex-shrink
为 1
也就是收缩了 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/an-animated-guide-to-flexbox-d280cf6afc35#.pr7928unu