flex布局轻而易举实现页面布局;超详细解析轻松掌握

我们曾如此渴望命运的波澜,到最后才发现,人生最曼妙的风景,竟是内心的淡定和从容。我们曾如此期盼外界的认可,到最后才知道,世界是自己的,与他人毫无关系。——杨绛

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第1张图片

开始

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第2张图片

痛点

网页布局(layout)的传统解决方案,

基于盒状模型,依赖 display属性 + position属性 + float属性。

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第3张图片

它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。

44年前我们把人送上月球,但在CSS中我们仍然不能很好实现垂直居中。

——James Anderson

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第4张图片

诞生

2009年,W3C提出了一种新的方案——Flex布局,可以简便、完整、响应式地实现各种页面布局。

一、什么是Flex布局?

Flex是Flexible Box的缩写,即“弹性盒子”,用来为盒状(盒子)模型提供最大的灵活性。

Flexible(灵活的; 有弹性的;  可变动的;)

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第5张图片

弹性盒子是一种用于按行或按列布局元素的一维布局方法; 元素可以膨胀以填充额外的空间, 也可收缩以适应更小的空间;

使用Flexible Box来进行布局的方案称之为Flex布局(Flex layout)。

目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。

二、基础知识和术语

——(两对象,两轴,两线,两尺寸)

       Basics and terminology(基础知识和术语)

         Since flexbox is a whole module and not a single property, it involves a lot of things including its whole set of properties. Some of them are meant to be set on the container (parent element, known as “flex container”) whereas the others are meant to be set on the children (said “flex items”).

        If “regular” layout is based on both block and inline flow directions, the flex layout is based on “flex-flow directions”. Please have a look at this figure from the specification, explaining the main idea behind the flex layout.

        由于flexbox是一个完整的模块(css3以模块的形式更新版本),而不是一个单独的属性,所以它涉及到很多事情,包括它的一整套属性。其中一些要设置在容器上(父元素,称为“弹性容器”),而另一些则要设置在子元素上(称为“弹性项目”)。

        “常规”布局基于块流方向(垂直方向)和内联流方向(水平方向),而弹性布局则基于“弹性流方向”。请看一下本说明书中的这个图(下图),其解释着flex布局背后的主要思想。

两对象:flex container(容器)和 flex item(项目)

两轴:main axis(主轴) 和 cross axis(交叉轴)

两线:main/cross start (起始线)和 main/cross end (终点线)

两尺寸: main size(主尺寸) 和 cross size (交叉尺寸)

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第6张图片

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第7张图片

Items will be laid out following either the main axis (from main-start to main-end) or the cross axis (from cross-start to cross-end).

项目将按照主轴(从主起始线main start到主终点线main end)或交叉轴(从交叉起始线cross start到交叉终点线cross end)进行布置

  • main axis 主轴 – The main axis of a flex container is the primary(首要的、最重要的) axis along which flex items are laid out. Beware, it is not necessarily horizontal; it depends on the flex-direction property (see below).
  • ——弹性容器的主轴是布置弹性项目的首要的轴。小心,它(主轴)不一定是水平的;它取决于flex direction属性(见下文)。

  • main-start | main-end 主起始线和主终点线 – The flex items are placed within the container starting from main-start and going to main-end.
  • ——弹性项目被放置在容器内,从主起始线一直到主终点线。

  • main size 主尺寸 – A flex item’s width or height, whichever is in the main dimension(尺寸; 方面; 范围), is the item’s main size. The flex item’s main size property is either the ‘width’ or ‘height’ property, whichever is in the main dimension.
  • ——弹性项目的宽度或高度(以主尺寸中的宽度或高度为准)是项目的主尺寸。弹性项的主要大小属性是“width”或“height”属性,以主维度中的属性为准。简而言之(项目默认沿主轴排列。单个项目占据的主轴空间叫做main size)

  • cross axis  交叉轴 – The axis perpendicular to the main axis is called the cross axis. Its direction depends on the main axis direction.
  • ——垂直于主轴的轴称为交叉轴。其方向取决于主轴方向。

  • cross-start | cross-end 交叉起始线和交叉终点线 Flex lines are filled with items and placed into the container starting on the cross-start side of the flex container and going toward the cross-end side.
  • ——弹性行 装着满满的项目,并从弹性容器的交叉起始线开始放置到容器中,然后向交叉端侧移动。

  • cross size 交叉尺寸 – The width or height of a flex item, whichever is in the cross dimension, is the item’s cross size. The cross size property is whichever of ‘width’ or ‘height’ that is in the cross dimension.
  • 弹性项目的宽度或高度,以交叉尺寸中的值为准,即为项目的交叉尺寸。cross-size属性是cross-dimension中的“width”或“height”中的任意一个。简而言之(占据的交叉轴空间叫做cross size。)

