grid布局浏览器兼容_CSS Grid布局尝试

先看思维导图

9e7b35809c96cf79ea1f54d5f5647589.png

起步

首先搭好基本的结构

<div id="container">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
  <div class="item item-4">4</div>
  <div class="item item-5">5</div>
  <div class="item item-6">6</div>
  <div class="item item-7">7</div>
  <div class="item item-8">8</div>
  <div class="item item-9">9</div>
  <div class="item item-10">10</div>
  <div class="item item-11">11</div>
  <div class="item item-12">12</div>
  <div class="item item-13">13</div>
  <div class="item item-14">14</div>
  <div class="item item-15">15</div>
  <div class="item item-16">16</div>
</div>

这里我觉得一个问题是,grid布局下面的所有元素都是同等的,实际中可能还存在层级的关系,直接使用略微有不满足语义化的缺陷,当然开发者是可以自己组建层级,然后再针对每个层级继续布局下去的 。

给每个项目设置样式以区分

.item {
  font-size: 1em;
  text-align: center;
}
.item-1 {
  background-color: #b71c1c;
}
.item-2 {
  background-color: #c2185b;
}
.item-3 {
  background-color: #8e24aa;
}
.item-4 {
  background-color: #651fff;
}
.item-5 {
  background-color: #1a237e;
}
.item-6 {
  background-color: #2196f3;
}
.item-7 {
  background-color: #039be5;
}
.item-8 {
  background-color: #18ffff;
}
.item-9 {
  background-color: #009688;
}
.item-10 {
  background-color: #00c853;
}
.item-11 {
  background-color: #b2ff59;
}
.item-12 {
  background-color: #eeff41;
}
.item-13 {
  background-color: #fbc02d;
}
.item-14 {
  background-color: #ff6f00;
}
.item-15 {
  background-color: #e65100;
}
.item-16 {
  background-color: #6d4c41;
}

然后开始了,先把容器设为display: grid

d5ec5063d407ec68d4b23c40662e8dfb.png

我们看到每个项独占一行,因为默认是块级元素,如果想变为行内,要设置display: inline-grid,厂商前缀自己按照浏览器加上,我使用的是Chrome,不需要。

5273678c14d18269b5376eee741ab719.png

这两个设置跟flexinline-flex是相似的。

接下来就见真格了,以下先是设置网格布局容器上的属性。

grid-template-columns, grid-template-rows

可以看到如果不给每个项设置宽高就根本没法看,所以第一步要设置grid-template-columnsgrid-template-rows

数值

#container {
  display: grid;
  grid-template-columns: 100px 100px 100px 100px;
  grid-template-rows: 100px 100px 100px 100px;
} 

0d257fa2f9d1620284fe8d746b77e4e9.png

也可以使用百分比

#container {
  display: grid;
  grid-template-columns: 25% 25% 25% 25%;
  grid-template-rows: 100px 100px 100px 100px;
}

ba397e2c0e14a1078bc037629c787faa.png

看看如果设置的配置和实际元素数量不一致会怎么办

#container {
  display: grid;
  grid-template-columns: 25% 25% 25%;
  grid-template-rows: 100px 100px 100px;
}

c3b95aa70a331fbea8a155c01001bd73.png

如果是

#container {
  display: grid;
  grid-template-columns: 25% 25%;
  grid-template-rows: 100px 100px 100px;
}

7d9a5f17709bfe2c2cab53b09ae0d218.png

如果是

#container {
  display: grid;
  grid-template-columns: 25% 55%;
  grid-template-rows: 50px 100px 200px;
}

839daaac2dd0bf220d7b3e17350bf037.png

如果把方向从row变为column

#container {
  display: grid;
  grid-auto-flow: column;
  grid-template-columns: 25% 25%;
  grid-template-rows: 100px 100px 100px;
}

6ce619a55b51e3d85d99578eb1045175.png

可以得出结论就是前面row * col个元素是遵循设置内容,然后按照排列次序以及排列方向,延续row或者column的设置值。

repeat()

这个函数为懒人设置,表示重复多少次

#container {
  display: grid;
  grid-template-columns: repeat(3, 25%) 100px;
  grid-template-rows: repeat(2, 100px) repeat(2, 150px);
}

