flex布局
Learn From:
flex 布局背后的主要思想是让容器能够改变其项目的宽度/高度(和顺序)以最好地填充可用空间(主要是为了适应各种显示设备和屏幕尺寸)。弹性容器扩展项目以填充可用的可用空间或缩小它们以防止溢出。
Flexbox
布局最适合应用程序的组件和小规模布局,而 Grid
布局适用于更大规模的布局。
基本概念
由于 flex
是一个完整的模块而不是单个属性,它涉及到很多东西,包括它的整个属性集。
其中一些是要设置在容器上(父元素,称为“flex container
”),而其他是要设置在子级(称为“flex items
”)上。
如果常规布局基于块流方向和内联流方向,则弹性布局基于“弹性流方向”。请看下面中的这张图,解释了 flex 布局背后的主要思想:
main axis
: 弹性容器的主轴是弹性项目沿其布置的主轴。请注意,它不一定是水平的;它取决于flex-direction
属性。main-start | main-end
: 弹性项目从main-start
到main-end
放置在容器内。main size
: 弹性项目的宽度或高度,以主要尺寸中的为准。cross axis
: 垂直于主轴的轴称为交叉轴。它的方向取决于主轴方向。cross-start | cross-end
: 弹性线用项目填充并放入容器中,从cross-start
开始,到cross-end
结束。cross size
: 弹性项目的宽度或高度。
Properties for the Parent (flex container)
display
定义一个弹性容器,内联或块 取决于给定的值。它为其所有 直接子级 启用了弹性上下文。
.container {
display: flex; /* or inline-flex */
}
注意:CSS columns 在 flex
容器内不起作用
flex-direction
这建立了主轴,从而定义了弹性项目放置在弹性容器中的方向。即 规定弹性布局的主方向
- row (默认值): 在
ltr
情况下从左到右 ; 在rtl
情况下从右到左 - row-reverse: 与
row
相反 - column: 从上到下
- column-reverse: 从下到上
.container {
/* flex-direction: row | row-reverse | column | column-reverse; */
}
flex-wrap
默认情况下,弹性项目都将尝试将所有弹性项目挤进一行。
flex-wrap
规定是否自动换行
- nowrap (默认值): 所有弹性项目都会在一行
- wrap: 挤满后会自动换行,从上到下换行
- wrap-reverse: 挤满后会自动换行,从下到上换行
flex-flow
flex-direction
和flex-wrap
的简写
justify-content
这定义了沿主轴的对齐方式。
当一行上的所有 flex 项目都不灵活,或者是灵活的但已达到最大大小时,它有助于分配额外的可用空间。 当项目溢出行时,它还会对项目的对齐方式施加一些控制。
start
从行首开始排列。每行第一个元素与行首对齐,同时所有后续的元素与前一个对齐。end
从行尾开始排列。每行最后一个元素与行首对齐,其它元素与后一个对齐。flex-start
从行首开始排列。每行第一个弹性元素与行首对齐,同时所有后续的弹性元素与前一个对齐。flex-end
从行尾开始排列。每行最后一个弹性元素与行尾对齐,其他元素将与后一个对齐。center
伸缩元素向每行中点排列。每行第一个元素到行首的距离将与每行最后一个元素到行尾的距离相同。left
伸缩元素一个挨一个在对齐容器得左边缘,如果属性的轴与内联轴不平行,则left的行为类似于start。right
元素以容器右边缘为基准,一个挨着一个对齐,如果属性轴与内联轴不平行,则right的行为类似于end。space-between
在每行上均匀分配弹性元素。相邻元素间距离相同。每行第一个元素与行首对齐,每行最后一个元素与行尾对齐。space-around
在每行上均匀分配弹性元素。相邻元素间距离相同。每行第一个元素到行首的距离和每行最后一个元素到行尾的距离将会是相邻元素之间距离的一半。space-evenly
flex 项都沿着主轴均匀分布在指定的对齐容器中。相邻 flex 项之间的间距,主轴起始位置到第一个 flex 项的间距,主轴结束位置到最后一个 flex 项的间距,都完全一样。stretch
填充safe
与对齐关键字一起使用,如果选定的关键字会导致元素溢出容器造成数据丢失,那么将会使用 start 代替它。unsafe
无论项目和对齐容器的相对大小如何,都会遵循给定的对齐值。baseline
first baseline
last baseline
浏览器对这些值的支持是有细微差别的。
例如,某些版本的 Edge 从未支持 space-between,并且 Chrome 中还没有 start/end/left/right
最安全的值是 flex-start
、flex-end
和 center
。
align-items
这定义了弹性项目如何沿当前行的交叉轴布局的默认行为。将其视为横轴(垂直于主轴)的 justify-content 版本。
stretch
(default): 拉伸以填充容器(仍然尊重最小宽度/最大宽度)flex-start / start / self-start
: 项目放置在横轴的起点。这些之间的区别是微妙的,并且是关于尊重flex-direction
规则或write-mode
规则。flex-end / end / self-end
: 项目放置在横轴的末端。center
: 项目在横轴上居中baseline
: 项目基于基线对齐
safe
和 unsafe
修饰符关键字可以与所有其他关键字一起使用
align-content
当横轴上有额外空间时,这会对齐 flex 容器的线条,类似于 justify-content 如何对齐主轴内的单个项目。
注意:该属性只对多行灵活容器生效,其中 flex-wrap
设置为 wrap
或 wrap-reverse
)。
单行灵活容器(即 flex-wrap
设置为其默认值,no-wrap
)不会起作用
- normal (默认值): 默认位置
- flex-start / start
- flex-end / end
- center
- space-between
- space-around
- space-evenly
- stretch
支持 safe 和 unsafe 关键词
gap, row-gap, column-gap
gap 属性明确控制弹性项目之间的空间。它仅在不在外边缘的项目之间应用该间距。
Properties for the Children (flex items)
order
默认情况下,弹性项目按源顺序排列。但是,
order
属性可以控制它们在flex
容器中出现的顺序。
所有flex items
的order
默认为 0,即优先级都为 0。设元素会按照优先级排列,优先级大的往后排。
.item5 {
order: 1; /* 默认为0 */
}
flex-grow
这定义了弹性项目在必要时增长的能力。
它接受用作比例的无单位值。它规定了项目应该占用的弹性容器内的可用空间量。
如果所有项目都将flex-grow
设置为 1,则容器中的剩余空间将平均分配给所有子项。
如果其中一个子项目的值为 2,则该子项目将占用其它子项目之一的两倍空间(或者它至少会尝试)。
.item {
flex-grow: 4; /* 默认为 0 */
}
不支持负值
flex-shrink
这定义了弹性项目在必要时收缩的能力。
.item {
flex-shrink: 3; /* 默认为 1 */
}
不支持负值
flex-basis
这定义了在分配剩余空间之前元素的默认大小。
它可以是具体长度(例如 20%、5rem 等)或关键字。
auto
关键字的意思是“看看我的 width 或 height 属性”(这是由 main-size 关键字临时完成的,直到被弃用)。
content
关键字的意思是“根据项目的内容调整大小” —— 这个关键字还没有得到很好的支持,所以很难测试,也很难知道它的兄弟 max-content、min-content 和 fit-content 是做什么的。
如果设置为 0
,则不考虑内容周围的额外空间。
如果设置为 auto
,则根据其 flex-grow
值分配额外空间。请参阅此图:
flex
这是
flex-grow
、flex-shrink
和flex-basis
组合的简写。
第二个和第三个参数(flex-shrink 和 flex-basis)是可选的。
默认值为0 1 auto
,但如果您使用单个数字值设置它,例如 flex: 5; 则会将 flex-basis 更改为 0%,因此就像设置 flex-grow: 5;flex-grow: 1;flex-basis: 0%
建议您使用此属性,而不是设置单个属性。它会智能地设置其他值。
align-self
这允许为单个弹性项目覆盖默认对齐方式(或由
align-items
指定的对齐方式)。
浮动、清除和垂直对齐在弹性项目中不起作用。
为 Flexbox 添加前缀
Flexbox 需要一些供应商前缀来支持尽可能多的浏览器。它不仅包括带有供应商前缀的属性,实际上还有完全不同的属性和值名称。 这是因为 Flexbox 规范随着时间的推移发生了变化,创建了“Old” Flexbox and “New” Flexbox版本。
也许处理这个问题的最好方法是编写新的(和最终的)语法并通过 Autoprefixer
运行你的 CSS,它可以很好地处理回退。
或者,使用 Sass @mixin
来帮助添加一些前缀:
@mixin flexbox() {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
@mixin flex($values) {
-webkit-box-flex: $values;
-moz-box-flex: $values;
-webkit-flex: $values;
-ms-flex: $values;
flex: $values;
}
@mixin order($val) {
-webkit-box-ordinal-group: $val;
-moz-box-ordinal-group: $val;
-ms-flex-order: $val;
-webkit-order: $val;
order: $val;
}
// use
.wrapper {
@include flexbox();
}
.item {
@include flex(1 200px);
@include order(2);
}
例子
居中最简单版本:
.parent {
display: flex;
height: 300px; /* Or whatever */
}
.child {
width: 100px; /* Or whatever */
height: 100px; /* Or whatever */
margin: auto; /* Magic! */
}
这取决于弹性容器中设置为自动的边距吸收额外空间的事实。因此,设置自动边距将使项目在两个轴上完美居中。
现在让我们使用更多的属性。考虑一个包含 6 个项目的列表,所有项目都具有固定尺寸,但可以自动调整大小。 我们希望它们在水平轴上均匀分布,这样当我们调整浏览器大小时,一切都可以很好地缩放,并且不使用媒体查询。
.flex-container {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
}
让我们试试别的。想象一下,我们网站顶部有一个右对齐的导航元素,但我们希望它在中型屏幕上居中,在小型设备上为单列:
/* Large */
.navigation {
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
}
/* Medium screens */
@media all and (max-width: 800px) {
.navigation {
justify-content: space-around;
}
}
/* Small screens */
@media all and (max-width: 500px) {
.navigation {
flex-direction: column;
}
}
让我们通过玩弹性项目的灵活性来尝试更好的东西!带有全宽页眉和页脚的移动优先 3 列布局: