CSS Grid 笔记

2019-06-13

反复看了几遍陈慧晶老师在第五届css conf中的新时代CSS布局的主题演讲,有很多收获,在演讲中许多体会自己也在日常中有些体会,对于老师的观点也很认同。grid布局之前自己仅仅是看过文档和玩过一个关于css grid的game,并未记录过相关笔记,这次好好记录一下,加深自己印象的同时,又当做一个自己可以查阅的资料。

grid属性

看完一遍grid的文档之后将其相关属性整理并手写一遍。 关于grid的css属性主要分为容器(grid container)属性项目(grid item)属性

容器属性


display: grid /*指定一个容器采用网格布局(块级元素) */
display:inline-grid /*指定一个容器采用网格布局(行内元素)*/
grid-template-columns:1fr 1fr 1fr /*定义每一个列的宽度*/
grid-template-rows:1fr 1fr 1fr /*定义每一个行的高度*/
grid-template-rows: repeat(3, 1fr); /*repeat()函数重复 重复的次数,重复的值*/
grid-column-gap:10px /* 定义列间距 */
grid-row-gap:10px /*定义行间距*/
grid-template-areas:  'a b c'
                      'd e f'
                      'g h i'; /* grid-template-areas属性用于定义区域 */
grid-auto-flow:row /*规定容器的子元素排列顺序 默认是先行后列 column 先列后行*/
justify-items:start  /*justify-items属性设置单元格内容的水平位置(左中右)*/
align-items:start /* align-items属性设置单元格内容的垂直位置(上中下) */
place-items:start start /* align-items属性和justify-items 简写*/
justify-content:start /*justify-content属性是整个内容区域在容器里面的水平位置(左中右)*/
align-content:start /*align-content属性是整个内容区域的垂直位置(上中下)*/
place-content: <align-content> <justify-content> /* place-content是简写形式。*/
grid-auto-rows:20px; /*设置浏览器自动创建的多余网格的列宽和行高*/
grid-auto-columns:20px; /*设置浏览器自动创建的多余网格的列宽和行高*/

项目属性

grid-column-start:  2 /* 左边框所在的垂直网格线 */
grid-column-end: 4 /* 右边框所在的垂直网格线 */
grid-row-start: 2  /* 上边框所在的水平网格线 */
grid-row-end: 4  /* 下边框所在的水平网格线 */
grid-column: grid-column-start / grid-column-end
grid-row: grid-row-start / grid-row-end
grid-area:header /*指定项目放在哪一个区域*/
justify-self:start /* 设置单元格内容的水平位置(左中右) */
align-self:start /* 设置单元格内容的垂直位置(上中下) */
place-self:<align-self> <justify-self>

特别说明

repeat函数

.grid-container {
  display: grid;
  grid-template-columns: repeat(2, 100px);
}

repeat接受两个参数,第一个参数是重复的次数,第二个是要重复的值(模式)grid-template-columns: repeat(2, 100px)

auto-fill 关键字

.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
}

auto-fill关键字表示自动填充,每列宽度100px,然后自动填充,直到容器不能放置更多的列。

fr关键字

.grid-container {
  display: grid;
  grid-template-columns: 1fr 2fr 4fr;
}

fr表示网格布局当中的比例关系,上述表示第二列是第一列的两倍,第三列是第二列的两倍。

minmax函数

.grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr minmax(100px, 1fr);
}

minmax()函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。上述表示第三列最小值为100px 最大不能超过1fr

auto关键字

.grid-container {
  display: grid;
  grid-template-columns: 100px auto 100px;
}

表示由浏览器自己决定长度,第二列的宽度等于其本身的最大宽度。

网格线的名称

.grid-container {
  display: grid;
  grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
}

使用方括号,指定每一根网格线的名字,方便设置grid-column-start使用网格线的名字。

实践

传统布局实现方式

布局

思考一下我们通过grid如何实现这样的布局,grid(网格)布局,其实我们就可以考虑成网格,我们一共将页面分为了5块,也就是共有五个区域,这个时候我们就可以利用容器属性grid-template-areas来为我们的gird容器设置区域,然后再通过我们的项目属性grid-area为项目指定相关区域。

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>grid_demo</title>
  <style>
    .grid-container{
      display: grid;
      grid-template-columns: repeat(4,1fr);
      grid-template-rows: repeat(4,1fr);
      grid-template-areas: "header header header header"
                           "menu main main right"
                           "menu main main right"
                           "menu footer footer footer";
      gap: 10px 20px;
      width: 80vh;
      height: 90vh;
      padding: 10px;
      background: #fff;
      border: 1px solid #1d39c4;
    }
    .grid-item{
      display: grid;
      align-items: center;
      font-size: 32px;
      text-align: center;
      color: #000;
      background: pink;
      border: 1px solid #fff;
    }
    .grid-item:nth-of-type(1){
      grid-area: header;
    }
    .grid-item:nth-of-type(2){
      grid-area: menu;
    }
    .grid-item:nth-of-type(3){
      grid-area: main;
    }
    .grid-item:nth-of-type(4){
      grid-area: right;
    }
    .grid-item:nth-of-type(5){
      grid-area: footer;
    }
  </style>
</head>
<body>
  <div class="grid-container">
    <div class="grid-item">header</div>
    <div class="grid-item">menu</div>
    <div class="grid-item">main</div>
    <div class="grid-item">right</div>
    <div class="grid-item">footer</div>
  </div>
</body>
</html>

flexbox是一维的,gird是二维的,在开发需求中flexbox并不一定能够满足所有的需求,grid和flexbox结合才可以将页面做的更好。

目前浏览器对于grid也有了不错的支持,对于一些旧的浏览器完全可以通过@supports,本地css功能检测来做一下兼容

.selector {
  /* Styles that are supported in old browsers */
}

@supports (property:value) {
  .selector {
    /* Styles for browsers that support the specified property */
  }
}