689d3685eeeb48ccefd57d0477990cea.png

repeat()里第二个参数还能指定多个项

#container {
  display: grid;
  grid-template-columns: repeat(2, 15% 25%);
  grid-template-rows: repeat(2, 100px 150px);
}

3340d81a895fed8a3bdfa3bc69a712ac.png

第一个值也可以不指定具体的数字,而用auto-fill表示尽量排下去,有点float的味道,此时不能确定另一个维度的设置会用到几个。

#container {
  display: grid;
  grid-template-columns: repeat(auto-fill, 200px);
  grid-template-rows: 50px 100px 150px 200px 250px; /*不知道可能用到几个 */
}

c2f28c4235f061b157d1f06f3d59c8c2.png

此时我把浏览器拉宽,排下来只有三行了,就只会用到grid-template-rows里的三项值。

cfb83c84e8923d7baf049a7b0ad33547.png

fr

这个关键字就相当于flex布局里的flex-grow,表示各元素之间的比例。

#container {
  display: grid;
  grid-template-columns: 1fr 2fr 3fr 4fr;
  grid-template-rows: 50px 100px 150px 200px;
}

b8df811aaae21c432e6c490df2250c99.png

配合绝对数值也是和flex里一样的

#container {
  display: grid;
  grid-template-columns: 1fr 2fr 3fr 100px;
  grid-template-rows: 50px 100px 150px 200px;
}

374436334562e0b828711a2ba9f2ea0a.png

minmax()

这个函数就类比于设置min-widthmax-width。下面我设置了个特殊情况,就是最小值要比最大值还来的大。

#container {
  display: grid;
  grid-template-columns: 1fr 1fr minmax(500px, 1fr) 1fr;
  grid-template-rows: 50px 100px 150px 200px;
}

此时500px是大于1fr的,我们看到

cdd9bac897b0251fd0ab9fb5b3118098.png

说明此时布局系统优先满足最小值的设定。

auto

auto关键词表示接盘,它就是一个接盘侠——把剩下的空间都分给我。

#container {
  display: grid;
  grid-template-columns: 1fr 1fr auto 1fr;
  grid-template-rows: 50px 100px 150px 200px;
}

346e2e6bd6fcc39c73d2db072a32e581.png
#container {
  display: grid;
  grid-template-columns: 100px 100px auto auto;
  grid-template-rows: 50px 100px 150px 200px;
}

363360aace4c08d94991e4eba632dab6.png

网格线名称

在这里还能指定网格线的名称,但此时还排不上用场,注意实际的网格线数要+1,四个格子就要有五根线。

#container {
  display: grid;
  grid-template-columns: [no1] 100px [no2] 100px [no3] 100px [no4] 100px [no5];
  grid-template-rows: 50px 100px 150px 200px;
}

grid-row-gap,grid-column-gap,grid-gap

它们用来设置网格之间的间隙,一般在网格布局中都会有这项设置,下图是antd的网格组件

5b3a762fb70364a631c8bdf213680d75.png
#container {
  display: grid;
  grid-template-columns: 100px 100px 100px 100px;
  grid-template-rows: 100px 100px 100px 100px;
  grid-row-gap: 20px;
  grid-column-gap: 10px;
  /* 或者
    grid-gap: 20px 10px;
    */
}

26bf16d152dec89936a574d12307c5d8.png

grid-template-areas

这个属性和刚才指定网格线类似,它是给区块指定名字,比如

#container {
  display: grid;
  grid-template-columns: 100px 100px 100px 100px;
  grid-template-rows: 100px 100px 100px 100px;
  grid-template-areas:
    "caocao caocao zhaoyun machao"
    "caocao caocao zhaoyun machao"
    "guanyu guanyu zhangfei zhangfei";
}

如果某个区块不需要名字,可以指定.

注意设置了区域名字后,区域两边的线会被自动命名,比如caocao的起始位置的水平网格线和垂直网格线叫做caocao-start,终止位置的水平网格线和垂直网格线叫做caocao-end。

grid-auto-flow

这个属性用来指定网格是先横向排列还是先纵向排列,跟flex布局里的flex-direction类似。

