CSS(四):FLEX 布局

108 阅读7分钟

参考:原文地址

简介

采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。

在这里插入图片描述

容器默认存在两根轴:

  • 水平的主轴(main axis)

  • 垂直的交叉轴(cross axis)。

主轴的开始位置(与边框的交叉点)叫做 main start, 结束位置叫做 main end;

交叉轴的开始位置叫做 cross start, 结束位置叫做 cross end。

项目默认沿主轴排列。

单个项目占据的主轴空间叫做 main size, 占据的交叉轴空间叫做 cross size。

容器属性(container)

flex-direction,主轴方向

flex items 默认都是沿着 main axis(主轴)从 main start 开始往 main end 方向排布

flex-direction 决定了 main axis 的方向,有四个取值:

属性值
row默认值,主轴为水平方向,起点在左端
row-reverse主轴为水平方向,起点在右端
column主轴为垂直方向,起点在上沿
column-reverse主轴为垂直方向,起点在下沿

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

flex-wrap,容器是单行还是多行

决定了 flex container 是单行还是多行

属性值
nowrap默认值,单行
wrap多行
wrap-reverse多行反转

说明:

  • 设置为单行时若所有项目(子)的宽度总和超过容器(父)的宽度,则项目宽度会被等比例压缩;

  • 设置多行时容器的剩余空间不足以容纳项目时就会换行,项目不会倍压缩。

flex-flow = flex-direction + flex-wrap

flex-flow 是 flex-direction 与 flex-wrap 的简写

也就是说,当你使用这个属性的时候,你可以使用上述两个的属性值,例如:flex-flow: row wrap;(水平排列,多行显示)

justify-content,项目在主轴对齐方式

justify-content 决定了 flex item 在 main axis 上的对齐方式 [ˈdʒʌstɪfaɪ]

属性值
flex-start默认值,与 main start 对齐
flex-end与 main end 对齐
center居中
space-between两端对齐主轴的起点与终点,项目之间的间隔都相等
space-around每个项目两侧的间隔相等。所以项目之间的间隔比项目与边框的间隔大一倍
space-evenly项目之间的间隔比和与边框的间隔比相同

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

align-items,单行项目在交叉轴对齐方式

决定单行 flex items 在 cross axis 上的对齐方式

属性值
stretch默认值,如果项目没有设置高度或者宽度(取决于flex-direction),则项目会被拉伸以填满容器
flex-start与 cross start 对齐
flex-end与 cross end 对齐
center居中对齐
baseline项目按照基线对齐。基线可以被认为是文本行中的字母或字符放置的位置。对于有多个基线的元素(比如多行文本),这个值将对齐第一行文本的基线

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

align-content,多行项目在交叉轴对齐方式

决定了多行 flex items 在 cross axis 的对齐方式 用法与 justify-content 相似 一个是横轴。一个控制竖轴。

align-content 属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

属性值
stretch默认值,与 align-items 的 stretch 类似
flex-start与 cross start 对齐
flex-end与 cross end 对齐
center居中对齐
space-between与 justify-content 中类似
space-around同上
space-evently同上

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

flex 项目属性(item)

order,排序

order 属性定义项目的排列顺序。数值越小,排列越靠前,默认为 0。

.item {
  order: <integer>;
}

在这里插入图片描述

align-self,设置单个项目在交叉轴的对齐方式

align-self 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖 align-items 属性。默认值为 auto,表示继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch。

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

align-self 属性有 6 个值,除了 auto,其他都与 align-items 属性完全一致。

在这里插入图片描述

flex-grow,放大比例,默认 0 不放大

flex-grow 属性定义项目的放大比例,默认为 0,即如果存在剩余空间,也不放大。

.item {
  flex-grow: <number>; /* default 0 */
}

在这里插入图片描述

在这里插入图片描述 将剩余空间分为4份,给黄色的3份,给紫色的1份。

每个项目分配空间计算公式:

div1:不放大,即不被分配剩余空间

