Flex+Grid 布局

FlexBox 基础

使用 display: flex 开启 Flex 布局

 

方向 Direction

Direction 定义了主轴的方向,决定项目是水平排列还是垂直排列的。

flex-direction 默认值为 row,即默认以横排列(左右排)

此时,我们的主轴就是从左到右。此时所有的项目(item)会以左到右依次排列。与这条主轴垂直的,即是交叉轴,交叉轴为从上到下排列

 

当 flex-direction 值为 column 时,主轴是垂直的,其排列为从上到下

此时的交叉轴则是打横的,其排列为从左到右

 

主轴对齐 Justify Content

justify-content 管理项目在主轴上的对齐和分布。

主轴值分为两大类

  • 对齐类
  • flex-start(默认): 向起点对齐
  • flex-end: 向终点对齐
  • center: 居中对齐

 

  • 分布类
  • space-between: 两端对齐,中间平分
  • space-around: 项目两侧间距相等,所以项目与项目之间的距离,是项目与边缘的两倍
  • space-evenly: 所有间距完全相等,平均等分相距距离

 

交叉轴对齐 align-item

align-items 管理项目在交叉轴上的对齐方式。

  • stretch(默认):项目被拉伸以填满交叉轴;如果项目没有设置高度时,会被自动拉伸到容器的高度。
  •  
  • flex-start: 向交叉轴的起点对齐
  • flex-end: 向交叉轴的终点对齐。
  • center: 在交叉轴中整体居中。

 

空间分配机制

几个子元素在容器中,有的被拉伸,有的被压缩,但最终尺寸似乎难以预测。

基本认识

Flex 布局除了对项目进行方向性排列的控制外,也会对项目的大小进行管理,如果一个页面中的空间,不足以存下这些项目时,这些项目应该要如何处理?是统一以比例压缩,还是只以某个项目进行压缩,还是进行重新排序等等。相对比如果项目不能完全填充页面中的空间时,又要怎样的方式进行分配空间。

其总体计算可以参考以下图的流程:

 

flex-basis 元素最初定义大小

基准宽度:空间分配的计算起点。元素的“理想”尺寸

也就是元素最初希望的大小,它在设置里有三种值,

基准值是用于参与空间扩大和缩小时,对元素的比例缩放有关系的,谁要的基准值越多,缩放比例也越大。

  • auto :元素最初大小由它的内容所撑开的大小决定(也可以是css控制大小的决定)
  • xxxpx :  指定元素特定的初始空间占用值,如果设置100px,则认为这个元素一开始就是100px大
  • 0: 指这个元素初始大小是0

 

flex-grow 元素扩大比例

扩张因子:当容器有剩余空间时,决定如何“瓜分”这些空间

这是假设如果项目放在页面中后,依然有剩余空间的情况下的设置项。

案例:

  • 容器宽度 600px,空间充足的情况
  • Flex 属性值说明:flex: flex-grow | flex-shrink | flex-basis
  • 子项A: flex: 1 1 0; (基准宽度0, 空间扩充比例为 1, 空间收缩比为 1)
  • 子项B (本身内容占 200px): flex: 2 1 auto;  (基准宽度为自动, 空间扩充比例为 2, 空间收缩比为 1)
  • 子项C: flex 1 1 100px;  (基准宽度100px, 空间扩充比例为 1, 空间收缩比为 1)

1.计算基准宽度,已知【A】定义宽基准为0,【B】定义宽基准为自动,因为自身有内容200px所以基准为200px, 【C】定义固定宽基准为100px

总基准宽 = 0 + 200 + 100 = 300px

 

2.计算剩余空间,目前容器总宽有 600px

剩余空间 = 600px - 300px = 300px

因此当前空间是充足的,所以开始计算 grow 值。

 

3.计算总的 grow 值,【A】定义为 1,【B】定义为 2,【C】定义为1

总Grow = 1 + 2 + 1 = 4

所以

【A】在总的空间中占有比例为 A的分配比例 = 1 / 4 = 0.25

【B】在总的空间中占有比例为B的分配比例 = 2 / 4 = 0.5

【C】在总的空间中占有比例为C的分配比例 = 1 / 4 = 0.25

 

4.计算每个项目额外空间占用的空间位置为:剩余空间按 grow 比例分配

【A】占有: A的占有空间 = 300px * 0.25 = 75px

