CSS Grid 布局从 0 到 1

简介: 现在很多的 UI 组件库都提供了栅格系统,在响应式方面非常的方面,今天我们来谈的是 CSS 原生的栅格系统。

什么是栅格


现在很多的 UI 组件库都提供了栅格系统,在响应式方面非常的方面,今天我们来谈的是 CSS 原生的栅格系统。

栅格系统是一个二维系统,他可以同时处理行和列

1682563751(1).png

栅格系统很强大,但是兼容性并不是特别好(我感觉其实已经可以了),截至目前(2022.6.30)grid 的兼容性如下

1682563769(1).png


绘制栅格


使用 display: grid; 声明一个 grid 容器。

绘制行列需要使用grid-template-rows 声明行的高度,grid-template-columns 声明列的宽度

<style>
  .grid {
    width: 200px;
    height: 200px;
    border: 1px solid silver;
    display: grid;
    grid-template-rows: 100px 100px;
    grid-template-columns: 100px 100px;
  }
  .grid div {
    background-color: pink;
    background-clip: content-box;
    padding: 10px;
    border: 1px solid pink;
    box-sizing: border-box;
  }
</style>
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>
复制代码

上面的示例中声明了一个 2*2 的 grid,并且固定量宽度和高度

1682563790(1).png

除了使用固定宽高,还可以使用百分比

<style>
  .grid {
    width: 200px;
    height: 200px;
    border: 1px solid silver;
    display: grid;
    grid-template-rows: 30% 70%;
    grid-template-columns: 50% 50%;
  }
  .grid div {
    background-color: pink;
    background-clip: content-box;
    padding: 10px;
    border: 1px solid pink;
    box-sizing: border-box;
  }
</style>
<!-- <div class="triangle"></div> -->
<!-- <div id="circle-rect"></div> -->
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>
复制代码

百分比的计算是相对于 grid 容器来计算的,上面的代码表示第一行高度为 30%,第二行高度为 70%,每一列的宽度都为 50%

1682563811(1).png

如果行列的百分比加起来不足 100%就会有空余区域,如果大于 100%就会超出容器范围

可以使用 repeat 函数来帮我们进行重复操作

.grid {
  width: 200px;
  height: 200px;
  border: 1px solid silver;
  display: grid;
  grid-template-rows: repeat(2, 50%); /*等价于 50% 50%*/
  grid-template-columns: repeat(4, 25%);/*等价于 25% 25% 25% 25%*/
}
复制代码

1682563829(1).png

在使用 repeat 来进行重复操作时,可以传入多个数值,比如repeat(2, 100px 50px),等价于 100px 50px 100px 50px,是将第二个参数整体重复多次

除了 repeat 固定数值,还可以让 grid 自动填充

.grid {
  width: 200px;
  height: 200px;
  border: 1px solid silver;
  display: grid;
  grid-template-rows: repeat(auto-fill, 100px);
  grid-template-columns: repeat(auto-fill, 100px);
}
复制代码

上面这段代码会让 div 按照每份 100px 的宽高进行自动分配,比如容器宽度不确定时,可以使用自动分配

和自动分配比较接近的是按比例划分,类似于 flex 布局中使用 flex 声明比例

.grid {
  width: 60%;
  height: 200px;
  border: 1px solid silver;
  display: grid;
  grid-template-rows: 1fr 2fr;
  grid-template-columns: 2fr 3fr;
}
复制代码

第一行高度为 1/3 第二行高度为 2/3,第一列宽度为 2/5 第二列宽度为 3/5

1682563851(1).png

可以使用 minmax 控制尺寸的响应式波动

.grid {
  width: 60%;
  height: 50px;
  border: 1px solid silver;
  display: grid;
  grid-template-rows: repeat(2, minmax(30px, 50px));
  grid-template-columns: 2fr 3fr;
}
复制代码

列按照比例等比划分,公有两行,每一行最小 30px, 最大 50px,如果容器范围小于所有行的最小范围,内容就会溢出

1682563877(1).png


间距控制


