Grid 是一个栅栏系统,你可以把它想像成他是一个 Table,有一些像是 Table 的概念例如合并储存格 行列、直列
与 Flexbox 相比,就是从一维
变成了二维
,占比是可由内外部决定,大部分情况是由外部宣告
来看一下语法
先确认一下 CSS Grid 会长什么样子
css
.grid-wrapper{
display: grid;
grid-auto-flow: column dense;
grid-auto-columns: 1fr 1fr;
grid-auto-rows: 1fr;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 0px 0px;
}
or
css
.grid-wrapper{
grid-template-areas:
". head"
"nav main"
". footer";
}
.header { grid-area: 1 / 1 / 2 / 4 }
.main { grid-area: 2 / 1 / 4 / 2 }
.anv { grid-area: 2 / 3 / 5 / 4 }
.footer { grid-area: 4 / 1 / 5 / 2 }
看起来有点杂,但其实我们主要会用到 grid-template-column
、gap
grid-template-column
代表横列放几个,并且占比多少grid-template-row
代表直列放几个,并且占比多少,不过如果我们想要做到 flexbox 那样自动超出占比换行,设定为1fr
即可gap
内间距,下面会提到
内间距 Gap
在 Grid 中,不使用 百分比做网格,而是真的实际的占用几块 (ex: 5fr),所以不会有 Gap 不被百分比计算的问题 (ex: Flexbox), 这部分对 Grid 来说是相对优势,因为就不需要在外层使用 Row 负margin 来做抵销 Col Padding
确认对齐
先测试一下对齐方式,深入你记忆中。
为什么排版是填满的,明明我的宽度就是设定 auto?
没错,这就是 Flexbox 跟 Grid 的对齐特性,在 Normal 的情况下子项目会填满,如果你不想填满,那你需要给他对齐模式。
然后我们会发现,他一样像 Flexbox 一样,虽然一样有 Column、Row, 但没有 的主轴与交错线不同的问题,
另外 items 跟 content 的定义也需要明确厘清 (ex: align-items、align-content)
- items: 个别项目对齐
- content: 内容对齐方式
- place-content: 同时设定 align-content 和 justify-content
- place-items: 同时设定 align-items 和 justify-items
排列方向
左到右排列,还是上到下排列,类似 flex-direction
Flexbox column 的对齐演示,就是使用这样的方式,我希望他从上到下 超过换行,而不是从左到右 超过换行 Sample
css
.grid-wrapper{
grid-auto-flow: column;
}
使用元件来做
tsx
import {Grid} from 'bear-react-grid';
<Grid gap="2px">
<div>child</div>
<div>child</div>
<div>child</div>
</Grid>
这样代表 grid-auto-columns: repeat(3, auto)
,CSS IN JS 会得 children.count() 作为一般排版使用 Gap 为 2px 但如果你今天是要做商品列表,你可以指定占比:
tsx
<Grid columns="repeat(3,1fr)" gap="2px">
<div>child 1</div>
<div>child 2</div>
<div>child 3</div>
<div>child 4</div>
<div>child 5</div>
<div>child 6</div>
</Grid>
这样就会 3个一列,多出3个自动换行
相关参数可参照 CSS Grid Component
对齐
如果要对齐,你可以使用公用类样式:
tsx
import {Grid, GridCol} from 'bear-react-grid';
<Grid columns="repeat(3,1fr)" gap="2px"
className="justify-content-start align-content-start"
>
<div>child 1</div>
<div>child 2</div>
<div>child 3</div>
</Grid>
公用类样式也有提供响应式设定
合并
如果你有合并需求,或是你想要由内部决定,你可以:
tsx
import {Grid, GridCol} from 'bear-react-grid';
<Grid columns="repeat(3,1fr)" gap="2px">
<GridCol col={2}>child 1</GridCol>
<GridCol>child 2</GridCol>
<GridCol col={2}>child 1</GridCol>
<GridCol>child 2</GridCol>
</Grid>
相关参数可参照 CSS Grid Col Component
响应式
如果你有响应式的需求,你可以:
tsx
import {Grid, GridCol} from 'bear-react-grid';
<Grid columns={{
xs: 1,
md: 'repeat(3,1fr)',
}} gap="2px">
<GridCol col={2}>child 1</GridCol>
<GridCol>child 2</GridCol>
<GridCol col={2}>child 1</GridCol>
<GridCol>child 2</GridCol>
</Grid>
结论
在常规的时候,我建议直接使用Grid + Flex + Utilities CSS 来处理,省去额外定义宣告,并且让阅读Html 的时候较明确知道是什么(flex or grid 几个),目前的展示首页,就是使用这种方式来制作
而对于复杂样式的时候,例如一个甘特图,切分各区块的命名,那就额外宣告一个 Styled-component
去定义
这边也推荐一个方便制作复杂 Grid 的工具 grid.layoutit.com/
以上使用的 Grid 元件是 bear-react-grid
bear-react-grid.pages.dev 首页也是使用这个方式来排版
不管使用的是什么CSS工具(scss、css module、bootstrap、uno、tailwind css 等等),但一定要要有栅栏可以统一排版方式,與快速排版的功能 即正确的姿势