你还在苦苦寻找好的grid网格布局教程?嘿!bro!这可能是你看过最好的入门教程了

292 阅读9分钟

前言

事情起因是这样的,有粉丝通过私信找到了作者的联系方式,想让作者出一篇关于基本布局方面的知识。

ae659139aa4cc67e8f272128b985f75.jpg

原本我是准备写些CSS黑科技的。但是能让粉丝等吗?我直直直接从床上跳起来码文章,接下来几天我会将css的基础全部给大家讲一遍。

正式讲解

本文不会给大家讲解太多的属性,主要介绍常用的。况且一篇文章太长了其实教学效果也不好

网格容器

示例代码:

  <div class="container">

  </div>
    .container {
      display:  grid;
      grid-template-rows:100px 100px 100px 100px
    }

Grid

grid:表示启用Grid布局,container下的元素都会按照Grid布局方式进行排列。

grid-template-rows

grid-template-rows:100px 100px 100px 100px:定义网格的行轨道,按照100px,100px,100px,100px划分四行。

image.png

grid-template-columns

同理我们有定义列轨道grid-template-columns

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

grid-template-columns:100px 100px 100px :定义了网格的列轨道,按照100px,100px,100px来划分三列

image.png

fr

我们有时候会看到frfr是什么呢?🤔

fr 是 CSS Grid 布局中的一个长度单位,它代表了网格容器中可用空间的一部分(fraction)。当使用 fr 时,它会根据网格容器中剩余的空间来分配大小。

比如 grid-template-columns:100px 100px 100px 1fr 如图 image.png 浏览器会自动将剩余的地方分配给fr

如果有多个 fr 单位,它们会根据各自的比例来分配剩余空间,如图 grid-template-columns:100px 100px 100px 1fr 1fr image.png

repeat

我们发现100px 100px 100px这种写法太麻烦了,并且代码特别长,有没有简单的写法呢?

我们可以使用repeat

  grid-template-rows: repeat(3,100px) 50px;
  grid-template-columns: repeat(3,100px) repeat(2,1fr);

image.png 发现效果是一样的

网格项

  <div class="container">
    <div class="item1">1</div>
    <div class="item2">2</div>
    <div class="item3">3</div>
  </div>

如果你采Grid布局,你写的元素会自动填充满你所写的网格之中,也就是说我们修改网格,在不设置元素的宽高的时候,会随着网格的变化而变化。

      grid-template-columns: repeat(5, 100px);
      grid-template-rows: repeat(5,100px);

image.png

修改后

grid-template-rows: 200px 250px;
grid-template-columns: 100px 200px;

image.png

排序顺序

网格里面的内容默认排序顺序是从左到右从上到下。

比如从左到右第一行铺满了,那么就会进入下一行继续从左到右排列,效果如图 image.png

基本用法

这里都是对3号盒子进行演示

grid-column

我们如何想移动元素在网格里的位置呢?

我们可以使用grid-column

.item3 {
      background-color: red;
      text-align: center;
      grid-column: 5;
    }

image.png grid-column可以将元素移动到你指定的列位置,grid-colum :5 就表示将元素移动到第五列的位置。

grid-row

同理移动行也是。我们可以使用grid-row


    .item3 {
      background-color: red;
      text-align: center;
      grid-column: 5;
      grid-row: 2;
    }

image.png

grid-row可以将元素移动到你指定的列位置,grid-row :2 就表示将元素移动到第五列的位置。

改变元素在网格中的大小

那我们如何在不操作元素本身的宽高的前提下,改变每个元素在网格中的位置和大小呢?🤔

grid-column: start-line / end-line

grid-column 属性,其用于定义网格项目在网格布局中的列位置,接受的语法 grid-column: start-line / end-line; 决定了元素在网格中水平方向的位置和跨度。

例如: grid-column:3/5

image.png 这段代码的意思是网格项目放置在从第 3 条垂直网格线开始,到第 5 条垂直网格线结束的区域,跨越 2 列

可能会有人觉得这太麻烦了,我还要看网格线,有没有更好的方式,比如公式之类的。

你别说还真有!

