掌握grid布局,用最简单结构实现复杂的页面布局

2,792 阅读6分钟

本文正在参加「金石计划」

grid布局通常在C端布局用得比较多,非常强大,特别是在响应式布局上也有很大作用,过去我们使用弹性盒子布局,flex布局,通常我们在不改变结构的情况下可以使用grid布局来更灵活的拓展我们的布局

正文开始...

grid

当我们对一个父级元素使用grid时,此时子级元素会发生什么

 <div class="app">
    <div class="box-1">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
        <div class="item">5</div>
        <div class="item">6</div>
        <div class="item">7</div>
        <div class="item">8</div>
        <div class="item">9</div>
    </div>
</div>

对应的css

 * {
    padding: 0;
    margin: 0;
  }
  .app {
      background: beige;
  }
  .box-1 {
      display: grid;
  }
  .box-1 .item {
      width: 80px;
      height: 80px;
  }
  .box-1 .item:nth-of-type(2n) {
      background-color: green;
  }
  .box-1 .item:nth-of-type(2n+1) {
      background-color: pink;
  }

此时子元素将默认单行排列 默认情况下,当父元素设置grid,默认grid-template-columns: 1fr,grid-template-rows:1fr

网格布局主要由columsrows来定义列与行

  • 九宫格 通常我们在页面布局上,左右间距等分,这个在以前布局上,左右间距设置就是间距的一半,上下间距会合并
 <div class="box box-1">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
</div>
.app {
            background: beige;
        }
.box-1 {
    display: grid;
    grid-template-columns: 33.3% 33.3% 33.3%;
    grid-template-rows: 200px 200px 200px;
    grid-gap: 10;
}
.box .item:nth-of-type(2n) {
    background-color: green;
}
.box .item:nth-of-type(2n+1) {
    background-color: pink;
}

宽度自适应,每个高度为固定200px的九宫格 我们从以上发现,我们的结构只有父子结构,第二行也是自动换行从第4个元素开始。

也就是grid-template-columns确定了3列,并且宽度事整个屏幕的33.3%,而高度为固定高度200px有且仅有3行

当我们把grid-template-columns: 1fr 1fr 1fr时,此时与之效果是一样,有且仅仅只有三列

看到1fr是不是很陌生,这是网格的轨道单位,这是一个很灵活的单位

  • 假设我们要平分整个屏幕的1/3,那么你就需要设置grid-template-columns: 1fr 1fr 1fr,每一个1fr就是33.33%
  • 假设你要设置一个2fr 1fr 1fr,那么第一个元素会是第二个元素的两倍

grid-template-columns

在以上九宫格例子中,我们使用grid-template-columns控制了网格列数,通过这个属性,我们可以不用单独对子元素进行控制

 .box-1 {
      display: grid;
      grid-template-columns: 200px 100px 1fr;
      grid-template-rows: 200px 200px 200px;
  }
  .box .item:nth-of-type(2n) {
      background-color: green;
  }
  .box .item:nth-of-type(2n+1) {
      background-color: pink;
  }

在父元素上,我们可以在grid-template-columns中设置子元素columns的宽度,grid-template-columns: x y z ...x,y,z既可以是百分比,也可以是固定像素

grid-template-rows

在以上例子中我们用这个属性控制了子元素的高度,当我们UI设计的一个模块是4行时,我们就可以对应设置grid-template-rows: x y z p这个属性控制了网格中的行

grid-columns-grap

控制列之间的间距

.app {
  background: beige;
}
.box-1 {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 200px 200px 200px;
  grid-column-gap: 10px; /* 列之间10个像素*/
}
.box .item:nth-of-type(2n) {
    background-color: green;
}
.box .item:nth-of-type(2n+1) {
    background-color: pink;
}

grid-rows-grap

控制行之间的间距

.box-1 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 200px 200px 200px;
    grid-row-gap: 10px; /* 行之间的间距 */
}

我们实现上下左右间距相等的间距

.app {
  background: red;
}
.box-1 {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 200px 200px 200px;
  grid-column-gap: 10px;
  grid-row-gap: 10px;
  padding: 10px;
}

我们给父元素添加padding: 10px;,然后分别设置grid-column-gap: 10px;,grid-row-gap:10就可以实现间距相等了

我们可以用column-gaprow-gap来替代grid-column-gapgrid-row-gap

repeat 复制

在以上我们使用grid-template-columns:1fr 1fr 1fr来控制,我们也可以利用repeat来简写

