css3新增-网格Grid布局

目录

flex弹性布局

flex布局

flex适合一维布局,在进行二维布局时 => 布局当多行,最后一行数量与前面行数不一致会出现展示问题,如下:

开发者期待的结果是每行展示4个,若是不足4个左对齐。

显然这种情况需要单独处理 如最初就判断元素数量若是%4不为0添加空元素不齐等方式。

但是使用Gird则会轻松解决如上问题。

Gird布局

gird /ɡəːd /(该的 )布局又称网格布局,是将一个容器划分为一个个单元格。

开启网格布局
css 复制代码
/* 给父元素设置display: grid | inline-grid;即可开启网格布局*/
display: grid; /*开启块级grid网格布局*/
display:inline-grid; /* 开启内联级的网格布局 */

当开启网格布局之后,以display: grid;为例

  • 父元素成为会成为一个块级网格容器,;这意味着它会像普通的块级元素一样,独占一行宽度若不设置默认会与父元素同宽

  • 子元素被称为 网格项,它们已经脱离了常规的文档流格式上下文,进入了网格格式化上下文;

    它们的行为由网格布局控制。

    举例说明

    javascript 复制代码
    <style>
      .box{
        width: 800px;
        min-height: 200px;
        border: 1px solid #000;
        /* 开始网格布局 */
        display: grid;
      }
      .box div{
        background-color: aqua;
        border-radius: 10px;
      }
    </style>
    html 复制代码
    <div class="box">
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>5</div>
      <div>6</div>
      <div>7</div>
      <div>8</div>
      <div>9</div>
    </div>

如上: 子元素没有设置宽高 默认填充整个单元格;

通过上述例子可以看到 当开启网格布局之后

  • 默认 列数/列宽:只有1列 该列宽度为父元素宽度 => gird-template-columns: 1fr;
  • 默认 行数/行高:行数 = 元素个数 / 列数 有余数+1 / 行高 = 父元素高度/ 行数;
  • 默认 子元素宽高: 每个子元素会占据一个网格单元格, 若是子元素没有设置宽高则默认与单元格同宽同高 => align-content: stretch; justify-content: strecth; 修改这两个属性后 子元素就会由内容撑开宽高了。
定义网格中的行和列
  • 定义网格的行结构 和 列结构

    css 复制代码
    grid-template-columns:定义网格的列结构和每列的宽度;
    css 复制代码
    grid-template-rows:定义网格的行结构和每行的宽度;

其强大之处在于它的属性值是非常灵活的

这两个属性的语法完全相同,只是方向不同,在此使用columns进行展示。

长度值

若是属性值为长度值,单位可以是px\rem\em等单位

javascript 复制代码
grid-template-columns: 150px 150px 150px 150px;

上述代码表示将网格分为4列,每列的宽度为150px

javascript 复制代码
grid-template-columns: 200px 100px 300px;

上述代码表示将网格分为3列,宽度分别为200px 100px 300px;

百分比值

属性的值也可以是百分比,表示按比例分配父元素的宽度

javascript 复制代码
grid-template-columns: 25% 50% 25%;

上述代码表示将网格分为3列 第二列的宽度是第一列和第三列的2倍;

新单位fr

使用百分比可以按照比例分配,但是若是列过多需要计算值并且每增加/减少一列都需要重新计算 => 不灵活;

fr是Grid 布局中独有的单位,代表"剩余空间"的等分份额。它解决了百分比和固定值布局不灵活的问题。

javascript 复制代码
grid-template-columns: 1fr 1fr 1fr 1fr;

上述代码表示将网格列分为4列并且宽度等分。

javascript 复制代码
grid-template-columns: 1fr 2fr 1fr 1fr;

上述代码表示将网格列分为4列,宽度以1:2:1:1的形式进行展示。

javascript 复制代码
grid-template-columns: 100px 2fr 1fr 1fr;

