grid内容删除横线样式_CSS从零开始——进阶样式(3)网格布局a

本文详细介绍了CSS Grid布局的概念,包括容器、项目、行和列、单元格和网格线的基本概念。接着讲解如何定义网格容器,如设置行和列、使用repeat()函数、比例填充fr单位,以及自动长度和minmax()函数。此外,还涉及了网格间距的设定和项目摆放顺序的控制。通过实例展示了Grid布局的强大和灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

284a49623678951e166b588b18509b1d.png

我疏忽了,忘记把这几章节放在布局那边了,不过后来想想还是独立成章更好一点,所以在进阶样式中间插入几个章节,叫做网格布局。

网格布局,即 grid 布局,虽然有不少人都说它是“最强大”的布局方案,但我认为没有哪一种一定比另一种强的说法,只有在什么时候适合用什么布局,目前如果真的是从零开始了解 CSS 的话,我还是觉得弹性盒子 display: flex; 这种更加直观,所以优先介绍了——正好自己重新学一次挺好的。

不过,不可否认的是,网格布局的确在很多时候是优于弹性盒子布局的,因为:

  • flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局
  • grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局

所以接下来就看看网格布局到底有多强大(很多内容参考自阮一峰老师的博客:CSS Grid 网格布局教程,如果有兴趣可以看看原文)。


1 概念

CSS 3 引入网格布局,是一次大革新,它把网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局。以前,只能通过复杂的 CSS 框架达到的效果,现在浏览器内置了,如下例(非常简单):

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>hello</title>
    <style>
      .container {
        width: 600px;
        height: 600px;
        display: grid;
        grid-template-columns: 33% 33% 33%;
        grid-template-rows: 33% 33% 33%;
      }
      .item {
        border: thin solid black;
        text-align: center;
        font-size: 64px;
        color: white;
        line-height: 200px;
      }
      #div1 {
        background: red;
      }
      #div2 {
        background: orange;
      }
      #div3 {
        background: yellow;
      }
      #div4 {
        background: green;
      }
      #div5 {
        background: blue;
      }
      #div6 {
        background: aqua;
      }
      #div7 {
        background: purple;
      }
      #div8 {
        background: brown;
      }
      #div9 {
        background: grey;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="item" id="div1">1</div>
      <div class="item" id="div2">2</div>
      <div class="item" id="div3">3</div>
      <div class="item" id="div4">4</div>
      <div class="item" id="div5">5</div>
      <div class="item" id="div6">6</div>
      <div class="item" id="div7">7</div>
      <div class="item" id="div8">8</div>
      <div class="item" id="div9">9</div>
    </div>
  </body>
</html>

6f5499b8ab0e5e96ca9c5f0651db249f.png

接下来我们可以来看看网格布局的一些基础概念先:

1.1 容器和项目

采用网格布局的区域,称为容器(container),容器内部采用网格定位的子元素,称为项目(item),比如上面例子里面的 div

    <div class="container">
      <div class="item" id="div1">1</div>
      <div class="item" id="div2">2</div>
      <div class="item" id="div3">3</div>
      <div class="item" id="div4">4</div>
      <div class="item" id="div5">5</div>
      <div class="item" id="div6">6</div>
      <div class="item" id="div7">7</div>
      <div class="item" id="div8">8</div>
      <div class="item" id="div9">9</div>
    </div>

最外层的 div.container 就是容器,而内层所有的 div.item 就是项目了;留意,项目必须是容器内的第一层子元素,不能再嵌套,比如里面还有个 <p> 标签,就不能再作为项目了,因为网格无法识别。

1.2 行和列

容器里面的水平区域称为行(row),垂直区域称为列(column),如下图:

e6972db05d7cdc609d363a54fd48e0ea.png

这个应该比简略图直观一点,如果不好懂,等你们反馈哦。

1.3 单元格

其实就是行列相交的位置,一个个小格子(和Excel里面的单元格是一个意思),也就是 cell;比如上图中,有9个单元格,因为它是由3行和3列构成的,也就是3 * 3 = 9

1.4 网格线

划分网格的线,称为网格线(grid line),两条水平网格线之间就是行,两条垂直网格线之间就是列。

正常情况下,n 行有 n + 1 根水平网格线,m 列有 m + 1 根垂直网格线,比如三行就有四根水平网格线:

74ffc545fcbd57db915538a8769a1173.png

垂直网格线也是一样的,就不单独截图了。

2 网格容器

为了使用网格布局,首先要定义网格容器,我们可以直接在容器上使用 display 属性来声明一个容器,其格式如下:

display: grid | inline-grid | subgrid
  • grid:定义一个块级的网格容器
  • inline-grid:定义一个内联的网格容器
  • subgrid定义一个继承其父级网格容器的行和列的大小的网格容器,它是其父级网格容器的一个子项,不同目前仅有 Firefox 支持,所以目前不建议使用