间距控制可以使用 margin,完全没问题,但是不够优雅,我们可以使用栅格提供的间距控制属性row-gap或、column-gap或者直接使用 gap

.grid {
  width: 60%;
  height: 100px;
  border: 1px solid silver;
  display: grid;
  grid-template-rows: repeat(2, minmax(30px, 50px));
  grid-template-columns: 2fr 3fr;
  gap: 20px 10px;
  /* 等价于
  row-gap: 20px;
  column-gap: 10px;
  */
}
复制代码

1682563905(1).png

使用 gap 时如果只设置一个数值,则行间距和列间距同时应用这个数值


栅格线定位


栅格线可以使用命名与编号找到,方便控制指定栅格,或将内容添加到指定栅格中。

栅格命名有两种方式,主动命名和自动命名。

自动命名就是按照栅格线从一开始向正方向计数

<style>
  .grid {
    width: 200px;
    height: 200px;
    border: 1px solid silver;
    display: grid;
    grid-template-rows: repeat(3, 1fr);
    grid-template-columns: repeat(3, 1fr);
  }
  .grid div {
    background-color: pink;
    background-clip: content-box;
    padding: 10px;
    border: 1px solid pink;
    box-sizing: border-box;
  }
  .grid div:first-child {
    grid-row-start: 1;
    grid-column-start: 1;
    grid-row-end: 2;
    grid-column-end: 4;
  }
</style>
<div class="grid">
  <div>1</div>
</div>
复制代码

控制 div 在第一条横线起始,第二条横线结束,也就是第一列;第一条竖线起始,第四条竖线结束,也就是第一、二、三列。

1682563925(1).png

主动命名就是在声明 grid 行列的时候手动为栅格线命名

<style>
  .grid {
    width: 300px;
    height: 300px;
    border: 1px solid silver;
    display: grid;
    grid-template-rows: [r1-start] 100px [r1-end r2-start] 100px [r2-end r3-start] 100px [r4-end];
    grid-template-columns: [c1-start] 100px [c1-end c2-start] 100px [c2-end c3-start] 100px [c4-end];
  }
  .grid div {
    background-color: pink;
    background-clip: content-box;
    padding: 10px;
    border: 1px solid pink;
    box-sizing: border-box;
  }
  .grid div:first-child {
    grid-row-start: r1-start;
    grid-column-start: c2-start;
    grid-row-end: r2-end;
    grid-column-end: c2-end;
  }
</style>
<div class="grid">
  <div>1</div>
</div>
复制代码

通过主动命名来实现栅格内容的填充

1682563944(1).png

在手动命名栅格线的时候也可配合重复来简化操作

<style>
  .grid {
    width: 300px;
    height: 300px;
    border: 1px solid silver;
    display: grid;
    grid-template-rows: repeat(3, [r-start] 1fr [r-end]);
    grid-template-columns: repeat(3, [c-start] 1fr [c-end]);
  }
  .grid div {
    background-color: pink;
    background-clip: content-box;
    padding: 10px;
    border: 1px solid pink;
    box-sizing: border-box;
  }
  .grid div:first-child {
    grid-row-start: r-start 1;
    grid-column-start: c-start 2;
    grid-row-end: r-end 2;
    grid-column-end: c-end 1;
  }
</style>
<div class="grid">
  <div>1</div>
</div>
复制代码

通过重复栅格+命名的方式我们实现了和上一个例子相同的效果

1682563965(1).png

可能会有人觉得这样多此一举,这样和自动命名编号没有区别。但是,注意如果重复栅格一组只有一个格效果和自动命名是一样的,但是如果重复栅格是多组的那么效果就不一样了

上面命名的示例都是通过栅格线定位的,还可以通过偏移量来定位

.grid div:first-child {
  grid-row-start: r-start 2;
  grid-column-start: c-start 2;
  grid-row-end: span 2;
  grid-column-end: span 1;
}
复制代码

通过 span 来表示使用偏移量来定位

1682563991(1).png

行列定位可以使用组合模式