上述代码表示将网格分为4列,第一列固定为100px,剩余宽度分给后面的三列,比例为2:1:1

关键字
  • auto:由浏览器决定宽度。通常会让内容撑满剩余空间,类似于 flex: 1

    javascript 复制代码
    grid-template-columns: 100px  100px auto 100px;
    // 假设父盒子的宽度为800px 那么就是将网格分为4列 每列的宽度分别是100px 100px 800-100-100-100 = 500px 100px
    grid-template-columns: 1fr 1fr auto 1fr;
    // 先按照内容给第三列划分宽度,剩余宽度平均分给第一、二、四列
  • min-content: 列/行的最小宽度/高度,由该轨道中最小不可断内容(如一个长单词或一张图片)决定。

  • max-content: 列/行的宽度/高度,由该轨道中最大内容(如最长的单词或最宽的图片)决定。

函数minmax(min, max)

minmax(min, max): 定义一个尺寸范围,轨道尺寸将在这个范围内变化。

min: 最小值

max: 最大值

非常有用,可以创建响应式布局。

函数-repeat

repeat的作用是重复创建具有相同模式的轨道,简化书写

css 复制代码
repeat(count | auto-fill | auto-fit, track-list)
  • count: 重复次数,如 3。

  • auto-fill / auto-fit: 根据容器宽度自动填充轨道(用于创建响应式布局)。

举例说明

css 复制代码
 grid-template-columns: 1fr 1fr 1fr 1fr; 

 /* 简写 */
 grid-template-columns: repeat(4, 1fr);
css 复制代码
grid-template-columns: 1fr 1fr auto 1fr;

/* 简写 */
grid-template-columns: repeat(2, 1fr) auto 1fr;
auto-fill vs auto-fit
css 复制代码
/* 尽可能多的创建宽度为200px的列*/
grid-template-columns: repeat(auto-fit, 200px);

auto-fill vs auto-fit: 当轨道数量不足以填满一行时,auto-fill 会保留空白轨道空间,而 auto-fit 会将空白轨道折叠(将其尺寸压缩为0),让非空白轨道扩张以填满空间。在大多数响应式布局中,auto-fit 更常用。

让我们在实际应用场景理解一下这个问题 => 现在想设置宽度为200px的列,至于设置几行需要根据父元素的宽度来决定(响应式的),此时就可以使用auto-fill/auto-fit来实现

css 复制代码
grid-template-columns: repeat(auto-fill, 200px);
grid-template-columns: repeat(auto-fit, 200px);

但是此时发现一个问题,以父元素宽度为700px为例,发现空余部分会被保留,如下:

看起来就比较丑,若是希望多余空白部分被均分,可以进行如下配置

javascript 复制代码
 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));

minmax(200px, 1fr) 表示列宽最小为200px,最大可以扩展到1fr;

这里要重点关注minmax函数里面的1fr => 1fr 的计算方式:

当容器有剩余空间时,所有设置为 1fr 的轨道会平均分配这些剩余空间每个 1fr 代表"一份"剩余空间

通过设置父容器的宽度为百分比,再配合auto-fill和minmax(),就能根据屏幕大小自动调整网格的列数,让布局始终优雅地适应各种设备。

举例说明

现在将所有元素统一大小宽高均为80px 填充在父元素内, 超过父元素宽度就换行

html 复制代码
<style>
  .box{
    width: 300px;
    height: 300px;
    border: 1px solid #000;
    /* 开始网格布局 */
    display: grid;
    grid-template-columns: repeat(auto-fit, 80px);
    /* grid-template-rows: repeat(auto-fit, 80px);  这行代码写了是没有意义的 当划分好列之后,会根据子元素的数量划分行数 行高会根据行数平分父元素的高度!!!!!*/

  }
  .box div{
    background-color: aqua;
    color: #fff;
    border-radius: 2px;
  }