div2:3 / (3 + 1) * 剩余空间 = 3 / 4 * 剩余空间

div3:1 / (3 + 1) * 剩余空间 = 1 / 4 * 剩余空间

flex-shrink,缩小比例,默认 1,空间不足则缩小

flex-shrink 属性定义了项目的缩小比例,默认为 1,即如果空间不足,该项目将缩小。负值对该属性无效。如果 flex-shrink 值为 0,表示该项目不收缩。

仅在默认宽度之和大于容器的时候才会发生收缩。

当子元素宽度之和大于父元素宽度时,flex-shrink 将会按照一定的比例进行收缩,即将子元素宽度之和与父元素宽度的差值按照子元素 flex-shrink 值来分配给各个子元素,指定各个子元素收缩多少,每个子元素原本宽度减去按比例分配的值,其剩余值为收缩完的实际宽度。

.item {
  flex-shrink: <number>; /* default 1 */
}

flex-shrink 之和大于或等于 1

主轴长度为1000px,子元素溢出空间:(300 + 400 + 500) - 1000 = 200 px。

项目1 占 300px,项目2 占 400px,项目3 占 500px,各个项目的 flex-shrink 值分别为1,2,3,总权重为 300 * 1 + 400 * 2 + 500 * 3 = 2900px,则每个项目的权重分别为:

  • 项目1:(300 * 1) / 2900 = 0.103448275862069
  • 项目2:(400 * 2) / 2900 = 0.2758620689655172
  • 项目3:(500 * 3) / 2900 = 0.5172413793103448

下面,计算每个项目分别缩小的空间:

  • 项目1:200(溢出空间)* 0.103448275862069 = 20.6896551724138 px
  • 项目2:200(溢出空间)* 0.2758620689655172 = 55.17241379310344 px
  • 项目3:200(溢出空间)* 0.5172413793103448 = 103.448275862069 px

效果: 在这里插入图片描述

flex-shrink 小于 1

当所有项目的flex-shrink之和小于1,只收缩溢出空间的一部分。

假设项目1 为0.1,项目2为 0.2,项目3为 0.3,溢出200px,总收缩空间为:200px * (0.1 + 0.2 + 0.3) = 120px

每个项目的权重计算方式是不变的(和上面的一样),每个项目分别缩小:

  • 项目1:120 * 0.1153846153846154 = 13.84615384615385 px
  • 项目2:120 * 0.3076923076923077 = 36.92307692307692 px
  • 项目3:120 * 0.5769230769230769 = 69.23076923076923 px

效果: 在这里插入图片描述

flex-shrink 等于 0

<div class="container">
  <div class="item t1">我是 div 1</div>
  <div class="item t2">我是 div 2</div>
  <div class="item t3">我是 div 3</div>
</div>

<style>
.container {
  display: flex;
}
.t1 { width: 100px }
.t2 { width: 200px }
.t3 { width: 300px }

.item {
  flex-shrink: 0;
  /* 使元素保持原有的宽度,如果不加,上面设置的width可能会在flex布局下失效 */
}
</style>

flex-basis,设置项目占据主轴固定空间

flex-basis 属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

.item {
  flex-basis: <length> | auto; /* default auto */
}

它可以设为跟 width 或 height 属性一样的值(比如 350px),则项目将占据固定空间。

效果如下所示:

在这里插入图片描述

项目 1,无论是把 width 放在 flex-basis 上方还是下方都不起作用了,只要设置了 flex-basis 项目就占据主轴固定空间,width 不起作用。

flex = flex-grow + flex-shrink + flex-basis

flex 属性是 flex-grow、flex-shrink、flex-basis 的简写,默认值为 0 1 auto。后两个属性可选。

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

注意:

  • 该属性的默认值为 0 1 auto(注意顺序),后两个属性可选

  • 该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。

  • 如果需要这三个属性的时候,建议使用 flex,而不是单独的三个分离的属性,因为浏览器会推算相关值

  • flex:1,表示如果有剩余空间,该项目会扩展以填满剩余的空间