#container {
  display: grid;
  grid-auto-flow: column;
  grid-template-columns: 100px 100px 100px 100px;
  grid-template-rows: 100px 100px 100px 100px;
}

c61ea934721a1766f77edd67508e3405.png

这个属性上还能设置dense,要用一个具体的例子来说明这个属性的作用。

假设我们在1和2上设置宽度

 #container {
  display: grid;
  grid-auto-flow: row;
  grid-template-columns: 100px 100px 100px 100px;
  grid-template-rows: 100px 100px 100px 100px;
}

.item {
  font-size: 1em;
  text-align: center;
}

.item-1 {
  grid-column-start: 1;
  grid-column-end: 3;
  background-color: #b71c1c;
}

.item-2 {
  grid-column-start: 1;
  grid-column-end: 3;
  background-color: #c2185b;
}

此时的效果是

5d297f958a616204e042356fedc1ed0a.png

由于区块2另起了一行,区块1的一行都被空着,如果设置

#container {
  display: grid;
  grid-auto-flow: row dense;
  grid-template-columns: 100px 100px 100px 100px;
  grid-template-rows: 100px 100px 100px 100px;
}

7800085d3c959f0706d7521b4ac15df6.png

没有比见缝插针这个词更适合当前的场景了。

justify-items,align-items,place-items

justify-items针对单元项里的内容的水平位置,align-items针对单元项里的内容的垂直位置,它们都能取如下的值

  • start
  • end
  • center
  • stretch

设置成end看看效果

#container {
  display: grid;
  justify-items: end;
  grid-template-columns: 100px 100px 100px 100px;
  grid-template-rows: 100px 100px 100px 100px;
}

be8c6d2b61e097f6c15fd826317cfa5b.png

place-items就是justify-itemsalign-items的组合。

justify-content, align-content, place-content

justify-content是单元项在容器里的水平位置,align-content是单元项在容器里的垂直位置,它们可以取如下的值

  • start
  • end
  • center
  • stretch
  • space-around
  • space-between
  • space-evenly

让人想起了flex布局。

也试两个看看

#container {
  display: grid;
  justify-content: space-around;
  grid-template-columns: 100px 100px 100px 100px;
  grid-template-rows: 100px 100px 100px 100px;
}

dd11c9cdadd1ec773d64b81b33a9d6b3.png

改成end

627d9e7b6a2db4406dd931e4388334a6.png

同理place-content也是justify-contentalign-content的组合。

grid-auto-columns,grid-auto-rows

它们用来指定超出范围的那些单元项的设置,之前我们已经试过超出设置范围的单元项是什么样子的,用这两个配置能对它们多一层控制,比如

#container {
  display: grid;
  grid-template-columns: 25% 25% 25%;
  grid-template-rows: 100px 100px 100px;
  grid-auto-rows: 50px;
}

超出3 * 3 = 9个范围之后,多出来的单元项,将它们的高度设置为50px,可以将下图和上面的例子对比一下。

53eb0bcace01c9669e0493c0150b2ee6.png

对于那些设置了位置,使之不在grid-template-columnsgrid-template-rows范围之内的单元项(比如设置grid-column-startgrid-column-end),也被这两个配置影响。

grid-template, grid

跟flex一样,这两个也是合并的设置,反正我是记不住的

grid-template= grid-template-column + grid-template-rows + grid-template-areas

grid = grid-template-rows + grid-template-columns + grid-template-ares + grid-auto-rows + grid-auto-columns + grid-auto-flow

以下属性设置在单元项上

grid-column-start, grid-column-end, grid-row-start , grid-row-end, grid-column, grid-row

它们用来设置行的起点、终点和列的起点、终点,注意CSS里的起点都是以1开始的。

修改第一个单元项

.item-1 {
  background-color: #b71c1c;
  grid-column-start: 2;
  grid-column-end: 5;
}

89ca0f3df54d4466f848ecb910e78d29.png

针对这第一个单元项,还能再狠一点

.item-1 {
  background-color: #b71c1c;
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 2;
  grid-row-end: 4;
}

e8b1d61ba58ff71f0fb7c20fb278863c.png

可见是先把单元项1给排好,然后其他的依次按照grid-auto-flow的配置来排列。