【B】占有: B的占有空间 = 300px * 0.5 = 150px

【C】占有: C的占有空间 = 300px * 0.25 = 75px

 

5.计算最终的每个项目的占用空间大小:申请的基准空间 + 额外提供的空间

【A】占有: A最终占有空间 = 0 + 75px = 75px

【B】占有: B最终占有空间 = 200 + 150px = 350px

【C】占有: C最终占有空间 = 100 + 75px = 175px

 

flex-shrink 元素缩小比例

收缩因子:当容器空间不足时,决定如何“分摊”超出的部分。

这是假设如果项目放在页面中后,页面没有更多的空间来存放这些项目时的情况。

 

案例:

  • 容器宽度 400px,空间不足的情况
  • Flex 属性值说明:flex: flex-grow | flex-shrink | flex-basis
  • 子项A : flex 1 1 300px (A 要求至少占有300px,如果空间不足按比例1来收缩)
  • 子项B : flex 1 2 200px (B 要求至少占有200px,如果空间不足按比例2来收缩)

1.计算总的基准宽度:基准宽度 = 300px + 200px = 500px

 

2.计算剩余的基准宽度:基准宽度 = 400px - 500px = -100px ,显然此时是空间不足以分配了。

因此当前空间是不足的,所以开始计算 shrink 值。

 

3.计算收缩比例分配收缩量

【A】的权重值为:权重 = 300px * 1 = 300

【B】的权重值为:权重 = 200px * 2 = 400

总权重值为: 300 + 400 = 700

【A】的压缩象素为: 300 / 700 * 100% = 42.86px

【B】的压缩象素为:400 / 700 * 100% = 57.14px

注意:实际上就是把这多出的空间,用它们自身的基准和权重在总体项目的比例来分配出需要收缩的量。

 

4.最总项目的实际宽度计算为

【A】的最终宽度为:300px - 42.86px = 257.14px

【A】的最终宽度为:200px - 57.14px = 142.86px

 

flex-wrap 是否换行

对于项目在一行中时,容器的宽度会直接影响项目的大小,如果容器的空间不足以容纳项目时,项目就会被无限制的压缩,甚至超出容器边界。

对于这一问题,flex-wrap 是用于控制项目当出现压缩到要超出容器时,是否换行的属性,默认值是 no warp 不换行。

  • no wrap 绝不换舻,强行挤在同一行
  • wrap 空间不足时,自动将项目移到新行
  • wrap-reverse 与 wrap 类似,但新行会出现在已有行的上方

wrap换行规则。

wrap-reverse 时的规则

 

align-content 换行间距

对于  flex-wrap 中设置的换行情况,在项目换行时,align-items 是只对一行项目的排列方式,对于换行的排列是不负责的,所以需要使用 align-content 来做换行的排列。

有如下几个属性值:

  • flex-start: 队列紧贴最上方,从上往下堆排
  • flex-end:队列紧贴最下方,从下往上堆排
  • center:队列整体居中,从上往下堆排,但保持整体居中
  • space-between:队列头和尾会紧贴边缘,多出的空间距离给到中间的行平分
  • space-around:把队列中的每一行都设置同等的空间距离,所以中间行间距会是边缘行距边缘间距的2倍
  • stretch:如果每个项目都不设置高度的情况下,会使队列中所有项目高度拉伸填满所有空间

 

 

align-self 单元素设置

align-self 是用于控制单个元素的独特对齐方式的属性。

对于我们使用的 align-items 属性,它只会把结构中的所有元素都以一种统一的方式进行排列,但是如果我想单独对某一个元素进行另类的对齐,就需要使用 align-self了,当设置了align-self 属性值后,align-items 属性会失效。

值与 align-items 一样

  • auto: 跟父元素的 align-items 的设置相同(就是align-self不起作用)
  • flex-start: 在交叉轴的起点对齐
  • flex-end: 在交叉轴的终点对齐
  • center: 在交叉轴上居中对齐
  • baseline: 基于项目的第一行文字的基线对齐,对于文字对不齐的比较有用
  • stretch: 若元素没有设置高度或为 auto 时,会拉伸整个容器高度。

示例效果:

 

order 项目排序

它允许我们仅通过css来调整Flex子项的视觉排列顺序,无需改动html源码

  • 所有子项的order默认都为 0
  • 浏览器根据 order 值的大小排序,数值越小,排列越靠前
  • order 值可以是负数

 