你想要开始的位置加上你想要占据的高度或者宽度,也就是start position / start position + want row/column

例如 如果你想让一个元素从第 4 列开始,并占据 2 列的宽度,那么代码就是grid-column: 4 / 4+2;也就是 grid-column: 4 / 6;

image.png

grid-column: start-line / end-line

同理行也是,其用于定义网格项目在网格布局中的行位置,接受的语法 grid-column: start-line / end-line; 决定了元素在网格中数值方向方向的位置和跨度。

比如我想让item3,从第3行开始,并且占据2行的高度,怎么做呢?

我们直接套公式 grid-row:3/3+2 也就是 grid-row;3/5

image.png

二者一起用

grid-column : 3/5;
grid-row: 3/5;

image.png

重叠

当我们在移动元素或者改变元素大小的时候,可能会出现两个原元素重叠的情况。

比如 我们能清晰的看到item1被挡住了,和我们在学习CSS定位时候的情况一样。 image.png

如何解决呢?

z-index

图层,默认情况在我们所有元素都位于一个图层,默认是0图层,默认情况在z-index是0,那我们现在应该也知道怎么才能做到1不被3挡住。

只需要修改item1z-index,让它比0大即可

此时我们发现不再被挡住 image.png

同理,如果想要item3不被挡住,你需要修改item3的z-index比item1

image.png

高级用法

grid-area

上面我们介绍了如何改变网格内容的大小和位置,发现要写两行太麻烦了,有没有其他方式呢?

grid-area可以用来定义网格项目在网格容器中的位置

具体语法如下

grid-area: grid-row-begin /grid-column-begin /grid-row-end /grid-column-end;
  • 第一个值表示网格项目的起始行位置。
  • 第二个值表示网格项目的起始列位置。
  • 第三个值表示网格项目的结束行位置。
  • 第四个值表示网格项目的结束列位置。

例如

    grid-area: 2/3/5/5;

表示这个特殊元素将从第 2 条水平网格线开始,第 3 条垂直网格线开始,到第 5 条水平网格线结束,第 5 条垂直网格线结束,即在网格中占据了一个矩形区域 image.png

有小伙伴发现这还有数网格线,还不如上面那个套公式方法好用。别急,这个 grid-area有大用!

grid-template-area画图法

上面东西是不是有点难懂,没关系,借用宋浩老师一句话,通通不用学(开个玩笑😄)。

我们直接用grid-template-area来画图就行, grid-template-area 是 CSS 中用于网格布局(Grid Layout)的一个属性,它允许你使用命名区域来定义网格的布局结构。

我们直接看代码

    .container {
  display: grid;
  grid-template-rows: repeat(5,100px);
  grid-template-columns: repeat(5,100px) ;
  grid-template-areas: 
  '.        .          .          .          .'

  '.        .          .          .          .'

  '.        .          .          .          .'

  '.        .          .          .          .'

  '.        .          .          .          .'
}

这些点是什么?🤔

每个点代表一个网格,所以这里代表的就是我们5*5的网格

此时我们修改下网格的内容

  .item3 {
    background-color: red;
    grid-item:item3
  }
  
  .item2 {
    background-color: red;
    grid-area:item1
  }
  
  .item1 {
    background-color: orange;
    grid-area:item1
  } 

我们给grid-area都指定了一个名字,现在可能有大佬已经猜到我要进行什么骚操作了。😄,没错,我直接画!!

    grid-template-areas:
        'item1        .          .          .          .'

        '.        item2          .          .          .'

        '.        .          .          .          .'

        '.        item3          .          .          .'

        '.        .          .          .          .'

是不是炒鸡简单? image.png

我们如果想改变它的大小怎么办,也很简单,只需要继续画即可。

grid-template-areas:
        'item1    item1          .          .          .'

        '.        item2          .          .          .'

        '.        .          .          .          .'

        '.        item3          .          .          .'

        '.        item3          .          .          .'

image.png

这种方法非常直观,并且我们不需要去关注grid的相关API,想要他变成什么样直接话就行

当然有时候因为业务,你同事写的代码你看不懂,那你还是要去学习下相关的API。🌚

