Skip to main content

flex布局

Learn From:

flex 布局背后的主要思想是让容器能够改变其项目的宽度/高度(和顺序)以最好地填充可用空间(主要是为了适应各种显示设备和屏幕尺寸)。弹性容器扩展项目以填充可用的可用空间或缩小它们以防止溢出。

css-flexbox-poster.png

Flexbox 布局最适合应用程序的组件和小规模布局,而 Grid 布局适用于更大规模的布局。

基本概念

由于 flex 是一个完整的模块而不是单个属性,它涉及到很多东西,包括它的整个属性集。 其中一些是要设置在容器上(父元素,称为“flex container”),而其他是要设置在子级(称为“flex items”)上。

如果常规布局基于块流方向和内联流方向,则弹性布局基于“弹性流方向”。请看下面中的这张图,解释了 flex 布局背后的主要思想:

flex.png

  • main axis: 弹性容器的主轴是弹性项目沿其布置的主轴。请注意,它不一定是水平的;它取决于 flex-direction 属性。
  • main-start | main-end: 弹性项目从 main-startmain-end 放置在容器内。
  • main size: 弹性项目的宽度或高度,以主要尺寸中的为准。
  • cross axis: 垂直于主轴的轴称为交叉轴。它的方向取决于主轴方向。
  • cross-start | cross-end: 弹性线用项目填充并放入容器中,从 cross-start开始,到 cross-end 结束。
  • cross size: 弹性项目的宽度或高度。

Properties for the Parent (flex container)

container.png

display

定义一个弹性容器,内联或块 取决于给定的值。它为其所有 直接子级 启用了弹性上下文。

.container {
display: flex; /* or inline-flex */
}

注意:CSS columns 在 flex 容器内不起作用

flex-direction

这建立了主轴,从而定义了弹性项目放置在弹性容器中的方向。即 规定弹性布局的主方向

Value
  • row (默认值): 在 ltr 情况下从左到右 ; 在 rtl 情况下从右到左
  • row-reverse: 与 row 相反
  • column: 从上到下
  • column-reverse: 从下到上

flex-direction.png

.container {
/* flex-direction: row | row-reverse | column | column-reverse; */
}

flex-wrap

默认情况下,弹性项目都将尝试将所有弹性项目挤进一行。
flex-wrap 规定是否自动换行

可选值
  • nowrap (默认值): 所有弹性项目都会在一行
  • wrap: 挤满后会自动换行,从上到下换行
  • wrap-reverse: 挤满后会自动换行,从下到上换行
Result
Loading...
Live Editor

flex-flow

flex-directionflex-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
Result
Loading...
Live Editor
请注意

浏览器对这些值的支持是有细微差别的。
例如,某些版本的 Edge 从未支持 space-between,并且 Chrome 中还没有 start/end/left/right
最安全的值是 flex-startflex-endcenter

align-items

这定义了弹性项目如何沿当前行的交叉轴布局的默认行为。将其视为横轴(垂直于主轴)的 justify-content 版本。

value
  • stretch (default): 拉伸以填充容器(仍然尊重最小宽度/最大宽度)
  • flex-start / start / self-start: 项目放置在横轴的起点。这些之间的区别是微妙的,并且是关于尊重 flex-direction 规则或 write-mode 规则。
  • flex-end / end / self-end: 项目放置在横轴的末端。
  • center: 项目在横轴上居中
  • baseline: 项目基于基线对齐

safeunsafe 修饰符关键字可以与所有其他关键字一起使用

Result
Loading...
Live Editor

align-content

当横轴上有额外空间时,这会对齐 flex 容器的线条,类似于 justify-content 如何对齐主轴内的单个项目。

注意

注意:该属性只对多行灵活容器生效,其中 flex-wrap 设置为 wrapwrap-reverse)。
单行灵活容器(即 flex-wrap 设置为其默认值,no-wrap)不会起作用

取值
  • normal (默认值): 默认位置
  • flex-start / start
  • flex-end / end
  • center
  • space-between
  • space-around
  • space-evenly
  • stretch

支持 safe 和 unsafe 关键词

Result
Loading...
Live Editor

gap, row-gap, column-gap

gap 属性明确控制弹性项目之间的空间。它仅在不在外边缘的项目之间应用该间距。

Properties for the Children (flex items)

items

order

默认情况下,弹性项目按源顺序排列。但是, order 属性可以控制它们在 flex 容器中出现的顺序。
所有flex itemsorder 默认为 0,即优先级都为 0。设元素会按照优先级排列,优先级大的往后排。

.item5 {
order: 1; /* 默认为0 */
}
Result
Loading...
Live Editor

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 值分配额外空间。请参阅此图: rel-vs-abs-flex.svg

flex

这是 flex-growflex-shrinkflex-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 列布局:

扩展阅读