基础三栏布局

1.构建三栏布局

  <div class="container">
    <div class="left">左边栏</div>
    <div class="right">
      <div class="top">上顶层</div>
      <div class="middle">中间内容层</div>
    </div>
  </div>

 

 

 

2.使用flex布局定义其空间:

.container {
  // 外层设置为 flex 布局
  display: flex;
  // 使用从左到右排
  justify-content: flex-start;
  // 设置从上到下排,没有设置高度的会自动填充高度
  align-items: stretch;
  padding: 10px;
  .left {
    // 设置左边固定大小为 300 不允许缩
    max-width: 300px;
    // 设置左边不进行缩进
    flex-shrink: 0;
  }
  .right {
    // 设置右边为扩张层
    flex-grow: 1;
    // 设置右边扩张最大只能到 1000px
    max-width: 1000px;
    // 设置使其子元素也为 flex
    display: flex;
    // 设置顶部和内容为上下排列
    flex-direction: column;
    // 设置从上往下排,中间没空距
    justify-content: flex-start;
    .top {
      height: 100px;
    }
    .middle {
      flex-grow: 1;
    }
  }

}

 

Grid 布局

rf 单位说明

在css中,有多种单位体系,最常用的单位分为三类

  • 固定单位
  • px、em、rem
    • 可以提供可预测的,绝对的尺寸
    • 适用于固定侧边栏、导航栏等场景
  • 相对单位
  • %、vw、vh
    • 相对于容器或视口的尺寸
    • 善于创建与父容器紧密关联的布局
  • 自动单位
  • auto
    • 由内容决定尺寸
    • 遵循内容优先原则

在Grid 布局中,有一个专用的单为 fr

  • Grid 面局最具特色的单位
  • 1fr 代表在网格中“可用空间”的一份

图示fr的含意:

1.若在一个容器中,有其它单位占位的,则先扣除其它单位的空间后,再计算,剩下的就是fr

 

2.若在一个容器中设置2个以上的方格,每个方格各有自己的fr,则会按比例分配:

 

3.当在一个容器中,有其它的单位占位,也设置了方格之间的间距(gap)时,会先扣除其它单位的占位,和间距后再计算方格空间比例:这样的好处是,当可变量(如间距改变后),不需要人工重新计算每个方格的大小。

 

grid-template-columns 定义方格列

Grid 的思维是把一个页面,当作一个大方格,我们的工作是,需要在这个大方格当中,切分多少行,切分多少列,然后我们的内容就放在这些行和列构成的格子中。

要定义多少列,我们可以使用 grid-template-columns 定义。它可以接收一个数组,数组多少个成员就是定义多少列。

示例:

div{
  // 定义布局为方格布局
  display: grid;
  /*
  设置列数
  5列,第一列200px,最后一列200px
  剩下的切成4份,第二列占一份,第三列占一份,第四列占2份
  
   */
  grid-template-columns: 100px 1fr 1fr 2fr 200px;
}

 

grid-template-rows 定义方格行

通过定义方格列,可以把一个页面分成多少列,再通过定义方格行,形成一个个方格大小

  /*
  定义三个方格行,第一行20px,第二行30px,第三行占有剩下所有空间
   */
  grid-template-rows: 20px 30px auto;

 

gap 方格间距控制

我们还可以设置每个方格的间距,方格的间距会占用页面空间,所以fr单位可以帮我们扣掉方格间距后再计算格子大小:

div{
  // 定义布局为方格布局
  display: grid;
  /*
  设置列数
  5列,第一列200px,最后一列200px
  剩下的切成4份,第二列占一份,第三列占一份,第四列占2份

   */
  grid-template-columns: 100px 1fr 1fr 2fr 200px;

  /*
  定义三个方格行,第一行20px,第二行30px,第三行占有剩下所有空间
   */
  grid-template-rows: 20px 30px auto;
  
  /*
  设置方格间距为10px,本例中设置了5列,则有4列会有间距,共占40px
   */
  gap: 10px;
}

间距家族有三个属性:

  • column-gap : 设置列与列之间的间距
  • row-gap : 设置行与行之间的间距
  • gap : 同时设置行和列的间距
    • 格式 gap: 行间距 列间距
    • 格式 gap: 行列间距

 

 