响应式布局

整齐排列情况

这里我准备了几张图片

    img {
      width: 100%;
    }
    .container {
      display:  grid;
      grid-template-columns: repeat(4, 250px);
      justify-content: center;
      gap: 20px;
    }
<body>
  <div class="container">
    <img src="./assets/4.webp">
    <img src="./assets/4.webp">
    <img src="./assets/4.webp">
    <img src="./assets/4.webp">
    <img src="./assets/4.webp">
    <img src="./assets/4.webp">
    <img src="./assets/4.webp">
    <img src="./assets/4.webp">
  </div>
</body>

我们发现它是没有响应式效果的

298c4eb6-39d3-4f38-97ed-7480596c279c.gif

那我们如何做呢,两种方法,1.是media,2是auto-fill

media

@media screen and (max-width: 1024px) {
  .container {
    grid-template-columns: repeat(3, 250px);
  }
}

@media screen and (max-width: 767px) {
  .container {
    grid-template-columns: repeat(2, 250px);
  }
}

3a448b9f-eaec-46e2-9dfe-0504e73e3804.gif

可以发现的确实现了响应式效果,但是这种方式在这种整齐排列的的布局上是非常浪费时间的,我们有更简单的方法。

auto-fill

我们只需要更改一段代码

grid-template-columns: repeat(auto-fill, 250px);

3a448b9f-eaec-46e2-9dfe-0504e73e3804.gif 同样实现了响应式布局。

随机排列

当然,我们常常也会遇到类似这样的随机布局。

image.png

这种情况我们只能使用@meida了😂,当然也并不难,改改几个代码而已。

<body>
  <main>
    <div class="header">Header</div>
    <div class="feature-yellow">YELLOW</div>
    <div class="feature-purple">PURPLE</div>
    <div class="feature-red">RED</div>
    <div class="sign-up">SIGNUP</div>
    <div class="content">CONTENT</div>
  </main>
</body>

    main {
      font-size: 40px;
      text-align: center;
      display: grid;
      grid-template-columns: repeat(auto-fill,1fr);
      grid-template-rows: 200px 250px 150px auto; 
      grid-template-areas:
        "header header header"
        "fYellow fPurple fRed"
        "signUp signUp signUp"
        "content content content";
    }
.header {
      grid-area:header;
    }
  .feature-yellow {
      grid-area:fYellow;
    }
  .feature-purple {
      grid-area:fPurple;
    }
  .feature-red {
      grid-area:fRed;
    }
  .sign-up {
      grid-area:signUp;
    }
  .content {
      grid-area:content;
    }

  .header {
      background-color: orange;
    }
  .feature-yellow {
      background-color: #ff0;
    }
  .feature-purple {
      background-color: #f0f;
    }
  .feature-red {
      background-color: #f00;
    }
  .sign-up {
      background-color: #00f;
    }
  .content {
      background-color: #0f0;
    }

image.png 不用我说也知道没有响应式效果。

那我们如何使用@media实现那种随机排列的响应式效果呢?

很简单,只需要画就行了🤣

/* 当屏幕宽度小于 768px 时的布局调整 */
    @media (max-width: 768px) {
      main {
        grid-template-columns: 1fr;
        grid-template-rows: 150px 150px 150px 150px 150px 200px;
        grid-template-areas:
          "header"
          "fYellow"
          "fPurple"
          "fRed"
          "signUp"
          "content";
        font-size: 30px;
      }
    }
    /* 当屏幕宽度在 768px 到 1024px 之间时的布局调整 */
    @media (min-width: 768px) and (max-width: 1024px) {
      main {
        grid-template-columns: 1fr 1fr;
        grid-template-rows: 150px 200px 150px 250px;
        grid-template-areas:
          "header header"
          "fYellow fPurple"
          "fRed signUp"
          "content content";
        font-size: 35px;
      }
    }

fab4191d-7b4a-4f1c-9ad0-089b972e0da7.gif 实现辣!也没有多难不是吗?😄

初学者入门学习这么多够用了,如果大家后期遇到看不懂的代码再去查阅相关资料就可以了。