.grid div:first-child {
      grid-row: r-start 2 / r-end 3;
      grid-column: c-start 2 / span 1;
      /* grid-row: 2 / 4;
      grid-column: 2 / span 1; */
    }
复制代码

组合模式可以将多种方式混合使用,自动命名定位、手动命名定位、偏移量定位,/前面是start, 后面是 end


区域定位


除了使用栅格线定位还可以使用区域定位

.grid div:first-child {
  grid-area: 2 / 2 / 4 / 3;
}
复制代码

我们使用区域定位实现了和上面示例相同的效果

1682564011(1).png

区域布局同样可以使用命名栅格线来定位,同时可以混合使用

.grid div:first-child {
  grid-area: r-start 2 / c-start 2 / span 2 / 3;
}
复制代码

可以对每一个区域进行命名,使用grid-template-areas按照每行为一组进行命名

<style>
  .grid {
    width: 300px;
    height: 300px;
    border: 1px solid silver;
    display: grid;
    grid-template-rows: 60px 1fr 60px;
    grid-template-columns: 60px 1fr;
    grid-template-areas: 'header header''nav main''footer footer';
  }
  .grid div {
    background-color: pink;
    background-clip: content-box;
    padding: 10px;
    border: 1px solid pink;
    box-sizing: border-box;
  }
  .grid div:first-child {
    grid-area: header;
  }
  .grid div:nth-child(2) {
    grid-area: main;
  }
</style>
<div class="grid">
  <div>1</div>
  <div>2</div>
</div>
复制代码

有相同命名的区域会被合并为一个区域

1682564037(1).png

css 会自动将我们的命名区域的起始行和起始列命名为 【命名-start】结束列命名为【命名-end】,例如上面的 header 的grid-area 的形式为 grid-area: header-start / header-start/ header-end/ header-end。

区域和行列声明可以使用简写模式

grid-template: '栅格名称 栅格名称 栅格名称 栅格名称' 行高 '栅格名称 栅格名称 栅格名称 栅格名称' 行高 '栅格名称 栅格名称 栅格名称 栅格名称' 行高/列宽 列宽 列宽 列宽;

如果某个区域不需要命名可以使用.作为占位符,例如

.grid {
  grid-template-rows: 60px 1fr 60px;
  grid-template-columns: 60px 1fr;
  grid-template-areas: 'header .''nav main''. footer';
}
复制代码


栅格流动


如果要去除栅格之的空格可以使用grid-auto-flow来控制栅格的流动,栅格布局默认 row 流动

选项 说明
column 按列排序
row 按行排列
dense 元素使用前面空余栅格

比如

<style>
  .grid {
    width: 300px;
    height: 300px;
    border: 1px solid silver;
    display: grid;
    grid-template-rows: repeat(3, 100px);
    grid-template-columns: repeat(3, 100px);
  }
  .grid div {
    background-color: pink;
    background-clip: content-box;
    padding: 10px;
    border: 1px solid pink;
    box-sizing: border-box;
  }
  .grid div:first-child {
    grid-column: 1/span 2;
  }
  .grid div:nth-child(2) {
    grid-column: 2 / span 1;
  }
</style>
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>
复制代码

这个布局下的排列方式如下

1682564068(1).png

将排列方式更换为 column 之后

1682564110(1).png

设置为 row dense 之后

1682564127(1).png


对齐方式


对齐方式是我们经常需要用到的属性,在很多时候我们都需要使用对齐来调整样式

选项 说明 对象
justify-content 所有栅格在容器中的水平对齐方式,容器有额外空间时 栅格容器
align-content 所有栅格在容器中的垂直对齐方式,容器有额外空间时 栅格容器
align-items 栅格内所有元素的垂直排列方式 栅格容器
justify-items 栅格内所有元素的横向排列方式 栅格容器
align-self 元素在栅格中垂直对齐方式 栅格元素
justify-self 元素在栅格中水平对齐方式 栅格元素

justify-content 属性的值如下