repeat 函数创建列

grid-template-columns 中创建多少列,我们就要传入多少个参数值,那如果列数多的情况下,我们就需要传入好多参数,repeat 可以帮我们批量创建:

  // 设置10列,每列占用1份空间,即每列 10%总页面大小
  grid-template-columns: repeat(10, 1fr);

 

精确布局

定义列的开始位置和行开始位置

通俗的讲就是,定义我们的内容,应该是从第几行和第几列开始放置(在一个片网格中,不一定内容是从第一行第一列的格子开始的)

  // 定义内容会存放于页面中第一列到第三列之间
  grid-column-start: 1;
  grid-column-end: 3;
  
  // 定义内容会存放于页面中第二列到第四列之间
  grid-row-start: 2;
  grid-row-end: 4;

我们可以使用简单写法:

  // 定义内容会存放于页面中第一格线到第三格线之间
  grid-column: 1 / 3;

  // 定义内容会存放于页面中第二格线到第四格线之间
  grid-row: 2 / 4;

 

若我们不知道页面中被划分了多少个格子,我们可以使用 负数 定义,-1表示倒数第一行,-2表示倒数第二行

  // 定义内容会存放于页面中第一格线到倒数第一格线
  grid-column: 1 / -1;

  // 定义内容会存放于页面中第二格线到倒数第二格线
  grid-row: 2 / -2;

 

案例:通过下面的颜色的格子区分,我们可以看出有三个item,每个item占有一定的位置的格子

通过分析上面的颜色,

  • item1
    • 占据的列位置是 列线1~列线5
    • 占据的行位置是 行线1~行线3
  • item2
    • 占据的列位置是 列线5~列线8(或-1)
    • 占据的行位置是 行线1~行线6(或-1)
  • item3
    • 占据的列位置是 列线1~列线5
    • 占据的行位置是 行线3~行线5

因此我们可以在css中这样定义:

item1 {
  grid-column: 1 / 5;
  grid-row: 1 / 3;
  background-color: pink;
}

item2 {
  grid-column: 5 / -1;
  grid-row: 1 / -1;
  background-color: greenyellow;
}

item3 {
  grid-column: 1 / 5;
  grid-row: 3 / 5;
  background-color: orange;
}

 

span 动态占用网格

从上面的章节我们可以简单的通过定义开始的列线,和结尾的列线,来定义一块内容应占有页面中多少网格。

但是有时我们不想关心内容块要从那里占到那里,而是希望它总是要用多少个网格

比如我们的 item1  不关心占用网格线A~网格线B,只关心 item1 从网格线A开始,需要占用 3个网格。

我们可以使用上面的方式来定义

// 从网格线 1 占到 网格线 4
grid-column: 1 / 4;

但是我们可以使用 span 关键字来告诉它,我们只关心内容块占有多少块,而不是占有多少格到多少格

// 从网格线1开始,必须占有3个格子空间
grid-column: 1 / span 3;

利用媒体查询,我们还能运态切换内容块的占用情况:

item1 {
  // 从网格线1开始,必须占有3个格子空间
  grid-column: 1 / span 3;
}

// 当屏小于 768px 时,使 item 开始占有4个格子空间
@media (min-width: 768px) {
  item1 {
    grid-column: 1 / span 4;
  }
}

 

在某些情况下,我们还能不声明内容块从那条网格线开始,而是让浏览器自动分配摆方位置:

// 不要管我从那条格线开始放,浏览器看着放,反正给我4列3行的空间就行
item1 {
  grid-column: span 4;
  grid-row: span 3;
  background-color: pink;
}

 

命名网格布局

在html中定义好所有结构的名称,我们就可以利用这些名称来做统一化布局了,甚至在小屏下使用媒体查询方式来重新排板布局

我们来看一下css代码:

// 在一个容器中包含 header, nav, content, aside, footer 几个区域
.container {
  display: grid;
  // 声明这些元素统一化使用网格布局
  grid-template-areas: 
    "header"
    "nav"
    "content"
    "aside"
    "footer";
  
  // 以上这些元素统一占有一列份额的空间
  grid-template-columns: 1fr;
  // 格子相距 10px
  gap: 10px;
}

 

当页面太小时,我们还能通过媒体查询来改变它们的布局

