百度前端技术学院 第七天学习笔记(CSS flexbox)

flexbox弹性盒子

  • MDN flexbox例子
  • 想要flex生效必须定义其父元素的display属性为flex或inline-flex
  • flex容器flex container(父级容器)
  • flex子项flex item
  • 主轴main axis(主轴方向是可变的,主要取决于flex-direction属性),它是沿着 flex 元素放置的方向延伸的轴(比如页面上的横向的行、纵向的列)。该轴的开始和结束被称为 main start 和 main end。
  • 交叉轴(cross axis)垂直于 flex 元素放置方向的轴(垂直于主轴)。该轴的开始和结束被称为 cross start 和 cross end。
    flexbox示意图

父级container的属性

display定义flex父容器

display属性定义一个flex容器,内联或者根据指定的值,来作用于下面的子类容器。

  • 请注意,CSS列对flex容器无效。
  • float, clear, vertical-align 在flex项目中不起作用
属性值 含义
flex 块,将对象作为弹性伸缩盒显示
inline-flex 内联,将对象作为内联块级弹性伸缩盒显示

注意
子组件能够撑满剩余空间的前提是其父容器的尺寸不为零。如果父容器既没有固定的width和height,也没有设定flex,则父容器的尺寸为零。其子组件如果使用了flex,也是无法显示的。所以可以给父组件设置flex:1,表示让它占据了垂直的整个空间。


flex-flow简写flex-direction和flex-wrap属性

  • 这是flex-direction和flex-wrap属性的简写,它们一起定义了flexbox的主轴和交叉轴。
  • 默认值为row nowrap。(即:将所有子项排列在一行上)
    1
    flex-flow: row wrap;

flex-direction规定子项排列方式及方向

Flexbox是单向布局概念。可以将弹性项目想像为主要以水平行或垂直列布置。
flex-direction