</style>
</head>
<body>
  <div class="box">
    <div>1</div>
    <div>1</div>
    <div>1</div>
    <div>1</div>
    <div>1</div>
    <div>1</div>
    <div>1</div>
    <div>1</div>
    <div>1</div>
  </div>
</body>

此时发现子元素之间没有间隙并且父元素🈶️空白缝隙

  • 若是不想保留父元素的空白缝隙 => 子元素平分,可以这样写

    css 复制代码
    grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
  • 若是想将元素之间留有空隙,可以使用gap属性

grid-template-areas

grid-template-areas:网格布局允许指定"区域"(area),一个区域由单个或多个单元格组成。grid-template-areas属性用于定义区域

gap

控制网格之间的间距有以下几种属性

  • column-gap - 控制网格列之间的间距

  • row-gap - 控制网格行之间的间距

  • gap - 同时设置column-gap和row-gap的简写属性

注意: gap属性是控制网格之间的间距的 和父元素的间距是没有设置的,如下:

css 复制代码
grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
gap: 24px;

上述案例在网页中展示如下:

若是需要父元素和子元素之间设置相同大小,需要给父元素设置padding

css 复制代码
padding: 24px;
grid-auto-columns和grid-auto-rows

设定隐藏的网格轨道的大小

justify-content+align-content
justify-content

justify-content 属性用于**控制整个网格在网格容器内的水平对齐方式 **=> 适用于当网格总宽度小于网格容器宽度时)

属性值 说明
start 网格与网格容器的左端对齐(默认值)
end 网格与网格容器的右端对齐
center 网格处于网格容器的X轴的中间
stretch 调整网格项的大小,使其宽度填充整个网格容器
space-around 相当于给每一列单元格添加相同的左右margin
space-between 只给单元格内部添加边距,与父元素之间无边距
space-evenly 每一列之间的左右间距是相同的 与边缘也有相同的距离

注意点: stretch只在特定情境有效

  • 1\] 网格总宽度小于容器宽度

  • 网格轨道尺寸使用可拉伸单位(如 fr、auto)

举例说明

css 复制代码
display: grid;
grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
gap: 24px;
/* justify-content: center; */

像上述例子中,justify-content设置不设置没有任何意义;

因为repeat(auto-fit, minmax(80px, 1fr))的意思是尽可能多的划分宽度为80px的列 若是有空白缝隙平分给这些划分好的列;

所以上述案例中的 网格总宽度 = 网格容器也就是父元素的宽度(而justify-content适用于 网格总宽度< 网格容器也就是父元素的宽度)!

css 复制代码
  width: 300px;
  height: 300px;
  border: 1px solid #000;
  /* 开始网格布局 */
  display: grid;
  grid-template-columns: repeat(2, 50px);
  gap: 24px;

如上:设置了两列100px<300px 此时就可以通过justify-content来控制单元格的显示位置了

justify-content通常与 align-content 一起使用,实现网格在容器中的精确定位。

align-content

align-content 属性用于控制整个网格在容器内的垂直对齐方式(当网格总宽度小于容器宽度时)

属性值 说明
start 网格与网格容器的上端对齐
end 网格与网格容器的下端对齐
center 网格处于网格容器的Y轴的中间
stretch 调整网格项的大小,使其高度填充整个网格容器 (默认值)
space-around 相当于给每一列单元格添加相同的上下margin
space-between 只给单元格内部添加边距,与父元素之间无边距
space-evenly 每一列之间的上下间距是相同的 与边缘也有相同的距离

这里就解释了为什么没有给子元素设置高度但是子元素依旧能够填充整个单元格的原因了 => align-content的默认属性值为stretch

若是修改该属性值,子元素的高度就是由内容来撑开了,如下

若是还是想要在不设置高度的情况下进行拉伸可以使用 align-items(子元素的属性)进行控制

justify-items + align-items

justify-content 与 align-content是控制网格在网格容器中的对齐方式