其中我们最常用的还是 grid,除非有特殊原因,很少使用 inline-grid,所以接下来就主要针对 grid 这个值来继续介绍。

特别要注意一点:设为网格布局以后,容器子元素(项目)的floatdisplay: inline-blockdisplay: table-cellvertical-align column-* 等设置都将失效。

2.1 定义容器的行列

容器指定了网格布局以后,接着就要划分行和列,grid-template-columns 属性定义每一列的列宽,grid-template-rows 属性定义每一行的行高,比如最开始的例子:

      .container {
        width: 600px;
        height: 600px;
        display: grid;
        grid-template-columns: 33% 33% 33%; /* 列宽 */
        grid-template-rows: 33% 33% 33%; /* 行高 */
      }

上面的代码,指定了3列,每列宽是总宽度 600px 33%;同时指定了3行,每行高是总高度 600px 33%

当然,也可以直接使用具体的数值,比如我们明确的知道 600px1/3200px,这里也可以写成:

      .container {
        width: 600px;
        height: 600px;
        display: grid;
        grid-template-columns: 200px 200px 200px; /* 列宽 */
        grid-template-rows: 200px 200px 200px; /* 行高 */
      }

上面这样的写法,肯定会有人说,只有3行3列这样写还好,如果是9列10多行怎么办?不用担心,CSS 3 没有那么傻的。

(1)重复函数

其实 CSS 3 也提供了一个 repeat() 函数,上面的代码可以写成这样:

      .container {
        width: 600px;
        height: 600px;
        display: grid;
        grid-template-columns: repeat(3, 200px); /* 列宽 */
        grid-template-rows: repeat(3, 200px); /* 行高 */
      }

repeat() 可以接受两个参数,前面一个是重复次数,后面一个是重复的内容,也就是说,如果我们这样写,也可以:

      .container {
        width: 600px;
        height: 600px;
        display: grid;
        grid-template-columns: repeat(2, 10% 20%);
        grid-template-rows: repeat(3, 200px);
      }

网格列,将按照每列2个不同宽度,重复2次,而行将保持不变,结果如下:

b20a68e6f7d91fb577644aee471957b8.png

(2)自动填充

有时,单元格的大小是固定的,但是容器的大小不确定。如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用 auto-fill 关键字表示自动填充:

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

dbd12cea87586cba0ce7f89d58de5be7.png

这里可以注意到,由于没有设置行高,所以自动填充成两行之后,行高变成了容器总高度的1/2

(3)比例填充

为了方便表示比例关系,网格布局提供了 fr 关键字(fraction 的缩写,意为"片段")。如果两列的宽度分别为 1fr 2fr,就表示后者是前者的两倍:

      .container {
        width: 600px;
        height: 600px;
        display: grid;
        grid-template-columns: 1fr 2fr;
      }

1ce6b0b9132275bfbe8a6cc1d9a6f60b.png
这里也可以注意到,容器的总高度被突破了,不再是 600px

fr 关键字可以和长度数值结合起来使用,这样更加灵活和方便,比如:

      .container {
        width: 600px;
        height: 600px;
        display: grid;
        grid-template-columns: 100px 1fr 2fr;
      }

b6d08ef2cc8dae86a762cb49118a2c65.png

这里比较有意思,可以算一下:原本是 600px,第一列设置为 100px,则第二列是 (600px - 100px) / 3 ≈ 166.7px,第三列则是第二列的两倍。

(4)长度范围

minmax() 函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值:

grid-template-columns: minmax(0, 2fr) minmax(0, 2fr) minmax(0, 1fr);

cbf12be4084214365249553253670a44.png

(5)自动长度

auto 关键字表示由浏览器自己决定长度,我个人喜欢把它用在 minmax() 里面:

grid-template-columns: minmax(20px, auto) 1fr 1fr;

1645bb6b69f4a01a1403f5ef1876d04b.png

如果使用 auto 和固定长度单位来设置的话,则该列(行)的长度会自动调整为最大长度,比如:

grid-template-columns: auto 150px 150px;

2918eafb4c51b52ec8dc0df26188aa33.png

此时,auto 也就是 300px (= 600px - 150px - 150px)

(6)网格线的名称

grid-template-columns 属性和 grid-template-rows 属性里面,还可以使用方括号,指定每一根网格线的名字,方便以后的引用(这个我还真的没用过):

grid-template-columns: [c1] auto [c2] 150px [c3] 150px [c4];
grid-template-rows: [r1] 200px [r2] 200px [r3] 200px [r4];

上面代码指定网格布局为3行3列,因此有4根垂直网格线和4根水平网格线。方括号里面依次是这八根线的名字。

网格布局允许同一根线有多个名字,比如[fifth-line row-5]

