css之二维布局grid

332 阅读4分钟

grid网格是一个用于二维布局系统。利用网格,你可以把内容按照行和列的格式进行排版,网格能轻松地实现一些flex不好实现的复杂的布局。

定义网格

grid-template-columns/grid-template-rows:定义网格宽高

display: grid;
// 第一种写法
grid-template-columns: 50px 50px 50px;
grid-template-rows: 50px 50px 50px;
// 第二种写法
grid-template-columns: repeat(3, 50px);
grid-template-rows: 50px 50px 50px;
// 第三种写法
grid-template-columns: 150px 1fr 1fr;
grid-template-rows: 0.3fr 0.3fr;
// 第四种写法
grid-template-columns: minmax(100px, 1fr)
  • fr是自适应单位,它会根据容器的宽高自行计算。利用fr可以实现margin-right:auto的效果,因为fr会自动占满剩余的空间。
  • minmax(100px, 1fr): 最小100px 最大1fr

网格命名

grid-template-areas:对网格命名,需要配合子项grid-area使用

.main {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
  grid-template-areas:
    'a1 a1 a2'
    'a1 a1 a2'
    'a3 a3 a3';
}
.main div:nth-of-type(1) {
  grid-area: a1;
}
.main div:nth-of-type(2) {
  grid-area: a2;
}
.main div:nth-of-type(3) {
  grid-area: a3;
}

第一个div将占据4份的面积,第二个div占据2份的面积,第三个div占据3份的面积

网格间距

row-gap/column-gap:网格之间的间距

row-gap: 20px; 
column-gap: 30px; 
// 简写 
gap: 20px 30px;

还可以应用在flex弹性布局中

.main2 { 
    display: flex; 
    flex-wrap: wrap; 
    row-gap: 20px; 
    column-gap: 30px; 
}

设置网格内单元格位置

justify-items属性设置单元格内容的水平位置(左中右),align-items属性设置单元格内容的垂直位置(上中下)

.main {
  display: grid;
  width: 300px;
  height: 300px;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  justify-items: center;
  align-items: center;
  gap: 20px;
}
.main div {
  width: 50px;
  height: 50px;
  background-color: blueviolet;
}

css17.jpg

设置整个网格位置

justify-content属性是整个内容区域在容器里面的水平位置(左中右),align-content属性是整个内容区域的垂直位置(上中下)。

.main {
  background-color: beige;
  display: grid;
  width: 300px;
  height: 300px;
  grid-template-columns: 50px 50px 50px;
  grid-template-rows: 50px 50px;
  justify-content: center;
  align-content: center;
  gap: 20px;
}

css19.jpg

justify-content align-content:是针对整个容器的,而且grid容器的宽高要小于容器的宽高,这样才会显示出效果出来,下面grid的整个宽高是150px,而容器是300px。

隐式网格grid-auto-flow

隐式网格:就是你划分的网格数量小于实际内容的数量,因为实际内容数量在项目中是不确定的。这种情况在容器自适应行列的情况下非常有用。

.main {
  width: 300px;
  height: 300px;
  background: skyblue;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 100px;
  /* 默认:row 就是行产生隐式网格 */
  grid-auto-flow: row;
  /* 可以调节产生隐式网格的高度 */
  grid-auto-rows: 50px;
  gap: 20px;
}

.main div {
  background-color: aquamarine;
}
<div class="main">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
</div>

css20.jpg

  • grid-auto-flow: row/column 排序是按行排列还是按照列排列
  • grid-auto-rows: 设置剩余网格的宽高

定义子项的放置位置

grid-column-start/grid-column-end

// 第一种写法
.main div:nth-of-type(1) {
  grid-column-start: 2;
  grid-column-end: 3;
}
// 第二种写法
grid-column-start:2; 
grid-column-end:span 2; span表示跨2个网格
// 第三种写法
grid-column: 2 / 3; 
grid-row: 2 / 4;

应用场景

利用repeat,minmax和隐式网格实现一个行自适应

.main {
  background: skyblue;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-template-rows: 100px;
  grid-auto-rows: 100px;
  grid-gap: 20px 20px;
}
.main div {
  background: pink;
  border: 1px black solid;
}
<div class="main">
  <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>10</div>
  <div>11</div>
</div>
  • auto-fill: 有时单元格的大小是固定的,但是容器的大小不确定。如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用auto-fill关键字表示自动填充。
  • minmax(200px, 1fr): 单元格最小宽度是200px
  • 隐式网格:剩余的网格按行排列,当浏览器的分辨率变化的时候,由于minmax和auto-fill的设置,列会随着变化,产生自适应。

除了行自适应,还有列自适应

grid-template-rows: repeat(3, 1fr);
/* 列的折行,默认是行的折行,所以要加上grid-auto-flow: column; */
grid-auto-flow: column;
grid-auto-columns: 100px;

比定位更方便的叠加布局

css22.jpg

.main{
    display: grid;
}
.main img{
    grid-area: 1/1/1/1;
}
.main span{
    grid-area: 1/1/1/1;
    justify-self: end;
    align-self: end;
    margin:5px;
}
.main p{
    grid-area: 1/1/1/1;
    align-self: center;
}
<div class="main">
  <img src="./phone.png" alt="">
  <span>自制</span>
  <p>手机热卖中.....</p>
</div>

多种排列组合

css25.jpg

.main {
  width: 300px;
  height: 300px;
  background: skyblue;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 5px;
}
.main div {
  background: pink;
}
.main div:nth-of-type(1) {
  grid-area: 1/1 / span 2 / span 2;
}