而 justify-items 与 align-items是控制内容在单元格中的对齐方式。

子元素合并行/列
网格线编号系统

网格线从1开始编号,从左到右(列),从上到下(行)

一个6列的网格有7条垂直线

一个4行的网格有5条水平线

grid-column+ grid-row+grid-area

语法:

css 复制代码
grid-column : [start] / [end] - 从start网线开始到end网线结束 控制列占据 
grid-row: [start] / [end] - 从start网线开始到end网线结束 控制行占据

也可以使用span 关键子进行简写以列为例

css 复制代码
gird-column: start / span num  - 从start网线开始 跨越num列

若是该元素同时跨域行和列 也可以使用gird-area简写

css 复制代码
gird-area: [row-start] / [column-start] / [row-end] / [column-end]  
举例说明·
css 复制代码
<style>
  .box{
    width: 300px;
    height: 300px;
    border: 1px solid #000;
    /* 开始网格布局 */
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
    gap: 24px;
  }
  .box div{
    background-color: aqua;
    color: #fff;
  }
  .haveTwo{
    grid-column: 2 / 4; /* 这表示该元素将在第2条网线开始到第4条网线结束占据2列*/
    grid-row: 1 / span 2 ;
  }
</style>
html 复制代码
<body>
  <div class="box">
    <div>1</div>
    <div class="haveTwo">2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <div>7</div>
    <div>8</div>
    <div>9</div>
  </div>
</body>

当然上述案例可以直接使用grid-area结果是相同的,如下

css 复制代码
grid-area: 1 / 2 / 3 / 4 ;
命名网格线

在定义轨道的同时,还可以给网格线命名以提高代码可读性,使用方括号定义名称,如 [main-start]

css 复制代码
.container {
  grid-template-columns: [sidebar-start] 200px [sidebar-end content-start] 1fr [content-end];
  /* 
    创建了两条列轨道。
    产生了四条垂直的网格线,它们被命名为:
      1. sidebar-start
      2. sidebar-end (同时也是 content-start)
      3. content-end
  */
}

若是使用auto-fit,应该如何命名网格线呢? 这完全不用担心,gird内置自动索引功能,如下

css 复制代码
 grid-template-columns: repeat(auto-fit, [col-start] minmax(80px, 1fr) [col-end]);

/*
  创建n条轨道
  产生了n+2条垂直网线 它们被命名为
  第一列:col-start 1 和 col-end 1
  第二列:col-start 2 和 col-end 2
  第三列:col-start 3 和 col-end 3
  以此类推...

*/

上述示例中 为网格线命名以及使用网格线和并列代码修改如下

css 复制代码
grid-template-columns: repeat(auto-fit, [col-start] minmax(80px, 1fr) [col-end]);
css 复制代码
grid-column: col-start 2 / col-end 3;
相关推荐
伐尘3 小时前
【CE】图形化CE游戏教程通关手册
前端·chrome·游戏·逆向
不想吃饭e3 小时前
在uniapp/vue项目中全局挂载component
前端·vue.js·uni-app
非凡ghost3 小时前
AOMEI Partition Assistant磁盘分区工具:磁盘管理的得力助手
linux·运维·前端·数据库·学习·生活·软件需求
UrbanJazzerati3 小时前
前端入门:margin居中、border、box-radius、transform、box-shadow、mouse事件、preventDefault()
前端·面试
蝎子莱莱爱打怪3 小时前
🚀🚀🚀嗨,一起来开发 开源IM系统呀!
前端·后端·github
Enddme3 小时前
《前端笔试必备:JavaScript ACM输入输出模板》
前端·javascript·面试
前端鱼3 小时前
前端面试中值得关注的js题
前端·面试
UnnamedOrange3 小时前
有来前后端部署
前端·后端
德育处主任3 小时前
p5.js 绘制 3D 椭球体 ellipsoid
前端·javascript·数据可视化