三、flex布局的作用

  • 在父容器里面 垂直居中 一个子项目
  • 使容器的所有 子项占用等量的可用宽度/高度 ,而不管有多少宽度 / 高度可用
  •  比如使多列布局中的所有列采用相同的高度,即使它们包含的内容量不同。

四、各种属性

弹性容器(父级元素)的属性

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第8张图片

1.display

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第9张图片

display属性可以定义一个弹性容器;内联或块,取决于给定的值。它为其所有直接子项目启用了灵活的上下文。

请注意,CSS列对flex容器没有影响。

display: flex; 就是在告诉你的浏览器,“我想使用弹性盒子,在这个容器。”

属性值设置为flex和inline-flex的区别:

1.如果display对应的值是flex的话,

那么flex container是以block-level的形式存在的,相当于是一个块级元素

(块级元素占据其所在行的整个宽度)

2.如果display的值设置为inline-flex的话,

那么flex container是以inline-level的形式存在的,相当于是一个行内块元素

3.这两个属性值差异的影响在设置了属性值的元素上面,它们在子元素上的效果都是一样的

4.如果一个元素的父元素开启了flex布局;

那么其子元素的display属性对自身的影响将会失效,但是对其内容的影响依旧存在的;

举个例子:父元素设置了display: flex

即使子元素设置了display:block或者display:inline的属性,

子元素还是会表现的像个行内块元素一样,这就是父元素对其的影响使其display属性对自身的影响失效了;

