最近在杭州溜达,无事可做。想着就把我学过的知识回忆起来,写点东西把。文章的出发点是一张图,因为PS一张图还挺花时间的,那么既然图都P了那就写个文章把。
flex弹性布局
一、要理解弹性布局首先得从CSS布局说起,简单的梳理一下。
就我目前已知和常用的布局有4种:标准流、定位流、浮动流、弹性流、网络流。
我理解的CSS布局就是按照某种规则来放盒子。 详细了解MDN-CSS布局
- flex布局属于弹性流。
二、布局关浏览器什么事?浏览器渲染的大致过程:
1.根据HTML结构构建DOM树;
2.根据CSS规则构建CSS样式树;
3.遍历DOM树,适配其CSS样式合并生成 render 渲染树。
4.layout布局阶段,根据render树中的节点和CSS规则,计算出内部有规则自身有位置的盒子。并呈现在页面。注:有的盒子是标准流的,有些是弹性流的等等。总之今天要讲的flex在浏览器渲染过程中,大致处于这个工作流程。
5.painting阶段,把和布局无关的东西画上去。比如文本的颜色,背景的颜色。结合5呈现出来。
6.compose阶段,类似PS的图层顺序和每个图层所用的滤镜效果的最终呈现。(一个属性激起联想:z-index:9999)
题外话:4过程和回流有关,5过程和重绘有关系,6我也不知道应该是重绘把,没影响布局。
三、进入正题,到底什么是flex弹性布局?
(1)flex概念
给一个元素设置 display:flex 时,那么这个盒子里的项目就会依照 flex 规则来布局,而这个元素叫做容器(container),容器里的其他元素就是项目(item)。
<div class='container' style='display:flex'>
<span class='item'></span>
</div>
(2)对于一个 container 有几个相当重要概念
对于每一个容器都有着这些重要的概念,看懂它们有助于理解你对flex布局的理解。
- main axis 主轴
main size主轴尺寸(宽度或者高度)main start主轴起始的位置(上下左右都可以)main end主轴结束的位置(上下左右都可以)
- cross axis 交叉轴
cross size交叉轴尺寸 (宽度或者高度)cross start交叉轴起始的位置(上下左右都可以)cross end交叉轴结束的位置(上下左右都可以)
对于容器(container)里的项目(item)而言,项目们就是根据这些轴和尺寸进行一定规则的排列。而这些规则也就构成了flex弹性布局与其它布局不一样的地方。
- 因此
main axiscross axis等等 这些都是可以控制的。
(3)设置容器的属性,实际上就是对 main axis、main start... cross axis... 的操作和运用
1.flex-direction设置主轴的方向
主轴上的元素默认是从左到右排列的。
也就是 main start 默认从左起,main end 到右为止。
因此如何有代码,元素会这样呈现。
// 默认没有设置 flex-direction 属性。
<div class='container' style='display:flex'>
<span class='item'></span>
</div>
元素沿着主轴的方向(左起->右止)排列。
1.1我们知道容器的flex-direction属性可以控制主轴的方向,也就是说 main axis 也可以从右到左,或者从上到下... 来一起对比看看4种情况。
如果设置成 column 或者 column-reverse 其实就是和交叉轴互换角色。
2.flex-wrap空间不足时是否换行
3.flex-direction和flex-wrap可以可以简写属性。flex-flow
flex-flow: | flex-direction | 空格 | flex-wrap |
默认值flex-flow : row nowrap 即 main axis 从左到右,不换行。
4.容器的另外两个重要属性 justify-content 和 algin-items 它们有着类似的属性值
有没有人好奇为什么是 justify-content ? 而不是 justify-items?
为什么 flex 容器有 algin-items属性,没有justify-content?
- flex布局中 justify-items 是被忽略的。为什么?我认为在flex中也和grid一样,其实也有列线和行线,只是不能单独设置容器内项目的justify-self,进而无法设置justify-items
- 在algin-items中,它设置元素在其块上的对齐关系,也就是说在flex元素的交叉轴方向上,可以设置algin-self属性,从而可以设置algin-items
- justify-content,它可以定义分配顺着弹性容器主轴(或者网格行轴) 的元素之间及其周围的空间。这个属性在grid布局中也是通用的。
- 由于flex容器可以设置
direction也就将主轴和交叉轴的角色互换,所以有些属性在设置direction后会跟着变化。如果在默认的主轴方向上可以设置 justify-self 其实是多此一举,弹性布局的初衷便是分配在主轴上的元素顺着弹性容器主轴(或者网格行轴) 的元素之间及其周围的空间。而不是要分配每个项目在自己的行轴上的对齐关系。
总结:justify-items 和 justify-content 的区别
justify-items – 沿着行轴对齐网格项内的内容
justify-content – 此属性沿着行轴对齐网格
algin-items和algin-content又是怎么样的呢?
刚刚说了在algin-items中,它设置元素在其块上的对齐关系,也就是说在flex元素的交叉轴方向上,可以设置algin-self属性,从而可以设置algin-items,这个属性在grid上也是一样的,在flex容器中设置不会像justify-content那样被忽略。
同时 algin-content 一样是可用的。它的center属性指的是 cross axis cross strat 到cross end 中间那个距离。另外 algin-content 只有一行内容的时候无效,因此此时这一行就是内容的全部。这个部分暂时不展开描述。
5.其余容器属性
- row-gap 设置行间距
- column-gap 设置列间距
- gap:row-gap | column-gap 简写方法
(4)用于item项目自身的属性就是设置元素在其所在块里main axis、main start... cross axis... 的操作和运用
- align-self 设置项目自身在交叉轴方向上的的排列方式
1. flex-grow 项目所在行空间足够时的放大系数
如果遇到换行的情况,那么分母要重新计算。所以就算一样的值,在不同行可能大小是不同的。
2. flex-shrink 项目所在行空间不足时的缩小系数
3. flex-basis 设置当容器宽度足够分配时候的基本值。宽度无法超出容器的宽度。
对于这个属性,我用得不多还没有深入研究。
另一个值的注意的点:flex-basis的值不为auto的时候,它设置的宽度的优先级 > width
- flex:flex-grow | flex-shrink | flex-basis 简写属性。
4. algin-self 和 justify-self(不起作用) 上面已经分析过了就不赘述了~
文章全部自己一手一手码的,主要参考的是我以前学习的笔记和MDN上解释。在杭州的一天过去了。疫情之下,经历着有点难忘的人生一程。