《精通CSS第3版》(6)Flexbox
6.3 FlexBox
调试代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Navbar using flexbox, no width</title>
<style>
nav {
display: block;
}
.navbar ul {
display: -webkit-flex;
display: -ms-flexbox;
display: -webkit-box;
display: -moz-box;
display: flex;
font-family: 'Avenir Next', Avenir, Corbel, 'Franklin Gothic', 'Century Gothic', CenturyGothic, AppleGothic, sans-serif;
list-style: none;
padding: 0;
background-color: #486a8e;
}
.navbar li {
text-transform: uppercase;
text-align: center;
-moz-box-sizing: border-box;
box-sizing: border-box;
background-color: #12459e;
outline: 1px solid #fff;
}
.navbar li a {
display: block;
text-decoration: none;
line-height: 1.75em;
padding: 1em;
color: #fff;
}
</style>
</head>
<body>
<nav class="navbar">
<ul>
<li><a href="/home">Home</a></li>
<li><a href="/spaceships">Spaceships</a></li>
<li><a href="/planets">Planets</a></li>
<li><a href="/stars">Stars</a></li>
</ul>
</nav>
</body>
</html>
6.3.1 浏览器支持
IE10及更早版本的webKit浏览器,需要在标准代码补充前缀。
IE9及更早版本的IE不支持。
6.3.2 理解flex方向:主轴与辅轴
Flexbox允许您定义页面的一个区域,在这个区域中可以根据顺序、大小、分布和对齐方式控制一堆元素。 空格内的方框按两个方向之一排列:默认情况下水平(作为一行)或垂直(作为列)。 这个方向被称为主轴
。
里面的盒子也可以在垂直于主轴的方向上移动和调整大小:这被称为辅轴
。 通常,用flexbox创建布局最重要的测量是沿着主轴的尺寸:水平布局的宽度
和垂直布局的高度
。 我们把这个尺寸称为该产品的主尺寸
。
6.3.3 对齐与空间
对子项的排列有很多方式。沿主轴排列叫排布(justification),沿辐轴排列叫对齐(alignment)。
记住主轴方向叫排布。
用于排布属性是 justify-content
,默认值 flex-start
。
/* 对齐方式 */
justify-content: center; /* 居中排列 */
justify-content: start; /* 从行首开始排列 */
justify-content: end; /* 从行尾开始排列 */
justify-content: flex-start; /* 从行首起始位置开始排列 -- default */
justify-content: flex-end; /* 从行尾位置开始排列 */
justify-content: left; /* 一个挨一个在对齐容器得左边缘 */
justify-content: right; /* 元素以容器右边缘为基准,一个挨着一个对齐, */
/* 基线对齐 */
justify-content: baseline;
justify-content: first baseline;
justify-content: last baseline;
/* 分配弹性元素方式 */
justify-content: space-between; /* 均匀排列每个元素
首个元素放置于起点,末尾元素放置于终点 */
justify-content: space-around; /* 均匀排列每个元素
每个元素周围分配相同的空间 */
justify-content: space-evenly; /* 均匀排列每个元素
每个元素之间的间隔相等 */
justify-content: stretch; /* 均匀排列每个元素
'auto'-sized 的元素会被拉伸以适应容器的大小 */
/* 溢出对齐方式 */
justify-content: safe center;
justify-content: unsafe center;
/* 全局值 */
justify-content: inherit;
justify-content: initial;
justify-content: unset;
外边距为auto而且还有空间
对于flexbox子项指定值为 auto
的外边距,而且容器那一侧还有空间,那么外边距就会扩展占据可用空间。
1 辐轴对齐
增加flex容器或某一项高度,辐轴会发生变化。
.navbar ul {
min-height: 100px;
}
控制辐轴对齐的属性 algin-items
,默认值 stretch
(拉伸),其他还有 flex-start
、center
和 flex-end
。
最后还有 baseline
,子项文本基线与容器基线对齐。解决子项大小不一,而希望虽然位置不同,但本身对齐的问题。
2 对齐个别项
还可以在辐轴指定个别项的对齐方式
.navbar ul {
min-height: 100px;
align-items: flex-end;
}
.navbar li:first-child {
align-self: flex-start;
margin-right: auto;
}
align-self 属性定义flex子项单独在侧轴(纵轴)方向上的对齐方式。
注意:align-self 属性可重写灵活容器的 align-items 属性。
3 flexbox中的垂直对齐
-
只有1个元素
-
只要容器设置为 flex, 再将剧中的元素外边距设置为 auto。因为flexbox各项自动外边距会扩展“填充”相应的方向。
<div class="flex-container"> <div class="flex-item"> <h2>Not so lost in space</h2> <p>This item sits right in the middle of its container...<p> </div> </div> <style> html, body { height: 100%; } .flex-container { height: 100%; display: flex; } .flex-item { margin: auto; } </style>
-
-
有多个元素
-
排布和对齐都设置为 center。(单个也行,auto代码更少)
.author-meta { border: 1px solid #ccc; height: 160px; display: flex; align-items: center; justify-content: center; }
-
6.3.4 伸缩的尺寸
1 相关属性
可伸缩体现在3个属性:flex-basis
、flex-grow
和 flex-shrink
.
-
flex-basis
调节项目在主轴上的“首选”尺寸(width或height),然后根据可用空间进行修正。 它可以设置为长度(例如18em)、百分比(基于容器的主轴大小)或关键字auto(默认值)。auto
关键字听起来像是将宽度或高度设置为auto,但实际上并非如此。 相反,它意味着项目将从相应的属性(宽度或高度)中获得它的主要大小。 如果没有设置主大小,元素的大小将根据其内容,有点像浮动或内联块,您还可以将值设置为
content
,它也会根据项目的内容设置大小,但忽略任何带有宽度或高度的主轴大小设置(与auto不同)。 请注意,content关键字是对flexbox的一个更新的添加,在本文撰写时,对它的支持是参差不一的。 -
flex-grow
调节当通过 flex-basis 给每个元素指定其首选大小时,剩余空间会发生什么: 您向它提供一个数字,称为伸缩因子,它是额外空间的一部分。 我们马上会解释分数是如何工作的。 flex-grow的默认值是0
,这意味着项目的增长不会超过它们从flex- base获得的大小。 -
flex-shrink
的工作原理与flex-grow类似,但相反:如果没有足够的空间,元素如何收缩? 当flex-shrink开始发挥作用时,计算就有点复杂了——我们将在后面进一步讨论它。 默认值是1
,这意味着如果没有足够的空间,所有项将按比例缩小,与它们的首选大小相比。
简化一下步骤:
步骤:
(1)检查 flex-basis,确定假想的主尺寸。
(2)确定实际的主尺寸。如果在容器中放入假设的主要尺寸的物品后,容器中还有空间,它们就会增长。 这种增长是基于弹性增长因素 flex-grow。 同样地,如果空间太小,无法容纳它们,则可以根据弹性收缩因子 flex-shrink 来缩小项目。
例子:按比例占据整个空间而不考虑各自内容 flex-grow
<!DOCTYPE html>
<html>
<head>
<style>
body,html,ul{
padding:0;
}
.navbar {
width: 1000px;
height: 100px;
list-style: none;
border: 1px solid #c3c3c3;
display: flex;
}
.navbar li{
flex-basis: auto;
}
</style>
</head>
<body>
<ul class="navbar">
<li style="width:200px;background-color:coral;">Short</li>
<li style="width:400px;background-color:lightblue;">Looooooooooong</li>
</ul>
</body>
</html>
因为剩余空间可分配,考虑 flex-grow。默认为0,这里设置为1。
.navbar li{
flex-basis: auto;
flex-grow: 1; /*伸展,每项伸展1份*/
}
假设分别设置不同 flex-grow
.navbar li:first-child {
flex-grow: 3;
}
.navbar li:last-child {
flex-grow: 1;
}
2 纯粹按伸缩系数计算大小
记得上一节的检查步骤:
第一步(1)检查 flex-basis,确定假想的主尺寸:如果主尺寸为0,那在这一步就不会给项目分配空间。
这种情况容器内部的 **全部空间 **都留给第2步。
第二步这里使用: 如果空间太小,无法容纳它们,则可以根据弹性收缩因子 flex-shrink 来缩小项目。
.navbar li{
flex-basis: 0;
flex-grow: 1;
}
使用 flex简写:
.navbar li {
flex: 1 0 0%; /*flex-grow:1 flex-shrink:0 flex-basis:0%*/
}
如果项让第一个项目空间是其他2倍,就给第1项flex-grow设为2。
CSS 语法
flex: flex-grow flex-shrink flex-basis|auto|initial|inherit;
属性值
值 描述 flex-grow 一个数字,规定项目将相对于其他灵活的项目进行扩展的量。 flex-shrink 一个数字,规定项目将相对于其他灵活的项目进行收缩的量。 flex-basis 项目的长度。合法值:"auto"、"inherit" 或一个后跟 "%"、"px"、"em" 或任何其他长度单位的数字。 auto 与 1 1 auto 相同。 none 与 0 0 auto 相同。 initial 设置该属性为它的默认值,即为 0 1 auto。请参阅 initial。 inherit 从父元素继承该属性。请参阅 inherit。
3 收缩项目
当放置在容器内的项的总和超过可用空间时,我们可以根据flex-shrink
属性允许它们收缩。 机制比flexgrow更复杂。 收缩条目的更复杂规则背后的想法是,防止因为较大的条目导致总宽度超出范围而导致较小的条目收缩为零。 允许一个项目有更多的空间是相当简单的(就像我们在flex-grow中看到的那样),并且是按照可用空间的比例进行的。 当收缩发生时,它的做法略有不同。
回到我们假设的1000像素宽的导航条,让我们假设有两个子条目,每个子条目通过flex-basis都有首选的大小集。 它们一起使容器的宽度超出了300像素。
重点:
简单表述:首选尺寸大的项目比首选尺寸小的项目收缩得更多。
6.3.5 flexbox 布局
1 折行与方向
2 多行布局中可伸缩的大小
3 对齐所有行