通过上面的各个例子,其实我们可以发现,如果仅仅是需要做网页布局的话,grid-template-columns 就已经非常方便了,比如 SharePoint 常用3栏式布局,其样式声明只需要两行 CSS 代码就可以实现了:

#container {
  display: grid;
  grid-template-columns: 15% 80% 5%;
}

2.2 定义容器区域

grid-template-areas 属性用于定义区域,一个区域由单个或多个单元格组成,比如:

      .container {
        width: 600px;
        height: 600px;
        display: grid;
        grid-template-columns: 33% 33% 33%;
        grid-template-rows: 33% 33% 33%;
        grid-template-areas: 'a b c'
                             'd e f'
                             'g h i';
      }

上面代码先划分出9个单元格,然后将其定名为 a i 的九个区域,分别对应这九个单元格,当然还可以合并,只要把命名写成一样的就可以了,如下:

      .container {
        width: 600px;
        height: 600px;
        display: grid;
        grid-template-columns: 33% 33% 33%;
        grid-template-rows: 33% 33% 33%;
        grid-template-areas: 'a a a'
                             'b b c'
                             'd d d';
      }

这样的写法,则最上面一行全都合并为区域 a,中间的前两格合并为区域 b,下面一行合并为区域 d

如果有区域是不需要使用的,可以通过 . 来标记:

      .container {
        width: 600px;
        height: 600px;
        display: grid;
        grid-template-columns: repeat(4, 25%);
        grid-template-rows: repeat(3, 33.3%);
        grid-template-areas: 'a a . b'
                             'c c . b'
                             'd d . e';
      }
注意,区域的命名会影响到网格线。每个区域的起始网格线,会自动命名为区域名-start,终止网格线自动命名为区域名-end
比如,区域名为 header,则起始位置的水平网格线和垂直网格线叫做 header-start,终止位置的水平网格线和垂直网格线叫做 header-end

不过单独定义容器的区域还没有将定义过程完整走下来,接下来还需要定义项目的区域名,之后在介绍项目属性的时候再完善整个流程。

2.3 定义行列间距

默认的网格,项目之间是没有间距的,为了让项目看起来更分明,我们可以通过定义行列的间距,来分割开各个项目。

CSS 3 提供了三个和网格间距有关的属性:

  • row-gap:定义行间距
  • column-gap:定义列间距
  • gap:简写属性,定义行列间距

下面是个例子:

      .container {
        width: 600px;
        height: 600px;
        display: grid;
        grid-template-columns: repeat(3, 33%);
        grid-template-rows: repeat(3, 33%);
        row-gap: 10px;
        column-gap: 10px;
      }

efdee147beae2a35617b43274b653f3c.png

如果使用 gap 则更简单,可以改写成如下代码:

      .container {
        width: 600px;
        height: 600px;
        display: grid;
        grid-template-columns: repeat(3, 33%);
        grid-template-rows: repeat(3, 33%);
        gap: 10px 10px;
      }

如果 gap 省略了第二个值,浏览器认为第二个值等于第一个值。

这里要插一句,因为最新标准改成了 gap,其实之前是 grid-gap,也就是说新标准把 grid- 这部分给去除了,所以看到老代码的时候,出现了 grid-row-gap 之类的别奇怪,其实就是现在的 row-gap

2.4 项目摆放顺序

划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是“先行后列”,即先填满第一行,再开始放入第二行,即之前例图的顺序,可以再看一次:

e0c44b90f7306d3c64b2b09791bcdf46.png

我们可以通过 grid-auto-flow 这个属性来控制项目的摆放顺序,比如先列后行:

grid-auto-flow: column;

88aa09d9002f8204d538e1e852c313b6.png

grid-auto-flow 可以接受如下值:

  • row:默认值,先行后列
  • column:先列后行
  • dense:按照先后顺序排列,一般与 row 或者 column 同时设置,因为它本身不存在方向性

前面两个都比较好理解,dense 稍稍不好理解,我们可以参考下面的例子:

(1)当1和2号项目都占了两个单元格的时候,默认的 grid-auto-flow: row; 会产生下图这样子:

722ac38e140c3f162ced878373a00ade.png

当我们使用 grid-auto-flow: row dense; 的时候,项目1后面的空白单元格就会被项目3填充:

      .container {
        width: 600px;
        height: 600px;
        display: grid;
        grid-template-columns: repeat(3, 33%);
        grid-template-rows: repeat(3, 33%);
        gap: 10px 10px;
        grid-auto-flow: row dense;
      }

8326868e97164163a7f099942effd213.png

(2)如果我们使用 grid-auto-flow: column; 并且项目1和2占据了上下两个单元格的时候,项目1下面会出现空白单元格:

5e519eebbe96be4623b8e5153101b935.png

而如果我们使用 grid-auto-flow: column dense; 的时候,则项目1下面的空白的单元格会被项目3填充:

grid-auto-flow: column dense;

a197b54bfdba2653cda61e5104075a86.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值