另外刚才指定的网格线名称也能在这里使用了。

.item-1 {
  background-color: #b71c1c;
  grid-column-start: no2;
  grid-column-end: no5;
}

也能使用span来简单的指定跨越几个单元格。

.item-1 {
  background-color: #b71c1c;
  grid-column-start: span 2;
}

542a13007c3e678cd1a21eb043a2d1f6.png

或者

.item-1 {
  background-color: #b71c1c;
  grid-column-start: no2;
  grid-column-end: span 2;
}

3c61d83426e232cbaac4bc3ac9456572.png

grid-columngrid-row是以上的合并简写。比如

.item-1 {
  background-color: #b71c1c;
  grid-column: 1 / 3;
  /* 与以下相等
    grid-column-start: 1;
    grid-column-end: 3;
    */
  /* 与以下相等
    grid-column: 1 / span 2;
    */
}

grid-area

grid-area就会用到刚才指定的区块名字,比如刚才曾经指定

#container {
  display: grid;
  grid-template-columns: [no1] 100px [no2] 100px [no3] 100px [no4] 100px [no5];
  grid-template-rows: 100px 100px 100px 100px;
  grid-template-areas:
    "caocao caocao zhaoyun machao"
    "caocao caocao zhaoyun machao"
    "guanyu guanyu zhangfei zhangfei";
}

现在可以设置第一个区块为

.item-1 {
  background-color: #b71c1c;
  grid-area: caocao;
}

那最终第一个区块就占据了名字为caocao的区域

96a0e334ddebe49dac08e981517ffcae.png

当然也能用数字来指定

.item-1 {
  grid-area: 1 / 1 / 3 / 3;
}

justify-self, align-self, place-self

这几个跟flex布局里的align-self很相似,都是调整单元项在父级容器里的位置。

justify-self调整单元项在父级容器里的水平位置,align-self调整单元项在父级容器里的垂直位置,place-self理所当然是它们的合并方式,可以取如下的值

  • start
  • end
  • center
  • stretch

最后做一个综合的例子——华容道

b5ef253775e81fbe36e53b131ee15915.png

选用最傻瓜的方式——指定grid-area

<!DOCTYPE html>
<html>
  <head>
    <title>华容道</title>
    <style>
      #container {
        display: grid;
        grid-template-columns: 100px 100px 100px 100px;
        grid-template-rows: 100px 100px 100px 100px 100px;
        grid-template-areas:
          "zhaoyun caocao caocao huangzhong"
          "zhaoyun caocao caocao huangzhong"
          "zu1 machao . zu2"
          "zu3 machao . zu4"
          "guanyu guanyu zhangfei zhangfei";
      }
      .item {
        font-size: 1em;
        display: flex;
        align-items: center;
        justify-content: center;
        color: white;
      }

      .item-1 {
        background-color: #b71c1c;
        grid-area: zhaoyun;
      }
      .item-2 {
        background-color: #c2185b;
        grid-area: caocao;
      }
      .item-3 {
        background-color: #8e24aa;
        grid-area: huangzhong;
      }
      .item-4 {
        background-color: #651fff;
        grid-area: zu1;
      }
      .item-5 {
        background-color: #651fff;
        grid-area: zu2;
      }
      .item-6 {
        background-color: #009688;
        grid-area: zu3;
      }
      .item-7 {
        background-color: #00c853;
        grid-area: zu4;
      }
      .item-8 {
        background-color: #2196f3;
        grid-area: machao;
      }
      .item-9 {
        background-color: #546e7a;
        grid-area: guanyu;
      }
      .item-10 {
        background-color: #e65100;
        grid-area: zhangfei;
      }
    </style>
  </head>
  <body>
    <div id="container">
      <div class="item item-1">赵云</div>
      <div class="item item-2">曹操</div>
      <div class="item item-3">黄忠</div>
      <div class="item item-4">卒</div>
      <div class="item item-5">卒</div>
      <div class="item item-6">卒</div>
      <div class="item item-7">卒</div>
      <div class="item item-8">马超</div>
      <div class="item item-9">关羽</div>
      <div class="item item-10">张飞</div>
    </div>
  </body>
</html>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值