.box-1 {
  display: grid;
  / * grid-template-columns:1fr 1fr 1fr */
  grid-template-columns: repeat(3,1fr);
  /*
    grid-template-rows: 200px 200px 200px
  */
  grid-template-rows: repeat(3, 200px);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
  padding: 10px;
}

grid-column-start与grid-column-end

控制列的跨度

.box .item:nth-of-type(1) {
    grid-column-start: 1;
    grid-column-end: 4;
}

我们对第一个items使用grid-column-start:1,grid-column-end:4

grid-row-start与grid-row-end

控制行的跨度

  .box .item:nth-of-type(1) {
      grid-row-start: 3;
      grid-row-end: 3;
      grid-column-start: 1;
      grid-column-end: 3;
  }    

grid-column与grid-row

在之前我们有用过grid-column-startgrid-column-end来控制列的跨度

我们可以通过grid-column:1/3来简grid-column-start:1;grid-column-end:3

.box-1 {
  display: grid;
  grid-template-columns: repeat(4,1fr);
  gap: 20px;
  position: relative;
}
.box .item:nth-of-type(1) {
    grid-column: 1/3;
}

我们通过grid-row:1/3来简写grid-row-start:1;grid-row-end:3

.box .item:nth-of-type(1) {
    grid-column: 1/3;
    grid-row: 1/3;
}

minmax(200px, 1fr)

最小宽度200,最大自适应

.box-1 {
        display: grid;
        /* grid-template-columns: 1fr 1fr 1fr; */
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        grid-column-gap: 10px;
        grid-row-gap: 10px;
        padding: 10px;
    }

gap的简写

gap:10px 20px代表row-gap:10pxcolumn-gap:20px

 .box-1 {
    display: grid;
    grid-template-columns: repeat(4,1fr);
    /* grid-column-gap: 10px;
    grid-row-gap: 10px; */
    /* column-gap: 10px;
    row-gap: 10px; */
    gap:10px 20px;
 }

grid-area

这是一个基于grid-row-startgrid-column-startgrid-row-endgrid-row-end的简写

.box .item:nth-of-type(2) {
  grid-area: 1 / 2 / 2 / 2;
}
  • 实现一个headerslide,main,footer的布局
 <div class="app">
   <header>header</header>
   <aside>slide</aside>
   <main>main</main>
   <footer>footer</footer>
</div>

对应的css如下

* {
  padding: 0;
  margin: 0;
}
.app {
    background: red;
    display: grid;
    grid-template-columns: 200px 1fr;
    grid-template-rows: 30px calc(100vh - 90px) 60px;
}
header {
    grid-column: 1 / 3;
    background-color: blue;
}
aside {
    grid-column: 1 / 2;
    background-color: pink;
}
main {
    grid-column: 2 / 3;
    background-color: yellow;
}
footer {
    grid-column: 1 / 3;
    background-color: palegreen;
}

我们在父元素上设置了grid-template-columns: 200px 1fr,这个使得网格的第一列是固定200px,第二列是1fr

我们使用grid-template-rows: 30px calc(100vh - 90px) 60px;设置了row,那么第一行就是30px,第二行就是calc(100vh -90px),第三行就是60px

我们在header上用grid-column: 1/3设置了跨列显示,在aside上设置了grid-column: 1/2,在main上设置了grid-column: 2/3;footer设置了grid-column:1/3 最后我们看下效果

grid-area

命名网格区域名称

  * {
    padding: 0;
    margin: 0;
  }
.app {
  background: red;
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-auto-rows: minmax(100px, auto);
  grid-template-areas:
  "hd hd hd"
  "sd main main"
  "ft ft ft";
}
header {
  grid-area: hd;
  background-color: blue;
}
aside {
  grid-area: sd;
  background-color: pink;
}
main {
  grid-area: main;
  background-color: yellow;
}
footer {
  grid-area: ft;
  background-color: palegreen;
}

总结

  • grid布局常用的几个属性,比如grid-template-columnsgrid-template-rows控制网格的列与行

  • grid-colunms-gapgrid-rows-gap设置列与行之间的间距,row-gapcolumn-gap是它们的简写

  • grap可以设置row-gapcolumn-gap

  • grid-column-startgrid-column-end来设置列的跨度,grid-column: 1/2grid-row: 1/3可以替代它们

  • grid-area实现一个网站的headerslidemainfooter的布局

  • 本文code example