说明
start 容器左边
end 容器右边
center 容器中间
stretch 撑满容器
space-between 第一个栅格靠左边,最后一个栅格靠右边,余下元素平均分配空间
space-around 每个元素两侧的间隔相等。所以,栅格之间的间隔比栅格与容器边距的间隔大一倍
space-evenly 栅格间距离完全平均分配

align-content 属性的值如下

说明
start 容器顶边
end 容器底边
center 容器垂直中间
stretch 撑满容器
space-between 第一个栅格靠左边,最后一个栅格靠右边,余下元素平均分配空间
space-around 每个元素两侧的间隔相等。所以,栅格之间的间隔比栅格与容器边距的间隔大一倍
space-evenly 栅格间距离完全平均分配

justify-items 用于控制元素的水平对齐方式,可用的属性值如下

说明
start 元素对齐栅格的左边
end 元素对齐栅格的右边
center 元素对齐栅格的中间
stretch 水平撑满栅格

align-items 用于控制元素的垂直对齐方式,可用的属性值如下

说明
start 元素对齐栅格的顶边
end 元素对齐栅格的底边
center 元素对齐栅格的垂直中间
stretch 垂直撑满栅格

justify-self 与 align-self 控制单个栅格内元素的对齐方式,属性值与 justify-items 和 align-items 是一致的。

place-content 用于控制栅格的对齐方式,语法如下:

place-content: <align-content> <justify-content>

place-items 控制所有元素的对齐方式,语法如下:

place-items: <align-items> <justify-items>

place-self 控制单个元素的对齐方式,语法如下:

place-self: <align-self> <justify-self>

相关文章
|
1月前
|
前端开发 UED 容器
在 CSS 中使用 Flex 布局实现页面自适应时需要注意什么?
【10月更文挑战第22天】在使用 Flex 布局实现页面自适应时,需要对其基本原理和特性有深入的理解,同时结合具体的布局需求和场景,进行细致的调整和优化。通过合理的设置和注意事项的把握,才能实现理想的自适应效果,提升用户体验。还可以根据实际情况进行更深入的探索和实践,以不断提升 Flex 布局的应用能力。
|
25天前
|
前端开发 容器
实现CSS品字布局
【10月更文挑战第27天】
|
2月前
|
前端开发 容器
使用 CSS Grid 布局实现响应式设计
【10月更文挑战第1天】使用 CSS Grid 布局实现响应式设计
56 4
|
2月前
|
前端开发 容器
前端技术分享:利用CSS Grid布局实现响应式设计
【10月更文挑战第1天】前端技术分享:利用CSS Grid布局实现响应式设计
|
2月前
|
前端开发 UED 容器
前端技术分享:利用 CSS Grid 实现响应式布局
【10月更文挑战第1天】前端技术分享:利用 CSS Grid 实现响应式布局
62 2
|
3月前
|
前端开发 容器
css布局-弹性布局学习笔记
这篇文章是关于CSS弹性布局的学习笔记,详细介绍了flex容器和元素的相关属性,包括flex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content以及order、flex-grow、flex-shrink、flex-basis、flex和align-self等,解释了这些属性在弹性盒子布局中的作用和用法。
|
3月前
|
JavaScript 前端开发
网页前端课程设计-【模仿】香港中文大学官网,轮播图及div+css布局,js的dom操作
这篇文章介绍了如何模仿香港中文大学官网进行网页前端课程设计,包括使用div+css布局、js的DOM操作以及实现轮播图等技术细节。
|
4月前
|
前端开发 安全 容器
CSS如何优雅实现卡片多行排列布局?
【8月更文挑战第24天】CSS如何优雅实现卡片多行排列布局?
144 3
|
4月前
|
前端开发 开发者 容器
探索现代Web开发中的CSS Grid布局技术
【8月更文挑战第29天】在数字时代的浪潮中,网页设计不断进化以适应日新月异的用户需求。CSS Grid布局技术作为一项革新性的前端工具,为设计师和开发者提供了前所未有的布局能力。本文旨在通过深入浅出的方式介绍CSS Grid的核心概念、基本用法以及在实际项目中的应用,帮助读者快速掌握这一强大的网页布局工具。
58 3