(父元素从display:block转变为display: flex

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第10张图片

但是为什么我们说其对内容的影响还在呢?

假如说父子元素都设置了display: flex,那么子元素自身依然是行块级元素,

并不会因为其开启了flex布局就变为块级元素,

但是该子元素的内容依然会受到它flex布局的影响,各种flex特有的属性就会生效;

总结:我们如果想让设置flex布局的盒子变成块级元素的话,那就dispaly的属性值就设置为flex;

如果想让盒子变为行内块元素的话,就设置为inline-flex

父元素开启了flex布局之后,子元素的display属性对元素本身的影响就会失效,但是依旧可以影响盒子内部的元素;

2.flex-direction

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第11张图片

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第12张图片

图示动画展示了flex-direction的四个可能值:从上到下、从下到上、从右到左和从左到右。

flex-direction属性将建立主轴,从而定义项目在容器中的放置方向。

Flexbox(除了可选的包装)是一个单向布局概念。

将弹性项目视为主要以水平行或垂直列的形式进行布局。

row (default):在ltr中从左到右;rtl中从右到左

row-reverse:在ltr中从右向左;rtl中从左到右

column:与行相同,但从上到下

column-reverse:与行反转相同,但自下而上

ltr ?rtl?

——书写模式(writing-mode)、文字方向性

writing-mode 属性指定块流动方向和行级内容的流动方向。

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第13张图片

CSS writing-mode属性

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第14张图片

flex direction允许您控制容器中项目的显示方式。您希望它们从左到右、从右到左、从上到下还是从下到上?通过设置容器的dlex-direction,可以轻松地完成所有这些操作。

应用display:flex后的默认排列(flex-direction:row;)是沿主轴从左到右排列。下面的动画显示了将flex-direction:column; 添加到容器元素时发生的情况。

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第15张图片

也可以将 flex-direction 设置为  column  和  column-reverse

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第16张图片

3.flex-wrap

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第17张图片

默认情况下,弹性项目都会尝试放在一行一条线(“轴线”)上。

您可以在需要的时候,更改此属性,使项目换行。

nowrap(default):所有弹性项目都将在一行上。

wrap:弹性项目将从上到下换行成多行。

wrap-reverse:弹性项目将从下到上换行成多行。

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第18张图片

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第19张图片

4.flex-flow

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第20张图片

这是 flex direction 和 flex wrap 属性的简写,它们共同定义了flex容器的主轴和横轴。

默认值为row nowrap。

5.justify-content

 justify-content 决定了 flex items 在 main axis 上的对齐方式

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第21张图片

这定义了沿主轴的对齐方式。当一行中的所有弹性项目都是不灵活的,或者是灵活的但已达到最大大小时,它帮助分配剩余的额外可用空间。

当项目溢出行时,它还对项目的对齐进行一些控制。

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第22张图片

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第23张图片

flex-start(默认):项目朝(挤向)flex-direction的起始位置排列。

flex-end:项目朝(挤向)flex-direction的结束位置排列。

start:项目朝书写模式方向的起始位置排列。

end:项目朝书写模式方向的结束位置排列。

left:项目朝容器的左边缘排列,除非与flex-direction不符合,否则会表现得像start。

right:项目朝容器的右边缘排列,除非与flex-direction不符合,否则会表现得像end。

center:项目在行中居中对齐(挤在中间)。

space-between:项目在行中均匀分布;第一个项目在起始线上,最后一个项目在结束线上。

space-around:项目在行中均匀分布,并在它们周围有相等的空间。请注意,从视觉上看,空间并不相等,因为所有项目两侧的空间相等。第一个项目将在容器边缘有一个单位的空间,但是在下一个项目之间有两个单位的空间,因为下一个项目有自己的间距。

space-evenly:项目的间距(以及边缘的空间)均等分布。

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第24张图片

请注意,对于这些值的浏览器支持是有差异的。

例如,某些版本的Edge从未支持space-between

start/end/left/right在Chrome中尚未支持。MDN有详细的图表可供参考。

最安全的值是flex-start、flex-end和center。

此外,还有两个额外的关键词可以与这些值配对使用:safe和unsafe。

使用safe可以确保无论如何进行这种定位类型,都不会将元素推到屏幕之外(例如顶部之外),以避免内容无法滚动(称为“数据丢失”)。

6.align-items

 align-items 决定了 flex items 在 cross axis 上的对齐方式

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第25张图片

这定义了在当前行上沿着交叉轴如何排列 flex 项目的默认行为。可以将其视为交叉轴(与主轴垂直)上的 justify-content 版本。

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第26张图片

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第27张图片

stretch(默认值):拉伸以填充容器(但仍要考虑最小宽度/最大宽度)

flex-start / start / self-start:项目放置在交叉轴的起始位置。它们之间的差异微小,与是否遵守 flex-direction 规则或书写模式规则有关。

flex-end / end / self-end:项目放置在交叉轴的结束位置。差异还是很小,与是遵守 flex-direction 规则还是书写模式规则有关。

center:项目在交叉轴上居中对齐

baseline:项目对齐以使它们的基线对齐


安全(safe)和不安全(unsafe)修饰符关键词可以与其余所有关键词结合使用(请注意浏览器支持情况),用于帮助您防止对齐元素导致内容变得不可访问。

justify-content和align-items居中

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第28张图片

现在我们将同时使用justify-content和align-items属性。这将展示主轴和交叉轴之间的区别。

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第29张图片

7.gap

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第30张图片

gap、row-gap和column-gap属性用于控制弹性项目之间的间距。它仅在项目之间应用该间距,而不应用于外边缘上的项目。

这个属性的表现可以被看作是一个最小的间隔,如果间隔更大(因为像justify-content: space-between;这样的属性),那么只有当空间变小时,间隔才会生效。

gap属性不仅适用于flexbox,还适用于grid布局和多列布局。

CSS中的gap属性是row-gap和column-gap的简写,用于指定网格、flex和多列布局中行和列之间的间距(gutters)的大小。

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第31张图片

弹性项目(子元素)的属性

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第32张图片

1.order

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第33张图片

默认情况下,flex项目按照它们在源代码中的顺序进行布局。

然而,order属性可以控制它们在flex容器中的显示顺序。

具有相同order值的项将按照它们在源代码中的顺序进行布局。

可以设置任意整数(正整数、负整数、0),值越小就越排在前面
默认值是 0

2.flex-grow

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第34张图片

flex-grow属性

(如图示例子)在这个例子中,有两行flex项目,第一行的所有项都是相等大小的,它们的flex-grow值也相等;而第二行的中间项的宽度是其他项的两倍,因为它的flex-grow值为2。

flex-grow属性定义了flex项在需要时的扩展能力。它接受一个无单位的值,用作比例。它决定了flex项在flex容器内可用空间中所占的比例

如果所有项目的flex-grow值都设置为1,那么容器中剩余的空间将平均分配给所有子项。如果其中一个子项的值为2,那么该子项将占据其他子项中任意一个的两倍空间(至少会尝试如此)。

负数是无效的。

注意:flex items 扩展后的最终 size 不能超过 max-width\max-height

3.flex-shrink

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第35张图片

flex-shrink属性定义了flex项在需要时的收缩能力。


负数是无效的。

4.flex-basis

 flex-basis 用来设置 flex items 在 main axis 方向上的 base size

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第36张图片

这个属性定义了在 剩余空间分配之前 元素的默认大小。

它可以是一个长度值(例如20%,5rem等)或关键字。

关键字auto(默认)表示“根据我的宽度或高度属性来确定”(这个功能曾经被main-size关键字临时代替,但已被弃用)。

关键字content表示“根据项的内容来确定大小” - 这个关键字目前支持不太好,所以很难测试,并且更难知道它的兄弟关键字max-content、min-content和fit-content的作用。

如果设置为0,额外的空间不会被计算在内。

如果设置为auto,额外的空间将根据其flex-grow值进行分配。参考这个图示。

决定 flex items 最终 base size 的因素,从优先级高到低
 max-width\max-height\min-width\min-height
 flex-basis
 width\height
 内容本身的 size

5.flex

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第37张图片

flex是flex-grow、flex-shrink和flex-basis的简写形式。

第二个和第三个参数(flex-shrink和flex-basis)是可选的。

默认值是  0 1 auto,但如果您使用单个数字值设置它,例如    flex: 5;  ,

那么 flex-basis 将变为 0%,就像设置了   flex-grow: 5; flex-shrink: 1; flex-basis: 0%   一样。

建议您使用这个简写属性而不是设置单独的属性。简写属性会智能地设置其他值。

7.align-self

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第38张图片

图示:align-self属性用于将一个项目相对于flex容器的顶部而不是底部进行定位,这与其他所有项目的位置相反

这允许为单个flex项目覆盖默认对齐方式(或由align-items指定的对齐方式)。

请参阅align-items的解释以了解可用的值。

.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

请注意,float、clear和vertical-align对flex项目没有影响。

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第39张图片

align-self属性允许您调整单个元素的对齐方式。

它具有与align-items相同的属性。

在下面的动画中,父级div具有CSS属性align-items: center和flex-direction: row。

前两个方块循环显示不同的align-self值。

flex布局轻而易举实现页面布局;超详细解析轻松掌握_第40张图片

参考

A Complete Guide to Flexbox | CSS-Tricks - CSS-Tricks

Flexbox - The Ultimate CSS Flex Cheatsheet (with animated diagrams!)

你可能感兴趣的:(前端,css,html)