flex弹性布局
flex 弹性布局
认识 flexbox
- Flexbox 翻译为弹性盒子:
- 弹性盒子是一种用于按行或按列布局元素的一维布局方法 ;
- 元素可以膨胀以填充额外的空间, 收缩以适应更小的空间;
- 通常我们使用 Flexbox 来进行布局的方案称之为 flex 布局(flex layout);
- flex 布局是目前 web 开发中使用最多的布局方案:
- flex 布局(Flexible 布局,弹性布局);
- 目前特别在移动端可以说已经完全普及;
- 在 PC 端也几乎已经完全普及和使用, 只有非常少数的网站依然在用浮动来布局
与传统布局的对比
传统布局
- 兼容性好
- 布局繁琐
- 局限性,不能在移动端很好的布局
flex 弹性布局
- 操作方便,布局极为简单,移动端应用很广泛
- PC 端浏览器支持情况较差
- IE 11 或更低版本,不支持或仅部分支持
建议:
- 如果是 PC 端页面布局,我们还是传统布局。
- 如果是移动端或者不考虑兼容性问题的 PC 端页面布局,我们还是使用 flex 弹性布局
flex 布局初体验
1 | <head> |
flex 布局原理
flex 是 flexible Box 的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为 flex 布局。
当我们为父盒子设为 flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效。
伸缩布局 = 弹性布局 = 伸缩盒布局 = 弹性盒布局 = flex 布局
采用 Flex 布局的元素,称为 Flex 伸缩容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为 Flex 伸缩项(flex item),简称”项目”。
- 体验中 div 就是 flex 父容器。
- 体验中 span 就是 子容器 ,也叫 flex 项目
- 子容器可以横向排列也可以纵向排列
总结 flex 布局原理:
- 就是通过给父盒子添加 flex 属性,来控制子盒子的位置和排列方式
flex 布局父元素常见属性
以下由 6 个属性是对父元素设置的
flex-direction:设置主轴的方向
justify-content:设置主轴上的子元素排列方式
flex-wrap:设置子元素是否换行
align-content:设置侧轴上的子元素的排列方式(多行)
align-items:设置侧轴上的子元素排列方式(单行)
flex-flow:复合属性,相当于同时设置了 flex-direction 和 flex-wrap
flex-direction 主轴方向
- 01 主轴与侧轴
- 在 flex 布局中,是分为主轴和侧轴两个方向,同样的叫法有 : 行和列、x 轴和 y 轴
- 默认主轴方向就是 x 轴方向,水平向右
- 默认侧轴方向就是 y 轴方向,水平向下
- 在 flex 布局中,是分为主轴和侧轴两个方向,同样的叫法有 : 行和列、x 轴和 y 轴
- 02 属性值
- flex-direction 属性决定主轴的方向(即项目的排列方向)
- 注意: 主轴和侧轴是会变化的,就看 flex-direction 设置谁为主轴,剩下的就是侧轴。而我们的子元素是跟着主轴来排列的
- 在伸缩布局中,默认情况下水平方向是主轴,默认情况下主轴的起点在伸缩容器的最左边,默认情况下所有的伸缩项都是从主轴的起点开始排版的, 但是我们也可以通过属性来修改主轴的起点的位置
- flex-direction: 用于修改主轴起点的位置
- row: 起点在伸缩容器的最左边,终点在伸缩容器的最右边.从左至右的排版,默认的取值
- row-reverse: 起点在伸缩容器的最右边,终点在伸缩容器的最左边,从右至左的排版
- column: 起点在伸缩容器的最顶部,终点在伸缩容器的最底部,从上至下的排版
- 注意点:在伸缩布局中主轴和侧轴永远都是十字交叉的,只要主轴的方向发生了变化,侧轴也会发生变化
- column-reverse: 起点在伸缩容器的最底部,终点在伸缩容器的最顶部,从下至上的排版
1 | flex-direction: row; /* 伸缩项从左到右排列 默认项 */ |
justify-content 主轴元素排列
- justify-content 属性定义了项目在主轴上的对齐方式
- 注意: 使用这个属性之前一定要确定好主轴是哪个
1 | flex-direction: row; /* 主轴为 x 轴*/ |
flex-wrap 子元素换行
- 默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap 属性定义,flex 布局中默认是不换行的。
1 | /* |
align-items 侧轴元素排列(单行)
- 该属性是控制子项在侧轴(默认是 y 轴)上的排列方式 在子项为单项(单行)的时候使用
1 | /* 告诉浏览器排版好的伸缩项需要和侧轴的起点对齐*/ |
align-content 侧轴元素排列(多行)
- 设置子项在侧轴上的排列方式,并且只能用于子项出现 换行 的情况(多行),在单行下是没有效果的。
1 | /* |
align-content 和 align-items 区别
- align-items 适用于单行情况下, 只有上对齐、下对齐、居中和 拉伸
- align-content 适应于换行(多行)的情况下(单行情况下无效), 可以设置 上对齐、 下对齐、居中、拉伸以及平均分配剩余空间等属性值。
- 总结: 就是单行找 align-items 多行找 align-content
flex-flow 复合属性
- flex-flow 属性是 flex-direction 和 flex-wrap 属性的复合属性
1 | flex-flow: row wrap; |
- flex-direction:设置主轴的方向
- flex-wrap:设置子元素是否换行
- flex-flow:复合属性,相当于同时设置了 flex-direction 和 flex-wrap
flex 布局子项常见属性
- flex 子项目占的份数
- align-self 控制子项自己在侧轴的排列方式
- order 属性定义子项的排列顺序(前后顺序)
flex 属性
- flex 属性定义子项目分配剩余空间,用 flex 来表示占多少份数。
1 | .item { |
align-self 子项在侧轴的排列
- align-self 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖 align-items 属性。
- 默认值为 auto,表示继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch。
1 | span:nth-child(2) { |
1 | /* 如果在伸缩容器中通过 align-items:来控制伸缩项的对齐方式,是一次性控制所有伸缩项的对齐方式,如果想单独的控制某一个伸缩项在侧轴上的对齐方式,那么需要将控制对齐方式的属性写到伸缩项中 */ |
order 定义项目的排列顺序
- 数值越小,排列越靠前,默认为 0。属于伸缩项的属性
- 注意:和 z-index 不一样。
1 | /* |
flex-grow 扩充属性
在伸缩项中有一个 flex-grow 属性,用于控制当所有伸缩项的宽度总和小于伸缩容器宽度的时候如何扩充自己,以便于所有伸缩项宽度的总和能够填满整个伸缩容器
默认情况下 flex-grow 的取值是 0,表示我们设置的宽度是多少就按照多少来显示,不进行任何的扩充
注意点:
- 只有当所有伸缩项的宽度总和小于伸缩容器宽度的时候, flex-grow 这个属性才有效
flex-grow 扩充的公式
- 1 利用伸缩容器宽度 – 所有伸缩项的总宽度 = 剩余空间
- 600 - 300 = 300
- 2 利用剩余空间 / 所有需要扩充份数的总和 = 每一份的大小
- 300 / (1 + 4 + 8)= 23.07
- 3 利用当前伸缩项的宽度+需要的份数的宽度
- 第一个伸缩项 =100 + (1 * 23.07) = 123.07
- 第二个伸缩项 =100 + (4 * 23.07) = 192.28
- 第三个伸缩项 =100 + (8* 23.07) = 284.56
- 1 利用伸缩容器宽度 – 所有伸缩项的总宽度 = 剩余空间
1 | flex-grow: 1; |
flex-shrink 缩小属性
在伸缩项中有一个 flex-shrink 属性,用于控制当所有伸缩项的宽度总和大于伸缩容器宽度的时候如何缩小自己,以便于所有伸缩项宽度的总和能够填满整个伸缩容器
默认情况下 flex-shrink 的取值是 1,表示当所有伸缩项宽度的总和大于伸缩容器宽度的时候等比缩小自己
注意点:
- 只有当所有伸缩项的宽度总和大于伸缩容器宽度的时候, lex-shrink 这个属性才有效
flex-shrink 扩充的公式
- 1 利用所有伸缩项的宽度总和 – 伸缩容器宽度 = 溢出的宽度
- 900- 600 = 300
- 2 计算权重值
- 利用每一个伸缩项需要的份数 * 当前伸缩项的宽度然后再相加, 1 * 300 + 4 _ 300 + 8_ 300 = 3900
- 3 计算每个伸缩项需要缩小的范围
- 溢出的宽度 * 当前伸缩项的宽度 * 当前伸缩项需要的份数 / 权重值 300 * 300 *1/3900 = 23.07
- 第一个伸缩项宽度 = 300 - 23.07 = 276.9 300 _ 300_ 4/3900 = 92.3
- 第二个伸缩项宽度 = 300 - 92.3 = 207.6
- 1 利用所有伸缩项的宽度总和 – 伸缩容器宽度 = 溢出的宽度
1 | flex-shrink: 1; |
- 注意点:
- 1 如果没有指定 flex-grow 属性,或者 flex-grow 的值是 0,那么当前的伸缩项不会被扩充
- 2 如果 flex-shrink 的值是 0,那么当前的伸缩项不会被缩小
- 3 注意点
- 前面所写的注释都是说宽度扩充或者宽度缩小,但是这种说法是不严谨的也有可能扩充和缩小的是高度,到底是宽度还是高度是由主轴决定的, 扩充和缩小的是主轴方向上的值
- 也就是说如果主轴是水平方向的,那么扩充和缩小的就是宽度, 也就是说如果主轴是垂直方向的,那么扩充和缩小的就是高度
flex-basis 设置宽度
- 1 在伸缩布局中可以通过 flex-basis 属性设置伸缩项的宽度
- 注意点: flex-basis 只有在伸缩布局中才有效
- 2 在伸缩布局中如果通过 flex-basis 设置了宽度,那么再通过 width 设置宽度就会无效, 也就是说 flex-basis 的优先级要高于 width 的优先级
- 3 在伸缩布局中如果同时通过 flex-basis 和 width 设置了宽度,而且一个设置的是 auto,一个设置的是具体的值,那么会按照具体的值来显示
1 | flex-basis: 100px; /*同时设置 width 和 flex-basis,会以 flex-basis 为准*/ |
伸缩项属性连写
1 | /* flex:扩充缩小宽度; */ |
携程网案例
技术选型
- 方案:我们采取单独制作移动页面方案
- 技术:布局采取 flex 布局
设置视口标签以及引入初始化样式
1 | <meta |
- 常用初始化样式
1 | body { |
- 常见模块命名
- 常见 flex 布局思路
- 背景线性渐变
1 | /* background: linear-gradient(起始方向, 颜色1, 颜色2, ...); */ |
- 背景渐变必须添加浏览器私有前缀
- 起始方向可以是: 方位名词 或者 度数 , 如果省略默认就是 top
- 感谢你赐予我前进的力量