@media (min-width: 768px) {
  container {
    grid-template-areas:
    "header header" // 这一二列依然header全占
    "nav content" // 这一列放 nav 第二列放 content
    "aside aside" // 这一二列依然 aside 全占
    "footer footer"; // 这一二列依然 footer 全占
  }
  // 以上的两列的空间占用分别是 200px 和 1fr
  grid-template-columns: 200px 1fr;
}

 

容器级对齐

所谓的容器级对齐,是指整门页面中的所有网格之间的对齐。

容器级对齐属性与Flex类似

  • justify-content: 控制网格在行轴上的对齐
  • align-content: 控制网格在列轴上的对齐

属性值与 Flex 也一样:

  • start: 网格在容器的起始位置对齐
  • end: 网格在容器的结束位置对齐
  • center: 网格在容器中居中
  • space-around: 轨道均匀分布,首尾距边缘为轨道间距的一半
  • space-between: 轨道均匀分布,首尾轨道紧贴容器边缘
  • space-evenly: 完全均匀分布

 

单元格内对齐

对于每个网格内,也可以做对齐,单元格对齐有两种定义

  • 容器统一定义
    • justify-items: 控制所有项目在各自单元格内的水平对齐
    • align-items: 控制所有项目在各自单元格内的垂直对齐
  • 项目独立定义:
    • justify-self: 覆盖 justify-items 属性,控制单个项目的水平对齐
    • align-self: 覆盖 align-items 属性,控制单个项目的垂直对齐

属性值:

  • start: 项目对齐到单元格的起始边缘
  • end: 项目对齐到单元格的结束边缘
  • center: 项目在单元格内居中
  • stretvh(默认值): 项目拉伸填满整个单元格空间

 

响应式网格布局

minmax() 函数:为轨道设定弹性边界

在响应式面局中,我们需要让元素既能灵活伸缩,又不会在极端情况下导致内容失真

  • min: 轨道的最小尺寸,保证内容的可读性
  • max: 轨道的最大尺寸,通常使用 1fr 等弹性单位

案例:在设定的三列中,使两列弹性的控制其网格大小

.container {
  display: grid;
  // 创建三列网格,第一列最小不小于200px 最大占一份额空间
  // 第二列固定 500px 空间
  // 第三列最大 1份额空间,最小100px空间
  grid-template-columns: minmax(200px, 1fr) 500px minmax(100px, 1fr);
}

 

auto-fit vs auto-fill : 两种自动布局模式

 

这两个关键字都会不断的创建列,直到空间用光为止,但处理“剩余空间”的方式不同

auto-fill:保守填充

  • 1.用尽可能多的轨道填充容器
  • 2.保留空轨道作为空白区域
  • 3.适合希望保持轨道尺寸严格的场景

案例:

  • 总空间大小 900px
  • 轨道最小宽度 200px, 最大 1fr
  • 实际网格项 2 个

对于 fill 来说,它会认为,每个网格项最小200px空间,所以:

900px / 200px = 4.5  会给页面分成4个网格,但还有0.5个网格的空间,会平均分给这4个网格,

最终每个网格不小为 200px + 100 / 4 = 225px

当有两个网格项时,只会填充这两个网格的空间,留空剩下两个网格的空间,如下图:

auto-fit: 适应填满

  • 1.创建轨道后,折叠空轨道
  • 2.让现有网格项拉伸填满容器
  • 3.适合构建自适应卡片风格

案例:

  • 总空间大小 900px
  • 轨道最小宽度 200px, 最大 1fr
  • 实际网格项 2 个

对于 fit 来说,它会认为,每个网格项最小200px空间,所以:

900px / 200px = 4.5  会给页面分成4个网格,每个网格本应 225px,

但是因为只需要两个网格占用空间,会把剩余的两个空白网格空间调为0px以给其它网格使用:

 

如果您喜欢本站,点击这儿不花一分钱捐赠本站

这些信息可能会帮助到你: 下载帮助 | 报毒说明 | 进站必看

修改版本安卓软件,加群提示为修改者自留,非本站信息,注意鉴别

THE END
分享
二维码
打赏
海报
Flex+Grid 布局
FlexBox 基础 使用 display: flex 开启 Flex 布局   方向 Direction Direction 定义了主轴的方向,决定项目是水平排列还是垂直排列的。 flex-direction 默认值为 row,即默认以横排列(……
<<上一篇
下一篇>>