属性值 含义
row(默认值 把子项排在同一,从左到右
row-reverse 行,从右到左
column 把子项排在同一,从上到下
column-reverse 与row-reverse相似,只是变成了从下到上

flex-wrap使溢出子项换行

  • 默认情况下,所有弹性项目都将尝试放入一行。可以通过修改flex-wrap属性值使溢出父元素宽度的子项换行。
  • 注意:flex-direction属性值为row时将flex-wrap属性值设置为wrap会使得子项换行,但一个子项占据一行,此时可通过设置子项的flex属性值来设置默认宽度来达到一行多个子项的效果。
    flex-wrap
属性值 含义
nowrap (默认) 所有弹性项目都在一行上
wrap 弹性项目将从上到下分布在多行上。
wrap-reverse 弹性项目将从下到上分布在多行上。

justify-content定义子项沿主轴的对齐方式

定义了子项沿主轴的对齐方式。(主轴是可变的,主要取决于flex-direction属性值)
justify-content各属性值效果

属性值 含义
flex-start (默认 从flex-direction的开始处开始放置子项
flex-end 从flex-direction的末端开始放置子项
start 子项从书写模式方向的起点开始放置
end 子项从书写模式方向的末端开始放置
left 子项从容器的左边缘开始放置,除非这与flex-direction不一致,否则它的行为类似于start
right 子项从容器的右边缘开始放置,除非这与flex-direction不一致,否则它的行为类似于start
center 子项沿线居中
space-between 子项在行中均匀分布,第一项位于开始处,最后一项位于结束处
space-around 项目在行中均匀分布,并且周围有相等的空间。请注意,从视觉上看,空间是不相等的,因为所有项目的两侧都具有相等的空间。第一项相对于容器边缘有一个单位的空间,但是它与下一项之间有两个单位的空间。
space-evenly (evenly:均匀地)分配项目,任意两个项目之间的间距(以及到边缘的间距)相等
  • 请注意,浏览器对这些值的支持是有细微差别的。例如,space-between从来没有获得Edge支持,并且Chrome没有start/end/left/rightMDN 有详细的图表。最安全的值是flex-startflex-endcenter
  • 还可以这些值与将两个其他关键字(safe和unsafe)配对。使用safe确保无论执行哪种类型的定位,都不能以无法滚动内容的方式推送元素以使其呈现屏幕外(例如,从顶部移出)(称为“数据丢失”) 。

align-items定义子项在交叉轴上的对齐方式

用来设置每个flex元素在侧轴上的默认对齐方式
align-items

1
2
3
.container {
align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe;
}
属性值 含义
stretch (默认 使所有 flex 项沿着交叉轴的方向拉伸以填充父容器
如果父容器在交叉轴方向上没有固定宽度(即高度),则所有 flex 项将变得与最长的 flex 项一样长(即高度保持一致)。(仍然遵守最小宽度/最大宽度)
flex-start/ start/ self-start 项目放置在cross-axis的起点,它们之间的区别是微妙的,并且是遵守flex-direction规则或writing-mode规则的
flex-end/ end/ self-end 项目放置在cross-axis的末端。差异再次是微妙的,尊重flex-direction规则与writing-mode规则
center 使子项保持其原有的高度,在交叉轴上居中
baseline 项目对齐,例如基线对齐

可以结合safe和unsafe关键字与上面的属性值一起使用(但是注意浏览器支持),他可以防止内容变得不可访问。

align-content定义行沿交叉轴的对齐方式

  • 当flex父容器在交叉轴上有多余的空间时,且属性值为:flex-start、flex-end、center、stretch时,将所有子项作为一个整体单位沿交叉轴进行对齐。
  • 当flex父容器在交叉轴上有多余的空间时,且属性值为:space-between/space-around时,将单行子项作为一个单位沿交叉轴进行对齐。
  • align-content属性设置了不同行之间如何沿着父容器(flexbox container)的交叉轴在行周围分配空间。
  • 注意:只有一行flexbox时,此属性无效
  • 区分:justify-content的单位是子项,align-content的单位是一行子项

align-content
align-content

1
2
3
.container {
align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe;
}
属性值 含义
stretch (默认 拉伸所有行来填满剩余空间。剩余空间平均的分配给每一行
start 所有行从父容器的起始边缘开始填充
flex-start 所有行从垂直轴起点开始填充。第一行的垂直轴起点边和容器的垂直轴起点边对齐。接下来的每一行紧跟前一行。
end 所有行从父容器的结束边缘开始填充
flex-end 所有行从垂直轴末尾开始填充。最后一行的垂直轴终点和容器的垂直轴终点对齐。同时所有后续行与前一个对齐。
center 所有行朝向父容器的中心填充。每行互相紧挨,相对于容器居中对齐。容器的垂直轴起点边和第一行的距离相等于容器的垂直轴终点边和最后一行的距离。
space-between 所有行在容器中平均分布,相邻两行间距相等。容器的垂直轴起点边和终点边分别与第一行和最后一行的边对齐。(第一行在容器的开头,而最后一行在容器的结尾
space-around 所有行在容器中平均分布,相邻两行间距相等。容器的垂直轴起点边和终点边分别与第一行和最后一行的距离是相邻两行间距的一半。(每一行周围具有相等的空间(注意:两行之间有两个单位的空间,参考justify-content属性的space-around属性值))
space-evenly 项目均匀分布,(从视觉上看,每一个行周围具有相等的空间。)所有行沿垂直轴均匀分布在对齐容器内。每对相邻的项之间的间距,主开始边和第一项,以及主结束边和最后一项,都完全相同

区别justify-content与align-content还有align-items

justify-content属性可应用于所有的flex容器,定义子项在主轴上的对齐方式(位置)。【子项为单位】

align-items属性可应用于所有的flex容器,定义子项在交叉轴上的对齐方式(位置)

align-content属性只适用多行的flex容器(也就是flex父容器中的子项不止一行时该属性才有效果)。
当flex父容器在交叉轴上有多余的空间时,且属性值为:flex-start、flex-end、center、stretch时,将所有子项作为一个整体单位沿交叉轴进行对齐。
当flex父容器在交叉轴上有多余的空间时,且属性值为:space-between/space-around时,将单行子项作为一个单位沿交叉轴进行对齐。
align-content


子项item的属性

order顺序

  • 默认情况下,flexbox按源顺序排列。但是,该order属性可以控制子项在flex容器中出现的顺序而不会影响到源顺序(即 dom 树里元素的顺序)。这也是传统布局方式很难做到的一点。
  • order 值小的 flex 项在显示顺序中更靠前相同 order 值的 flex 项按源顺序显示。所以假如你有四个元素,其 order 值分别是2,1,1和0,那么它们的显示顺序就分别是第四,第二,第三,和第一。
  • 属性值:无单位整数,默认为0,可以为负值
    order
  • 例子:在众多按钮中将第一个按钮移动到主轴的末尾
    1
    2
    3
    button:first-child {
    order: 1;
    }

flex简写flex-grow、flex-shrink和flex-basis

  • 建议使用该简写属性!
  • 这是flex-grow、flex-shrink和flex-basis组合的简写。
  • 第二和第三个参数(flex-shrink和flex-basis)是可选的(省略部分属性值时注意有顺序要求)。
  • 默认值0 1 auto。(即0:如果存在剩余空间,也不放大。1:如果空间不足,则该子项格局1的比例缩小。auto:子项初始大小参照我的width和height属性
  • 大多数情况下,开发者只需要将 flex 设置为 auto,initial,none,或一个无单位正数 即可。
  • 如果一个子项a给定flex:200px而另一个子项b给定flex:1,那么将会先给a 200px,然后b自适应
  • 例子:表示“每个flex 子项将首先给出200px的可用空间,然后将剩余的可用空间将根据flex-grow属性值(2)分配的比例共享”
1
2
3
.item {
flex: 2 200px
}

注意

  • 一般而言我们会使用flex:1来指定某个组件扩张以撑满所有剩余的空间。
  • 子组件能够撑满剩余空间的前提是其父容器的尺寸不为零。如果父容器既没有固定的width和height,也没有设定flex,则父容器的尺寸为零。其子组件如果使用了flex,也是无法显示的。所以可以给父组件设置flex:1,表示让它占据了垂直的整个空间。
属性值 描述
initial 元素会根据自身宽高设置尺寸。它会缩短自身以适应 flex 容器,但不会伸长并吸收 flex 容器中的额外自由空间来适应 flex 容器 。相当于将属性设置为”flex: 0 1 auto”。
auto 元素会根据自身的宽度与高度来确定尺寸,但是会伸长并吸收 flex 容器中额外的自由空间,也会缩短自身来适应 flex 容器。这相当于将属性设置为 “flex: 1 1 auto”.
none 元素会根据自身宽高来设置尺寸。它是完全非弹性的:既不会缩短,也不会伸长来适应 flex 容器。相当于将属性设置为”flex: 0 0 auto”。【所以可以通过设置flex为none然后给定width使子项固定大小】
<'flex-grow'> 定义 flex 元素的 flex-grow 属性,详见 <number>。默认值为 0,负值无效。
<'flex-shrink'> 定义 flex 元素的 flex-shrink 属性,详见 <number>。默认值为1,负值无效。
<'flex-basis'> 定义 flex 元素的 flex-basis 属性。若值为0,则必须加上单位,以免被视作伸缩性。 默认值为 auto。

flex 属性值顺序要求

flex 属性可以指定1个,2个或3个值。但他是有顺序要求的!

单值语法: 值必须为以下其中之一:

  • 一个无单位数(<number>): 它会被当作<flex-grow>的值。
  • 一个有效的宽度(width)值: 它会被当作 <flex-basis>的值。
  • 关键字noneautoinitial.

双值语法: 第一个值必须为一个无单位数,并且它会被当作 <flex-grow> 的值。第二个值必须为以下之一:

  • 一个无单位数:它会被当作<flex-shrink>的值。
  • 一个有效的宽度值: 它会被当作 <flex-basis> 的值。

三值语法:

  • 第一个值必须为一个无单位数,并且它会被当作<flex-grow>的值。
  • 第二个值必须为一个无单位数,并且它会被当作 <flex-shrink> 的值。
  • 第三个值必须为一个有效的宽度值, 并且它会被当作 <flex-basis> 的值。

flex-grow子项空间占比(放大比例)

  • flex-grow属性值是一个无单位的比例值,规定 flex 项相对于其他flex 项沿主轴的进行扩展的量,它决定了子项在父级容器(flex container)内部占用多少可用空间,占用的空间是在设置 padding 和 margin 之后剩余的空间。
  • 属性值默认为0(即如果存在剩余空间,也不放大),不能为负数。
  • 如果所有项目flex-grow都设置为1,则容器中的剩余空间将平均分配给所有子项。如果其中一个孩子的值为2,则剩余空间将占其他孩子的两倍(或者至少会尝试)。
    flex-grow
    1
    2
    3
    .item {
    flex-grow: 3; /* default 0 */
    }

固定子项大小

想让子项固定大小可设置flex为none然后给定width

flex-shrink弹性收缩(缩小比例)

  • flex-shrink 属性指定了 flex 元素的收缩规则。flex 元素仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink 的值。
  • 一般用于溢出容器的 flex 子项。这指定了从每个 flex 项中取出多少溢出量,以阻止它们溢出它们的容器。 这是一个相当高级的弹性盒子功能.
  • 属性值:默认为1(即如果空间不足,该项目将缩小),不能为负数。如果是0,则空间不足子项也不缩小
    1
    2
    3
    .item {
    flex-shrink: 2; /* default 1 */
    }
  • MDN flex-shrink

flex-basis子项初始大小(最小值)

  • flex-basis 指定了 flex 元素在主轴方向上的初始大小。如果不使用 box-sizing 改变盒模型的话,那么这个属性就决定了 flex 元素的内容盒(content-box)的尺寸。
  • 即:flex-basis 指定在分配多余空间之前,项目占据的主轴空间(main size)
属性值 含义
长度 例如20%,5rem等
关键字 auto:参照我的width和height属性
content(此关键字不能很好地支持,不建议使用):根据子项的内容调整大小
1
2
3
.item {
flex-basis: 200px; /* default auto */
}

图解flex-basis中auto

  • 属性值如果设置为0,则不考虑内容周围的额外空间。
  • 属性值如果设置为auto,则根据其flex-grow值分配额外的空间。

align-self调整单个子项在交叉轴上的对齐方式

  • align-self 会对齐当前 flex 行中的 flex 元素,并覆盖已有的align-items 的值按照cross axis方向进行排列.
  • 注意:float(浮动), clear(清除浮动) 和 vertical-align对flex子项没有影响。
  • 默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

align-self

1
2
3
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
属性值 含义
auto (默认值) 设置为父元素的 align-items 值,如果该元素没有父元素的话,就设置为 stretch
flex-start flex 元素会对齐到 cross-axis 的首端
flex-end flex 元素会对齐到 cross-axis 的尾端
center flex元素会对齐到 cross-axis 的中间,如果该元素的 cross-size 的尺寸大于 flex 容器,将在两个方向均等溢出
baseline 所有的 flex 元素会沿着基线对齐。
如弹性盒子元素的行内轴与侧轴为同一条,则该值与’flex-start’等效。其它情况下,该值将参与基线对齐。
stretch 子项在交叉轴方向被拉伸以适应容器。
如果指定侧轴大小的属性值为’auto’,则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照’min/max-width/height’属性的限制。

各种属性值效果参考


flex 嵌套

弹性盒子也能创建一些颇为复杂的布局。一个元素即可以是父容器也可以是子项,也就是说你可以为父容器中的一个子项也设置display属性使其成为一个父容器。
例子
如上图,我们用一个 <section> 元素作为父容器包含了三个 <article>元素。第三个 <article> 元素(作为<section>子项的它同时被设置为父容器)包含了三个 <div>,像这样:

1
2
3
4
5
6
7
section - article
article
article - div - button
div button
div button
button
button

特别注意这里我们设置第三个

元素的子节点的布局同样为 flex ,但是属性值为列布局flex-flow: column;)。

,