CSS弹性布局
本文最后更新于 2025年8月2日 下午
Demo:
https://github.com/xuekeven/learn_web/blob/main/dome/CSS/两栏_弹性布局1.html 。
https://github.com/xuekeven/learn_web/blob/main/dome/CSS/两栏_弹性布局2.html 。
搭配:
https://www.ruanyifeng.com/blog/2015/07/flex-grammar.html 。
https://www.ruanyifeng.com/blog/2015/07/flex-examples.html 。
介绍使用
Flexbox,全称弹性盒子布局(FlexibleBox Layout),是一种新的布局方式。跟浮动比,Flexbox 的可预测性更好,还能提供更精细的控制,它也能轻松解决垂直居中和等高列问题。
给元素添加display:flex
,该元素变成了一个弹性容器(flex container),它的直接子元素变成弹性子元素(flex item)。弹性子元素默认在同一行按照从左到右的顺序并排排列。弹性容器像块级元素一样填满可用宽度,但弹性子元素不一定填满其弹性容器的宽度。弹性子元素高度相等,该高度由它们的内容决定。
还可以用display: inline-flex
,它也能创建了一个弹性容器,行为类似于 inline-block 元素。它会跟其他行内元素一起流式排列,但不会自动增长到 100% 的宽度。此容器内部的弹性子元素跟使用 display: flex
创建的弹性子元素行为一样。在实际开发时,很少用到 display:inline-flex
。
弹性容器能控制内部元素的布局。子元素按照主轴线排列,主轴的方向为主起点(左)直到主终点(右);垂直于主轴的是副轴,方向从副起点(上)到副终点(下)。轴方向可改变。
通常情况下,创建一个弹性盒子需要用到这些方法:
- 选择一个容器及其子元素,给容器设置
display: flex
或display: inline-flex
- 如有必要,给容器设置 flex-direction 属性
- 给弹性子元素设置外边距和/或 flex 值,用来控制子元素的大小
- 将元素大致摆放到合适的位置后,就可以按需添加其他的 Flexbox 属性
Flexbox 的实现是 CSS 的一大进步。一旦你熟悉了,你可能想要在页面的每个地方都开始使用,不过你应该依靠正常的文档流,只在必要的时候才使用 Flexbox。
Flexbox 的一个有趣之处是如何基于弹性子元素的数量和其中内容量(及大小)计算容器大小。因为如果网页很大,或者加载很慢时可能会产生奇怪的行为,建议整页布局时用网格布局。只有一行多列的布局才会产生这个问题。如果主页面布局采用的是一列多行 不会出现问题。
Flexbox 是一维的,是以内容为切入点由内向外工作的。
Flexbox 允许使用margin:auto
来填充弹性子元素之间的可用空间。
容器属性
- flex-direction(主副轴方向)
- flex-wrap(子元素换行
- flex-flow(子元素排列方式)
- justify-content(主轴方向子元素对齐方式)
- align-items(副轴方向子元素对齐方式)
- align-content(多轴线对齐方式)
flex-direction
Flexbox 一个重要功能是能够切换主副轴方向,其用弹性容器的 flex-direction 属性控制。改变了主轴方向,副轴因为要与主轴垂直,所以方向也随之改变。
row
主轴从左到右的方向排列,副轴从上到下的方向排列。默认值。
row-reverse
主轴从右到左的方向排列,副轴从上到下的方向排列,类似 row。
column
主轴从上到下的方向排列,副轴从左到右的方向排列。
对于弹性子元素而言,flex-basis、flex-grow 和 flex-shrink 现在作用于元素的高度而不是宽度。
水平弹性盒子的大部分概念同样适用于垂直的弹性盒子。但有一点不同:CSS 中处理高度的方式与处理宽度的方式在本质上不一样。弹性容器会占据 100% 的可用宽度,而高度则由自身的内容来决定。即使改变主轴方向,也不会影响这一本质。所以在垂直的弹性盒子里如果不给弹性子元素设置宽度,弹性子元素的宽度默认为弹性容器的宽度,即 100% 的可用宽度。
弹性容器的高度由弹性子元素决定,它们会填满容器高度。但在垂直的弹性盒子里,子元素的 flex-grow 和 flex-shrink 不会起作用,除非有“外力”强行改变弹性容器的高度。
column-reverse
主轴从下到的上方向排列,副轴从左到右的方向排列,类似 column。
flex-wrap
默认情况下,子元素都排在一条线(又称”轴线”)上。当子元素填满这根轴线呢?
flex-wrap 属性设置是否允许弹性子元素换行(列)显示。当 flex-wrap 属性设置启用换行后,子元素将不再根据 flex-shrink 属性收缩,任何超过弹性容器的子元素都会换行(列)显示。
如果 flex-direction 值为 column 或者 column-reverse,则 flex-wrap 设置允许弹性子元素换到新的一列显示,不过这只在限制容器高度的情况下才发生,否则容器会扩展高度以包含全部子元素。
nowrap
不拆行或不拆列。默认值。
wrap
必要的时候拆行或拆列,第一行在上方。
启用后,子元素不再根据 flex-shrink 值收缩,超过弹性容器的子元素都会换行显示。
wrap-reverse
必要的时候拆行或拆列,但是以相反的顺序,第一行在下方。
启用后,子元素不再根据 flex-shrink 值收缩,超过弹性容器的子元素都会换行显示。
flex-flow
flex-flow 属性用于设置或检索弹性盒模型对象的子元素排列方式。
flex-flow 是 flex-direction 和 flex-wrap 的属性简写,默认值为 row nowrap。
justify-content
justify-content 属性控制子元素在主轴方向上的对齐方式(前提为子元素未填满容器)。
对齐时子元素之间会产生间距,间距是在子元素的外边距之后另进行计算的,且 flex-grow 值要考虑进来。如果任意子元素的 flex-grow 值不为 0,或任意子元素在主轴方向的外边距值为 auto,justify-content 失效。下面假设主轴为从左到右。
flex-start
左对齐(子元素从主轴的开始位置顺序排列)。默认值。
flex-end
右对齐(子元素从主轴的结束位置开始排列)。
center
居中对齐。
space-between
第一个子元素左对齐,最后一个子元素右对齐,剩下的子元素间隔均匀放在两者中间。
space-around
每个子元素两侧的间隔相等。所以,子元素之间的间隔是子元素与边框的间隔的两倍。
align-items
align-items 属性控制子元素在副轴方向上的对齐方式。
stretch
在主轴为水平排列情况下,子元素未设高度或设为 auto,子元素填充容器高度(等高列);在主轴为垂直排列情况下,子元素未设宽度或设为 auto,子元素填充容器宽度。填充满就不用考虑对齐方式。默认值。
baseline
子元素根据每个弹性子元素的第一行文字的基线对齐。
flex-start
子元素与副轴的起点对齐。
flex-end
子元素与副轴的终点对齐。
center
子元素与副轴的中点对齐。
align-content
align-content 属性定义多根轴线在容器内对齐方式(前提为允许子元素换行(列)且有多跟轴线)。
在主轴为水平排列情况下,轴线为水平轴线,有几行则几根轴线;
在主轴为垂直排列情况下,轴线为竖直轴线,有几列则几根轴线。
Flexbox 为一维布局,适合用在元素组成的行或列上。Flexbox 支持用 flex-wrap 属性换行(列),但是没法让上一行(列)的元素跟下一行(列)的元素对齐,所以没有 justify-items 这样的属性。
当 align-content 属性与 align-items 属性冲突时,align-content 属性优先。
stretch
轴线占满整个副轴。默认值。
flex-start
与副轴的起点对齐。
flex-end
与副轴的终点对齐。
center
与副轴的中点对齐。
space-between
与副轴两端对齐,轴线之间的间隔平均分布。
space-around
每根轴线两侧的间隔相等。所以轴线之间的间隔是轴线与边框的间隔一倍。
子元素属性
- order(子元素顺序)
- flex(子元素大小)
- flex-basis(子元素基准)
- flex-grow(子元素增长)
- flex-shrink(子元素收缩)
- align-self(副轴方向子元素对齐方式)
order
正常情况下,弹性子元素按照在 HTML 源码中出现的顺序排列。它们会沿着主轴方向从主轴起点开始排列。使用 order 属性能改变子元素排列顺序。还可以将其指为任意正负整数。如果多个弹性子元素有一样的值,它们就会按照源码顺序出现。
在初始状态下,所有弹性子元素的 order 属性值都为 0。指定一个元素的值为 −1 它则会移动到列表最前面,指定为 1 则会移动到最后。可以按需要给每个子元素指定 order 以便重新编排它们。这些值不一定要连续。
谨慎使用 order。让屏幕上的视觉布局顺序和源码顺序差别太大会影响网站的可访问性。在大多数浏览器里使用 Tab 键浏览元素的顺序与源码保持一致,如果视觉上的差别太大就会令人困惑。视力受损的用户使用的大部分屏幕阅读器也是根据源码的顺序来的。
flex
flex 属性控制弹性子元素在主轴方向上的大小(指元素的宽度),用来设置或者检索弹性盒模型对象子元素如何分配空间。flex 属性是 flex-grow、flex-shrink 和 flex-basis 的属性简写,前两个属性都基于 flex-basis。
推荐使用简写属性 flex,而不是分别声明 flex-grow、flex-shrink、flex-basis。与大部分的简写属性不一样,如果在 flex 中忽略声明某个子属性,那么子属性的值并不会被置为默认值。如果某个子属性被省略,那么 flex 简写属性会设置其为: flex-grow:1
flex-shrink:1
flex-basis:0
。但是,默认值正是大多数情况下所需要的值。
flex 有几个特殊值:
flex: 0 1 auto
(默认值)
不增长但自动收缩,收缩比例为 1;flex-basis 为 auto,即取自用户定义的宽度或内容本身的宽度。flex: 1 1 auto
(flex: auto
)
自动增长缩放,比例均为 1;flex-basis 为 auto,即取自用户定义的宽度或内容本身的宽度。flex: 0 0 auto
(flex: none
)
不增长不缩放;flex-basis 为 auto,即取自用户定义的宽度或内容本身的宽度。flex: 0 1 0%
(flex: 0
)
不增长但自动收缩,收缩比例为 1;flex-basis 为 0。flex: 1 1 0%
(flex: 1
)
自动增长缩放,比例均为 1;flex-basis 为 0。当给所有子元素设置 flex: 1 则代表子元素平分宽度。- 两个值
第一个为 flex-grow;第二个,如果是数字认为是 flex-shrink,如果是宽度认为是 flex-basis。
flex-basis
flex-basis 属性定义了子元素大小的长度基准值,即一个初始的“主尺寸”。
flex-basis 属性可以设置为任意长度单位的值,包括 px、em、百分比。它默认值是 auto,此时浏览器会检查元素是否设置 width 属性。如果有则使用 width 值作为 flex-basis 值;如果没有则用元素内容自身的大小。如果 flex-basis 的值不是 auto,那么 width 属性会被忽略。
每个子元素初始主尺寸确定后,它们可能需要在主轴方向扩大或者缩小来适应(或填充)弹性容器的大小。这时候就需要 flex-grow 属性和 flex-shrink 属性来决定如何增长和缩放。
当 flex-basis 为 0% 时,内边距会改变弹性子元素的初始主宽度计算的方式。如果想要精确结果,则要么保证两列有相同的内边距,要么用 flex 属性时使用 flex-basis 设置弹性基准值。
flex-grow
每个弹性子元素 flex-basis 值计算出来后,它们(加上子元素间的外边距)加起来会占据一定的宽度。如果加起来的宽度不一定正好填满弹性容器的宽度,可能会有留白。
多出来的留白(或剩余宽度)会按照 flex-grow(增长因子)的值分配给每个弹性子元素,flex-grow 的值为非负整数。如果弹性子元素 flex-grow 值为 0,那么子元素的宽度不会超过 flex-basis 的值;如果弹性子元素 flex-grow 值非 0,那么子元素会增长到所有的剩余空间被分配完,这意味着弹性子元素会填满容器的宽度。
flex-grow 值越大,元素的“权重”越高,就会占据更大剩余宽度。一个flex-grow:2
的子元素增长的宽度为flex-grow:1
的子元素增长的宽度的两倍。分配时只跟 flex-grow 有关,跟 flex-basis 无关。
flex-grow 默认值为 0。
flex-shrink
flex-shrink 属性与 flex-grow 属性遵循相似的原则。计算出弹性子元素的初始主尺寸后,它们的累加值可能会超出弹性容器的可用宽度。如果不用 flex-shrink 属性又不用 flex-wrap 属性,就会导致溢出。
每个子元素的 flex-shrink 值代表它是否应该收缩以防止溢出,flex-grow 的值为非负整数。与 flex-grow 属性类似,如果子元素 flex-shrink 值为 0,则不会收缩;如果子元素 flex-shrink 值非 0,则会收缩至不再溢出。按照 flex-shrink 值的比例,值越大的元素收缩得越多。收缩时只跟 flex-shrink 有关,跟 flex-basis 无关。
flex-shrink 默认值为 1。
align-self
align-self 属性控制单个子元素在副轴方向上的对齐方式。align-self 属性跟弹性容器的 align-items 属性效果相同,但是它能单独给弹性子元素设定不同的对齐方式,两者冲突时 align-self 属性优先。
auto
以容器的 align-items 值为准,使用其他值会覆盖容器的设置。默认值。
stretch
在主轴为水平排列情况下,子元素未设高度或设为 auto,子元素填充容器高度(弹性布局能实现等高列);在主轴为垂直排列情况下,子元素未设宽度或设为 auto,子元素填充容器宽度。
flex-start
子元素与副轴的起点对齐。
flex-end
子元素与副轴的终点对齐。
center
子元素与副轴的中点对齐。
baseline
子元素根据每个弹性子元素的第一行文字的基线对齐。