本篇博客参考w3c权威技术报告编写:https://www.w3.org/TR/2018/CR-css-flexbox-1-20181119
注:由于一些专业名称使用英语来表示更明确,所以文章会出现较多的英语名称。
1. 摘要
css2.1定义了block layout
,inline layout
,table layout
,positioned layout
4种布局来计算boxes
的尺寸和位置。flex
是一种新的布局模式,用来实现更复杂的布局,flex布局可以布局在任意方向上,也可以缩放它的尺寸以避免溢出父元素。
flex布局和block布局很类似,但是它没有block布局的一些更复杂的以文本或文档为中心的属性,例如floats
和columns
,相反它拥有更加强大的分配空间和排列内容的能力。
这里给出一个简单的例子:
实现一个目录,目录的每一项有一个标题,照片,描述和支付按钮,设计者的意图是每个条目具有相同的整体尺寸,照片在文本上方,并且支付按钮在底部对齐而不管项目描述的长度。Flex布局使这种设计的许多方面变得容易:
- 目录使用flex布局来让项目按行排列并且确保它们是等高的,每一项又是一个按列排列的flex容器。
- 在每一项中,在源代码中按标题,描述,照片依次排列,这为文档阅读器和不支持css的浏览器提供了友好的顺序,但在视觉上使用
order
来把照片拉到首位,并使用align-self
来让它水平居中。 - 使用
'auto' margin
强制支付按钮放置在底部而不管描述的长度,(auto margin
的作用将在后面的章节解释。)
#deals {
display: flex; /* Flex layout so items have equal height */
flex-flow: row wrap; /* Allow items to wrap into multiple lines */
}
.sale-item {
display: flex; /* Lay out each item using flex layout */
flex-flow: column; /* Lay out item’s contents vertically */
}
.sale-item > img {
order: -1; /* Shift image before other content (in visual order) */
align-self: center; /* Center the image cross-wise (horizontally) */
}
.sale-item > button {
margin-top: auto; /* Auto top margin pushes button to bottom */
}
<section id="deals">
<section class="sale-item">
<h1>Computer Starter Kit</h1>
<p>This is the best computer money can buy, if you don’t have much money.</p>
<ul>
<li>Computer</li>
<li>Monitor</li>
<li>Keyboard</li>
<li>Mouse</li>
</ul>
<img src="images/computer.jpg"
alt="You get: a white computer with matching peripherals.">
<button>BUY NOW</button>
</section>
<section class="sale-item">
…
</section>
…
</section>
2. Flex布局盒模型和术语
一个flex container
就是一个元素把display
设置为flex
或inline-flex
后产生的盒子,flex容器中的孩子称为flex items
,并且使用flex的模式布局。
为了让flex
更加容易理解,这节定义了一些flex流的相关术语。flex-flow
的值和writing mode
决定了这些items
如何布局。
main axis
main dimension
flex容器的main axis
就是它的主轴,flex items沿着此轴排列,它在main dimension
中扩展。
main-start
main-end
flex item
在flex容器中的从main-start边朝着main-end边排列。
main size
main size property
在main dimension
中,一个flex container
或flex item
的width或者height就是那个盒子的main size
,因此它的main size property
就是it的width
orheight
属性。min-width/min-height
,max-width/max-height
同理。
cross axis
cross dimension
垂直于主轴(main axis)的轴,称为交叉轴(cross axis),它在cross dimension
上扩展。
cross-start
cross-end
充满items的flex line
从cross start
边开始向着cross end
边排列。
cross size
cross size property
在cross dimension
中,一个flex container
或flex item
的width或者height就是那个盒子的cross size
,因此它的cross size property
就是it的width
orheight
属性。min-width/min-height
,max-width/max-height
同理。
本文中额引用外的sizing术语被定义在 CSS Intrinsic and Extrinsic Sizing
3.Flex容器:display值flex
和inline-flex
Name: display
values: flex | inline-flex
flex
这个值引发一个元素生成一个flex container
盒子,在流布局中它是一个块级元素。
inline-flex
这个值引发一个元素生成一个flex container
盒子,在流布局中它是一个行内级元素。
一个flex container
为它的内容建立了一个flex格式化上下文,这和建立块级格式化上下文类似的,但是它们之间也有一些不同,一些适用于block container
的属性不一定适用于flex container
。overflow
属性适用于flex container
。
float
和clear
并不会为flex item
创建浮动或者清除浮动,并且也不会让它脱离布局流。vertical-align
对flex item
没有效果。::first-line
和::first-letter
伪元素不适用于flex container
,并且flex container
元素也不会成为它祖先的::first-line
和::first-letter
。
在某些情况下指定为inline-flex
的display值会被计算为flex
,请参考:CSS 2.1 Section 9.7
4. Flex Items
在布局流中,flex container
的每一个孩子成为一个flex item
,并且每一个连续的text
被包装为一个匿名的block container flex item
,然而如果一个text
只包含空格(例如被white-space
属性影响的字符串),那么它就不会被渲染(就好像它的display值是none)。
<div style="display:flex">
<!-- flex item: block child -->
<div id="item1">block</div>
<!-- flex item: floated element; floating is ignored -->
<div id="item2" style="float: left;">float</div>
<!-- flex item: anonymous block box around inline content -->
anonymous item 3
<!-- flex item: inline child -->
<span>
item 4
<!-- flex items do not split around blocks -->
<q style="display: block" id=not-an-item>item 4</q>
item 4
</span>
</div>
注意内部元素的空格消失了,匿名的
item box
是不能设置style的,因为没有元素去设置,它只能从flex container
继承styles。
一个flex item
为它的内容建立了一个独立的格式化上下文。然而flex items它本身是一个flex-level
盒子,而不是block-level
盒子:它们参与的是flex格式化上下文,而不是块级格式化上下文。
注意:在某些情况下flex item
的display值会被块级化,转换详情请参考:CSS2.1§9.7
和css display
注意:一些
display
值通常会在原始盒子周围创建匿名的盒子,但对于flex item
来说,它首先被块级化,所以不会创建匿名盒子,例如两个连续的flex items
的display值被设置为table-cell
将会创建两个分开的块级flex items
,而不是被包装为一个单独的匿名table。
对于display值被指定为table
的flex item,表格包装盒子成为一个flex item,order
和align-self
适用于它,任何标题框的内容都有助于计算表格盒子的最小和最大宽度。
然而对于width
和height
采用以下规则计算:flex items的最终尺寸是在执行布局的时候计算的,就好像表格盒子和表格内容的间隔是表格盒子的border+padding
区域一样。
4.1 绝对定位Flex Children
因为它脱离了文档流,所以绝对定位的child不参与flex布局。
flex container中的绝对定位元素的位置被计算就好像它是flex container中仅有的唯一元素一样,并且假设flex container和flex item都是固定大小的尺寸。所以为了此目的,auto
margin被视为0。换句话说,flex容器中的定位元素是相对于flex容器的content box
定位的。
这产生的影响是,如果你对flex container中的绝对定位的元素设置
align-self: center;
,自动offset将会让它在flex容器的cross axis
居中。然而因为一个绝对定位的flex item是固定尺寸的,stretch
属性被视为和flex start
相同。
4.2 Flex item Margins and Paddings
相邻flex items的margins不会合并。百分比的margins和paddings和block boxes
一样,相对于它们的containing block
计算。
auto
margins会扩展去吸收相应区域额外的空间,它们被用于对齐或者使相邻的flex items分离。详情参考:Aligning with auto margins
4.3 Flex Item Z-Ordering
flex items的渲染和inline block
类似,除了order
属性会改变源文档的顺序,不是auto
值的z-index
会创建一个堆叠上下文,甚至是position被设置static
的时候也一样(表现的好像是position是relative一样)。
注意:位于flex item外部的后代仍然参与flex item建立的的任何堆叠上下文
4.4 折叠items
在flex item上指定visibility:collapse
会引发它成为一个折叠flex item,产生一种类似在table-row
或table-column
上设置visibility:collapse
的效果:折叠的flex item完全从渲染中移除,但是留下一个桩来保持flex line
的cross size
的稳定。因此,如果一个flex容器只有一个flex line
,动态折叠或者不折叠items可能会改变flex容器的main size
,但是不会对它的cross size
产生影响,也不会导致页面其余部分“摇晃”,然而flex line
的换行是折叠之后重做的,所以具有多line的flex容器的cross size
可能会也可能不会改变。
尽管折叠flex item没有被渲染,但它确实出现在formatting structure,因此不像设置了display: none
的items。依赖于formatting structure的盒子的效果(例如递增计数器,运行动画或者过渡)仍然对折叠items产生作用。
在下面的例子中,侧边栏被设置为适应它内容的大小,
visibility: collapse
被使用来动态隐藏侧边栏的某些部分而不影响它的宽度,尽管最宽的item(“Architecture”)位于折叠部分中。动态效果
@media (min-width: 60em) {
/* two column layout only when enough room (relative to default text size) */
div { display: flex; }
#main {
flex: 1; /* Main takes up all remaining space */
order: 1; /* Place it after (to the right of) the navigation */
min-width: 12em; /* Optimize main content area sizing */
}
}
/* menu items use flex layout so that visibility:collapse will work */
nav > ul > li {
display: flex;
flex-flow: column;
}
/* dynamically collapse submenus when not targetted */
nav > ul > li:not(:target):not(:hover) > ul {
visibility: collapse;
}
<div>
<article id="main">
Interesting Stuff to Read
</article>
<nav>
<ul>
<li id="nav-about"><a href="#nav-about">About</a>
…
<li id="nav-projects"><a href="#nav-projects">Projects</a>
<ul>
<li><a href="…">Art</a>
<li><a href="…">Architecture</a>
<li><a href="…">Music</a>
</ul>
<li id="nav-interact"><a href="#nav-interact">Interact</a>
…
</ul>
</nav>
</div>
<footer>
…
为了计算桩的大小,flex布局第一次执行是在所有items未折叠的情况下,然后重新运行,每个折叠item都替换为桩,以便保持item所在原始line的原始cross size
的不变。更多有关visibility:collapse
的定义请参见Flex Layout Algorithm。
注意:在任何flex items上使用
visibility: collapse
将导致flex布局算法在中途重复,重新运行最昂贵的部分,如果items不是动态折叠的,建议作者继续使用display:none
隐藏item,因为这对布局引擎更有效。(然而,因为当可见性改变的时候只有部分需要重复运行,所以对于动态情况,仍建议使用visibility:collapse
)。
4.5 flex items的自动最小尺寸
注意:
auto
关键字代表一个automatic minimum size,它是min-width
和min-height
新的初始值,这个关键字以前定义在本节中,现在定义在 CSS Sizing。
为了为flex items提供一个更加合理的默认最小尺寸,对于一个不是滚动容器的主轴中的flex items的最小尺寸的值就是它的基于内容的最小尺寸,对于滚动容器,自动最小尺寸通常是0。
通常来说,flex items的基于内容的最小尺寸是content size suggestion
和specified size suggestion
中的较小值。然而,如果一个盒子具有宽高比但是没有specified size,它的基于内容的最小尺寸就是content size suggestion
和transferred size suggestion
中的较小值。如果盒子既没有specified size suggestion
也没有宽高比,它的基于内容的最小尺寸就是content size suggestion
。
specified size suggestion
如果item的计算main size property
是有定义的,specified size suggestion
就是该大小(如果它是被定义的,则由其最大main size property
限制),否则是undefined。
transferred size suggestion
如果item具有固有的宽高比并且它的计算的cross size property
是有定义的,transferred size suggestion
就是那个大小(如果它们是有定义的,则由其最小和最大cross size properties
限制),通过宽高比转化,否则是undefined。
content size suggestion
content size suggestion
就是主轴上的最小内容大小,如果它具有宽高比,通过任何定义的min and max cross peoperties
转化宽高比,那么它是受限制的,然后进一步受限制如果它定义了max main size property
.
为了计算盒子的固有大小(例如盒子的最小内容大小),基于内容的最小大小使得该轴中盒子的大小变得不确定(即使例如其宽度属性指定了确定的大小),请注意这意味着根据此大小计算的百分比将表现为auto
。
尽管如此,虽然在某些情况下这可能需要额外的布局传递来重新解决百分比,这个值(例如min-content
,max-content
,fit-content
,定义在 [CSS-SIZING-3])并不能阻止item中百分比大小的解决。
请注意,虽然基于内容的最小大小通常是合适的,并且有助于防止内容重叠或溢出其容器外,但在某些情况下,它不是:
特别是,如果将flex大小调整用于文档的主要内容区域,最好设置显式的字体相对最小宽度,例如min-width:12em。基于内容的最小宽度可能导致大表格或大图像将整个内容区域的大小拉伸到溢出区域,从而使得文本行无条件地长且难以阅读。
另请注意,当基于内容的大小调整用于具有大量内容的项目时,布局引擎必须遍历所有这些内容,然后才能找到其最小大小,而如果作者设置了明确的最小值,则这不是必需的。(但是,对于内容较少的项目,此遍历非常简单,因此不会影响性能。)
5. 顺序和方向
flex container的内容可以沿着任意方向和任意顺序布局,这个功能通过使用flex-direction
,flex-wrap
和order
属性实现。
5.1 Flex流方向:flex-direction属性
Name: flex-direction
value: row | row-reverse | column | column-reverse
Initial: row
Applies to: flex containers
flex-direction决定了flex items在主轴上沿着什么方向布局。
row
在当前writing mode中,在主轴的方向和inline axis
相似,main-start
和main-end
分别和inline-start
和inline-end
方向相同。
row-reverse
和row相似,除了main-start和main-end调转过来。
column
在当前writing mode中,主轴的方向和block axis
一致,main-start
和main-end
分别和block-start
和block-end
方向相同。
column-reverse
和column相似,除了main-start和main-end调转过来。
注意,reverse值并没有反转盒子的顺序:像
writing mode
和direction
一样,它们仅仅改变了流的方向。绘制顺序,语音顺序和顺序导航顺序不受影响。
5.2 Flex Line换行:flex-wrap属性
Name: flex-wrap
Value: nowrap | wrap | wrap-reverse
Inital: nowrap
Applies to: flex containers
flex wrap属性控制flex containers是单行的还是多行的,以及交叉轴的方向。
交叉轴的方向决定了新行被叠加的方向。
nowrap
flex containers是单行的。
wrap
flex containers是多行的。
wrap-reverse
和wrap一样,不过方向相反。
5.3 Flex方向和换行:flex-flow快捷方式
Name: flex-flow
Value:《flex-direction》 || 《flex-wrap》
Initial: row nowrap
Applies: flex containers
flex-flow是flex-directive和flex-wrap的简写形式,定义了flex container的主轴和交叉轴。
注意flex-flow是和写模式writing mode相关的。
5.4 展示顺序:order属性
flex item默认的展示顺序和源文档一样,order属性可以改变这种顺序。
Name: order
Value: 《Integer》
Initial: 0
Applies to: flex items
order接受一个整数值,从最低的值开始排列,值相同的按源文档的顺序排序,绝对布局的flex items被视为order: 0
。
order仅仅影响视觉上的顺序,而不会影响逻辑源代码的顺序和非视觉媒体或者不支持css的设备(例如speech)的顺序。
除非未来规范另有规定,否则此属性对不是flex item的框不起作用。
例子:
在网页布局常有这样一种布局,有一个头部一个顶部,中间有一个内容区域和两个侧边栏,通常我们希望先获取内容区域,然后才是侧边栏,以前这种布局有一定的难度,通常使用称为"Holy Grail Layout"的方式实现,现在flex的order属性让它变得容易:
<!DOCTYPE html>
<header>...</header>
<main>
<article>...</article>
<nav>...</nav>
<aside>...</aside>
</main>
<footer>...</footer>
main { display: flex; }
main > article { order: 2; min-width: 12em; flex:1; }
main > nav { order: 1; width: 200px; }
main > aside { order: 3; width: 200px; }
注意到侧边栏和内容区域默认是等高的,内容区域会按需填充屏幕的区域,另外这可以使用媒体查询来在窄屏幕上显示列布局:
@media all and (max-width: 600px) {
/* Too narrow to support three columns */
main { flex-flow: column; }
main > article, main > nav, main > aside {
/* Return them to document order */
order: 0; width: auto;
}
}
6. Flex Lines
flex items在flex容器中排列在flex lines
中,它是一个由布局算法组织和排列items所使用的假想容器。一个flex container可以是单行的或者多行的,这取决于flex-wrap
属性。
- single-line flex容器:(设置了
flex-wrap: nowrap
),所有的item布局在一个单行,即使会引起内容溢出。 - multi-line flex容器:(设置了
flex-wrap: wrap
或者flex-wrap: wrap-reverse
),分割它的flex items成为多line,类似text在单行中太长而被分割成新的line。当额外的line被创建,它们在容器的交叉轴上按照flex-wrap
属性的值堆叠,每一个line至少包含一个item,除非容器是空的。
这个例子展现了4个水平排列按钮,但是因为前3个按钮占了240px,第4个按钮放不下所以被包装成了多行。
#flex {
display: flex;
flex-flow: row wrap;
width: 300px;
}
.item {
width: 80px;
}
<div id="flex">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
一旦内容被分割为多行,每一行就是独立布局的,弹性长度和justify-content
,align-self
属性一次只考虑在一行中的items。
在一个多行的flex container中(甚至只有一行),每行的交叉轴尺寸就是能够包含下该行的items的最小尺寸(通过align-self
属性排列后),行在flex container中的排列使用align-content
属性设置。在单行的flex container中,行的交叉轴尺寸就是flex container的交叉轴尺寸,align-content
没有效果。每一行的主轴的尺寸总是和flex container内容盒子的主轴尺寸相同的。
这个例子和前一个一样,除了每个flex item被设置为flex: auto
。第一行的尺寸有60px的剩余空间,并且所有的item都是弹性布局,所以第一行的每一个item多接受20px的额外宽度,最终每一项100px,剩下的第4个按钮单独占据一行,并且扩展到整行的宽度。
7. 弹性
flex布局的定义方面是能够使flex items弹性,改变它们的宽度/高度去填充main dimension
剩余的空间,这可以通过flex
属性实现。flex container分配剩余空间给它的items(通过设置flex-grow
因子)来填充填充容器,或者收缩它们(通过设置flex-shrink
因子)来阻止溢出。
一个flex item是完全没有弹性的如果它的flex-grow
和flex-shrink
都是0,否则是弹性的。
7.1 flex
快捷方式
Name: flex
Value: none | [<《lex-grow》《flex-shrink》? || 《flex-basis》]
Initial: 0 1 auto
Applies to: flex items
flex
属性指定了组件的弹性长度:弹性因子(grow
,shrink
)和flex basis
。当一个盒子是flex item,使用flex
来计算盒子的main size
,而不是使用main size property
。如果盒子不是flex item,则flex
没有效果。
《flex-grow》
数字,指定了flex的增长因子,当有正的剩余空间的时候,增长因子决定了flex item相对于容器中其他的flex items的增长程度,缺省时设置为1。
0到1之间的Flex值有一些特殊的行为:当line上的flex值之和小于1时,它们将占用小于100%的可用空间。
《flex-shrink》
数字,指定了flex的收缩因子,当有负的剩余空间的时候,收缩因子决定了flex item相对于容器中其他的flex items的收缩程度,缺省时设置为1。
在分配负空间的时候,
flex shrink factor
会乘以flex base size
,这使得负空间与item能够收缩的程度成比例的分布,例如在较大的item明显减少之前,小的item不会缩小到零。
《flex-basis》
在按照弹性因子为item分配剩余空间之前,这个属性指定了flex item的初始化main size
。flex-basis接受和width
,height
一样的值(除了auto
被视为不同的),以及content
关键字。
-
auto
当在flex item使用该值时,auto
关键字将item的main size property
设为它的flex-basis。若那个值是也是auto
,就使用值就是content
。 -
content
表示基于flex item内容的自动尺寸。
注意:这个值没有定义在初始的flexible box layout中,因此一些老的浏览器不支持它,相同的效果可以使用
auto
和main size(width
,height
)设置为auto
来实现。
- 《width》
除此之外所有的其他值,“flex basis”都被视为和width和height一样,当缺省时,设定为0。
none
等同于0 0 auto
。
这个例子展示flex-basis设置为0和auto的情况,3个item弹性因子分别被设置为1,1,2。注意到弹性因子是2的增长速率是其他的两倍。
注意:在flex快捷方式中,
flex-grow
和flex-basis
的缺省值和flex
快捷方式的初始值是不同的,以便flex可以更加好的适应比较常见的情况。
7.1.1 常见的flex值
"flex: initial"
等效于flex: 0 1 auto
,基于它的width/height来设置它的尺寸(若item的main size property
被设置为auto
,它的尺寸将会基于它的内容),在正的剩余空间的时候flex item没有弹性,但是没有充足空间的时候会收缩到它的最小尺寸,alignment abilities
或者auto
margin在主轴上排列flex items。
"flex: auto"
等效于flex: 1 1 auto
,基于它的width/height来设置它的尺寸,并且使它完全弹性的,它会吸收任何多余的空间。
"flex: none"
等效于flex: 0 0 auto
, 基于它的width/height来设置它的尺寸,并且使它完全不可弹性的。甚至在溢出的情况也不会收缩。
"flex: 《positive-number》":
等效于flex: <positive-number> 1 0
,使flex item弹性的,并且设置flex basis为0。
默认情况下flex items并不会缩减到它的最小尺寸以下(最大的text长度或者固定尺寸的元素),改变这个可以通过设置min-width
或者min-height
属性。参考: §4.5 Automatic Minimum Size of Flex Items
7.2 弹性组成部分
弹性的组成部分可以通过独立的属性来控制,但是推荐使用flex
的快捷方式。
7.2.1 flex-grow属性
Name: flex-grow
Value:
Initial: 0
Applies to: flex items
flex-grow
属性设置弹性增长因子,通过提供一个整数值,负值是非法的。
7.2.2 flex-shrink属性
Name: flex-shrink
Value:
Initial: 1
Applies to: flex items
描述参考以上flex
7.2.3 flex-basis属性
Name: flex-basis
Value: content |
Initial: auto
Applies to: flex items
Percentages: 相对于flex container的内部main size
描述参考以上flex
8. 对齐
在flex container的内容完成它们的弹性,并且所有的flex item的尺寸最终确定后,它们就可以在flex容器中对齐了。
margin
可以用来对齐items,这和block layout
相似,但是更加强大。flex items也遵循CSS Box Alignment的对齐属性,这允许在主轴和交叉轴轻松进行基于关键字的对齐。这些属性使得css2.1中许多常见的比较难以实现的对齐变得微不足道,例如垂直和水平居中。
注意这里flex模块重新定义了CSS Box Alignment的属性,以便不会创建可能减慢规范进度的规范依赖。换句话说,一旦CSS Box Alignment Level 3定义完成,将取代这里的定义。
8.1 'auto' margin
对齐
flex item 和 block流的auto margin
非常类似:
- 在计算
flex bases
和弹性长度的时候,auto margin被视为0 - 优先于通过
justify-content
和align-self
设置的对齐属性,在那个区域的任何正的空间的都被分配给auto margin。 - 溢出的盒子会忽略它们的auto margin,并且在end方向溢出。
注意:如果剩余空间被分配给auto margin,则对齐属性就不会生效,因为margins会偷取所有分配之后剩余的空间。
下面这个例子实现流一个比较常见的导航条,一些项排列在左边,而其他的排列在右边。
nav > ul {
display: flex;
}
nav > ul > #login {
margin-left: auto;
}
<nav>
<ul>
<li><a href=/about>About</a>
<li><a href=/projects>Projects</a>
<li><a href=/interact>Interact</a>
<li id="login"><a href=/login>Login</a>
</ul>
</nav>
下面这幅图展示了auto margin和对齐属性在处理溢出情况下的不同。
左边的图使用margins居中,右边的图使用align-self
居中。如果这个列容器
是排列在页面左边界的时候,那么margin的行为是更为推荐的,因为长的项是完全可读的,但是在其他情况下对齐属性的行为可能会更好。
8.2 主轴对齐:justify-content
属性
Name: justify-content
Value: flex-start | flex-end | center | space-between | space-around
Initial: flex-start
Applies to: flex containers
justify-content
属性沿着主轴方向对齐当前行的flex item,这个过程在任何弹性长度或者auto margin完成后发生。通常,当一行上的所有flex items都是不可弹性的,或者是弹性的但是已经到达了最大尺寸时,它有助于分配剩余的额外空间,当flex items溢出行时,它也会对他们施加一些控制。
flex start
flex items被打包到一行的开始,每一行的第一个flex item的边界和main-start的边界齐平,之后的flex item和前面的flex item齐平。
flex end
flex items被打包到一行的末尾,每一行的最后一个flex item的边界和main-end的边界齐平,并且每一个之前的flex item和随后的flex item齐平。
center
flex items被打包到一行的中间,它们彼此齐平的排列在行的中间,第一个item到main-start的距离和最后一个item到main-end的距离相等,如果剩余空间是负的,
那么它们会在两个方向上会有相同的溢出。
space-between
flex items在行中均匀的分布,如果左边的剩余空间是负的或者仅有一个flex item,这个值就等同于flex-start
。否则,第一个item和最后一个item的边界分别与main-start和main-end边界齐平,剩余的flex items在行中均匀的分布,以便任意两个相邻item之间的距离是相等的。
space-around
flex items均匀分布在行中,两端各占一半的尺寸,如果左边的剩余空间是负或者仅有一个flex item,这个值就等同于center
。否则flex item均匀分布在行中,以便任意两个相邻item之间距离是相等的,第一个item和最后一个item到flex container的距离相等且等于item之间距离的一半。
8.3 交叉轴对齐:align-items和align-self属性
Name: align-items
Value: flex-start | flex-end | center | baseline | stretch
Initial: stretch
Applies to: flex containers
Name: align-self
Value: auto | flex-start | flex-end | center | baseline | stretch
Initial: auto
Applies to: flex items
flex items
可以在当前容器的当前行的交叉轴上对齐,类似于justify-content
但是在垂直方向,align-items
设置flex容器中所有项的默认对齐方式,包括匿名flex items
,align-self
为单个flex items
设置对齐方式,这会覆盖它的默认对齐方式,对于匿名的flex items,align-self
始终匹配它们相关联的flex容器的align-items
值。
如果任何flex-items的margin的值为auto。则align-self
无效。
auto
将交叉轴对齐设置为父容器的align-items
值(这是align-self
的初始值)。
flex-start
flex items的开始边界和cross-start
的边界对齐。
flex-end
flex items的开始边界和cross-end
的边界对齐。
center
flex items排列在交叉轴行的中间(如果交叉轴尺寸少于所有flex items和,则它会在两端均匀溢出)。
baseline
flex items参与基线对齐,所有参与的flex item在行内基线对齐,并且基线与它垂直方向的margin边距离最大的item的边界与cross-start
的边界齐平。如果项目在必要的轴中没有基线,则从flex items的边界盒子中合成一个。
stretch
如果flex item的cross size property
被计算为auto
,并且cross-axis
的margins不是auto,那么flex item被拉伸,其使用的值是使flex item边距框和line尽可能接近相同大小所需要的长度,同时仍然遵守min-height
/min-width
/max-height
/max-width
所施加的约束。
注意:如果flex容器的高度受到约束,stretch值可能导致flex item的内容溢出item。
8.4 打包Flex Lines:align-content属性
Name: align-content
Value: flex-start | flex-end | center | space-between | space-around | stretch
Initial: stretch
Applies to: multi-line flex containers
当cross-axis
有额外空间的时候,align-content
排列flex容器中的lines,类似justity-content
在主轴排列单独的item,注意这个属性对于单行的flex容器没有效果。单行flex容器的line会自动拉伸填充空间。
各字段意思参考8.2节,下面给出图例
8.5 Flex容器基线
为了使flex容器本身参与基线对齐(例如,当flex容器本身是外部flex容器的flex item时),它需要提交最能代表其内容的基线位置。为此,flex容器基线的位置被决定如下(使用order
重排后并将flex-direction
考虑在内):
first/last 主轴基线集
当flex容器的inline axis匹配它的main axis,它的基线被决定如下:
- 如果flex容器的最开始/最末尾的flex line中的任何flex items参与基线对齐,flex容器的first/last主轴基线集则从那些flex items的共享对齐基线生成。
- 否则,如果flex容器至少有一个flex item,则flex容器的first/last基线集是从最开始/最末尾的flex item的对齐基线生成。(如果该item没有与flex容器主轴平行的对齐基线,则首先从其边界边缘合成一个)。
- 否则,flex容器没有first/last主轴基线集,并且根据其对齐上下文规则在需要时合成一个。
first/last 交叉轴基线集
当flex容器的inline axis匹配它的cross axis,它的基线被决定如下:
- 如果flex容器至少有一个flex item,则flex容器的first/last基线集是从最开始/最末尾的flex item的对齐基线生成。(如果该item没有与flex容器交叉轴平行的对齐基线,则首先从其边界边缘合成一个)。
- 否则,flex容器没有first/last主轴基线集,并且根据其对齐上下文规则在需要时合成一个。
根据上述规则计算基线时,如果贡献基线的框具有允许滚动的overflow
值,则必须将该框视为处于其初始滚动位置以确定其基线。
当决定table cell
的基线时,flex容器提供基线就像line box和table-row做的一样。
更多关于基线的信息请参看CSS Writing Modes 3 §4.1 Introduction to Baselines 、 CSS Box Alignment 3 §9 Baseline Alignment Details
9. flex布局算法
Flex Layout Algorithm,有兴趣的朋友可以研究下。
注:如果读者发现文章中一些错误,欢迎希望指出!