CSS(四)详解Grid布局

本文是CSS布局系列的第四部分,重点介绍了Grid布局,包括容器属性如grid-template-row、grid-template-columns、grid-template-areas等,以及项目属性如grid-column-start、grid-column-end等。Grid布局是一种强大的二维布局方式,与Flex布局不同,它分为行和列,适用于复杂网页设计。文章通过实例解释了各种属性的用法,并提供了参考资料。

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

这是一个系列的文章,你也可以查看其他文章:

0、CSS-预热篇

1、CSS(一)详解position

2、CSS(二)transform

3、CSS(三)flex布局(flex弹性布局详解)

4、CSS(四)详解Grid布局

5、CSS(五)CSS动画-transition简介

6、CSS(六)CSS动画-animation简介

7、CSS(七)两栏布局详解

Grid布局又叫做网格布局。是一种强大二维布局,Flex布局是一维布局。

Grid布局和Flex布局类似,Grid布局也分容器和项目两部分。但和Flex不同的是,在容器内部,分为row和column(而不是Flex布局的轴和交叉轴),row和column交叉的部分叫cell,划分cell的线叫做gridline。

正常情况下,n(n>=1) 行和m(m>=1)列的布局产生n*m个 单元格(cell),n行(列)有n+1条girdline(网格线),例如3行和3列的布局有9个单元格,有16条网格线。

IE浏览器目前不支持grid布局,其他浏览器对于grid相关属性的详细兼容情况请查看:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout

容器属性

  • grid-template-row/grid-template-column
  • grid-template-areas
  • row-gap/column-gap/gap
  • grid-auto-flow
  • justify-items ,align-items ,place-items 
  • justify-content ,align-content ,place-content 
  • grid-auto-columns ,grid-auto-rows 
  • grid-template ,grid 

项目属性

  • grid-column-start ,grid-column-end ,grid-row-start ,grid-row-end 
  • grid-column ,grid-row
  • grid-area
  • justify-self ,align-self ,place-self 

下面分别介绍:

当然首先先要设置容器属性为grid,如下所示:

div {
    display: grid;
}

默认情况下,容器元素都是块级元素,但也可以设成行内元素。

div {
  display: inline-grid;
}

那么grid属性有没有什么需要注意的点呢?请看下面的小实验,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            width: 600px;
            height: 500px;
            border: 1px solid darkgray;
            background: lightgreen;
            padding: 10px;
        }
        .item{
            height:100px;
            width: 100px;
        }
        .item-inner{
            background: darkred;
            height: 20px;
            width: 30px;
        }
        .item:nth-child(1){
            /* display: grid; */
            background: darkblue;
        }
        .item-float{
            float: right;
        }
        .item:nth-child(2){
            /* display: grid; */
            background: darkmagenta;
        }
        .item-inline-block{
            display: inline-block;
        }
        .item:nth-child(3){
            /* display: grid; */
            background: darkgoldenrod;
            vertical-align:middle;
        }
        .item-table-cell{
            display: table-cell;
        }
        
        .item:nth-child(4){
            /* display: grid; */
            background: lightcoral;
        }
        .item-vertical-align{
            vertical-align:middle;
        }
        .item:nth-child(5){
            /* display: grid; */
            background: yellow;
            column-count: 3;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="item">
            <div class="item-inner">1-1</div>
            <div class="item-inner item-float">1-2</div>
            <div class="item-inner">1-3</div>
        </div>
        <div class="item">
            <div class="item-inner">2-1</div>
            <div class="item-inner item-inline-block">2-2</div>
            <div class="item-inner">2-3</div>
        </div>
        <div class="item">
            <div class="item-inner">3-1</div>
            <div class="item-inner item-inline-table-cell">3-2</div>
            <div class="item-inner">3-3</div>
        </div>
        <div class="item">
            <div class="item-inner">4-1</div>
            <div class="item-inner item-vertical-align">4-2</div>
            <div class="item-inner">4-3</div>
        </div>
        <div class="item">
            <div class="item-inner">5-1</div>
            <div class="item-inner">5-2</div>
            <div class="item-inner">5-3</div>
        </div>
    </div>
</body>
</html>

注释每个小容器的display:grid;时,即正常显示结果如下:

取消注释结果:

对比可以看出:设为网格布局以后,容器子元素(项目)的floatdisplay: inline-blockdisplay: table-cellvertical-aligncolumn-*等设置都将失效。

注意,以下所有属性值除了自定义属性值外,还有四个属性值:none、inherit、initial和unset。

  • none:不设置
  • inherit:继承
  • initial:默认
  • unset:暂不支持。简单理解为不设置。其实,它是关键字 initial 和 inherit 的组合。

当我们给一个 CSS 属性设置了 unset属性值

  • 如果该属性是默认继承属性,该值等同于 inherit
  • 如果该属性是非继承属性,该值等同于 initial

一、容器属性

1、grid-template-row / grid-template-column

.container {
  display: grid;
  grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
  grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}

当容器被定义为grid时,定义容器的每行和每列的大小。

  • line-name即线的名称,名称可省略。
  • track-size即为每列的宽度,值可以是长度单位,也可以是百分比,也可以是auto或者以下一些函数。

基本用法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container {
            display: grid;
            margin: 10px;
            height: 300px;
            width: 300px;
            grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
            grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
        }
        .item{
            border: 1px solid lightblue;
            font-size: 2em;
            text-align: center;
            background: lightskyblue;
        }
    </style>
</head>
<body>
    <div class="container">
        <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 class="item">10</div>
        <div class="item">11</div>
        <div class="item">12</div>
        <div class="item">13</div>
        <div class="item">14</div>
        <div class="item">15</div>
    </div>
</body>
</html>

 

(1)repeat():可以重复一些行或者列,值可以是长度或者是auto-fill(填充尽可能多的单元格)。

假如要做一个4行4列均相等的,可以这样写:

.container {
  display: grid;
  grid-template-columns: repeat(4, 25%);
  grid-template-rows: repeat(4, 25%);
}

等同于:

.container {
  display: grid;
  grid-template-columns: 25% 25% 25% 25%;
  grid-template-rows: 25% 25% 25% 25%;
}

颜色值采用js实现:

<script type=text/javascript>
    var colorArray = [ '#D24D57',' #26A65B','#EB7347','#2C3E50', 
'#84AF9B','#FC9D99','#AEDD81','#00CCFF','#D0D0D0','#990033','#FFFF00','#FF0033','#CCFFFF','#003366','#CCCC00'];
    var container = document.getElementById('grid-app-main').childNodes;
    for(var i = 0, k = 0, l = container.length; i < l; i++){
        if(container[i].className && container[i].className ==='item'){
            container[i].style.background = colorArray[k++];
        }
    }
</script>

repeat()还有一种用法是接受两个参数,第一个参数是重复的次数(上例是4),第二个参数是所要重复的值。

grid-template-columns: repeat(2, 100px 20px);

这样的结果也是4列,但1,2和3,4列宽度相同。

auto-fill:容器的大小不确定时,auto-fill表示自动填充容器,直到容器不能放置更多的列。

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

奇数列自动填充,偶数列固定100px

(2)fr:fraction 的缩写,意为"片段"。如果设置了fr,那么设置了fr的行/列将会按照比例分配容器剩余空间。

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

上面代码表示有3列,第一列固定宽度50px,假如容器尺寸为200px,则第二列和第三列分别为50px和100px。

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

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

上面的代码表示第3列的宽度介于50px 和1fr。

(4)auto:auto表示由浏览器自己决定长度。

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

上面代码含义是:第二列的宽度,基本上等于该列单元格的最大宽度,除非单元格内容设置了min-width,且这个值大于最大宽度。
(5)两栏布局左侧固定宽度,右侧自适应

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

左侧固定100px,右侧自适应宽度

2、grid-template-areas

属性用于定义区域。先用grid-template-row和template-template-column划分区域,然后才是分区域。

.container {
  grid-template-areas: 
    "<grid-area-name> | . | none | ..."
    "...";
}

布局实例

<div class="container">
    <div class="item-a">header</div>
    <div class="item-b">content</div>
    <div class="item-c">sidebar</div>
    <div class="item-d">footer</div>
</div>

 

.item-a {
    grid-area: header;
}

.item-b {
    grid-area: main;
}

.item-c {
    grid-area: sidebar;
}

.item-d {
    grid-area: footer;
}

.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr 1fr;
    grid-template-areas:
        "header header header header"
        "main main main sidebar"
        "footer footer footer footer";
}
.container > div{
    border:1px solid lightblue;
    text-align: center;
}

3、row-gap/column-gap/gap

row-gap属性设置行与行的间隔(行间距),column-gap属性设置列与列的间隔(列间距)。

.container {
  row-gap: 20px;
  column-gap: 20px;
}

grid-gap属性和flex属性类似,是grid-column-gapgrid-row-gap的合并简写形式。

gap: <grid-row-gap> <grid-column-gap>;
.container{
    gap: 20px 20px;
}

4、grid-auto-flow

划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是"先行后列".

grid-auto-flow默认值是row,如果设为column后

grid-auto-flow: column;

grid-auto-flow属性还可以设成row densecolumn dense。某些项目指定位置以后,如果容器行或者列有空余位置,dense规定剩下的项目尽可能紧凑排列,并且尽量填满空格。

5、justify-items ,align-items ,place-items 

justify-items属性设置单元格内容的水平位置(左中右),align-items属性设置单元格内容的垂直位置(上中下)。

.container {
  justify-items: start | end | center | stretch;
  align-items: start | end | center | stretch;
}

justify-items和align-items这两个属性都有如下值:

  • start:对齐单元格的起始边缘。
  • end:对齐单元格的结束边缘。
  • center:单元格内部居中。
  • stretch:拉伸,占满单元格的整个宽度(默认值)。

place-items属性是align-items属性和justify-items属性的合并简写形式。

注意:justify-items和align-items默认值是stretch,当设置这两个属性值为其他时,比如start,则宽度随单元格内容变化。

例如:

.container {
    display: grid;
    margin: 10px;
    height: 300px;
    width: 300px;
    grid-template-columns: 25% 25% 25% 25%;
    grid-template-rows: 25% 25% 25% 25%;
    justify-items: start;
    align-items: start;
}

如果省略第二个值,则浏览器认为与第一个值相等。

6、justify-content ,align-content ,place-content 

justify-content属性是整个内容区域在容器里面的水平位置(左中右),align-content属性是整个内容区域的垂直位置(上中下)。这两个值和flex中的juqstify-content和align-items有点类似。

.container {
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
  align-content: start | end | center | stretch | space-around | space-between | space-evenly;  
}

注意:此属性仅在网格总宽度小于grid容器宽度时候有效果。意味着假如按照百分比设置行列,那么这两个属性是无效的,除非你按照固定宽度设置才会有效。

例如:

如果按照百分比设置grid-template-column和grid-template-row,

.container {
    grid-template-columns: 25% 25% 25% 25%;
    grid-template-rows: 25% 25% 25% 25%;
    justify-content: start;
    align-content: start;
    border: 1px solid red;
}

.container {
    grid-template-columns: 50px 50px 50px 50px;
    grid-template-rows: 50px 50px 50px 50px;
    justify-content: start;
    align-content: start;
    border: 1px solid red;
}
      

place-content属性是align-content属性和justify-content属性的合并简写形式。

7、grid-auto-columns ,grid-auto-rows 

grid-auto-columns属性和grid-auto-rows属性用来设置,浏览器自动创建的多余网格的列宽和行高。

如果容器指定这连个属性,并且在单元格中指定位置,那么浏览器会按照指定的位置和大小放置单元格。

.container {
  display: grid;
  grid-template-columns: 50px 50px 50px 50px;
  grid-template-rows: 50px 50px 50px 50px;
  grid-auto-rows: 40px; 
}
.item:nth-child(15){
  grid-row-start: 5;
  grid-column-start: 3;
}
.item:nth-child(16){
  grid-row-start: 6;
  grid-column-start: 4;
}

如果子单元格不设定grid-column-start属性,grid-column-start默认值为1。

8、grid-template ,grid 

grid-template属性是grid-template-columnsgrid-template-rowsgrid-template-areas这三个属性的合并简写形式。

grid属性是grid-template-rowsgrid-template-columnsgrid-template-areas、 grid-auto-rowsgrid-auto-columnsgrid-auto-flow这六个属性的合并简写形式。

个人不建议使用这两个属性,会造成代码晦涩难懂。

二、项目属性

以下属性都是作用在item上

1、grid-column-start ,grid-column-end ,grid-row-start ,grid-row-end 

这四个数形用来指定项目的位置,具体方法就是指定项目的上、下、左、右四个边框分别在容器的哪个网格线。

  • grid-column-start属性:左边框所在的垂直网格线
  • grid-column-end属性:右边框所在的垂直网格线
  • grid-row-start属性:上边框所在的水平网格线
  • grid-row-end属性:下边框所在的水平网格线

注意上面的这四个属性可以覆盖容器中grid-template-row和grid-template-column属性。

.container {
  display: grid;
  grid-template-columns: 50px 50px 50px 50px;
  grid-template-rows: 50px 50px 50px 50px;
}
.item:nth-child(1){
  grid-column-start: 3;
  grid-column-end: 5;
  grid-row-start: 3;
  grid-row-end: 5;  
}

 上面代码表示第一个元素左边框起始于第3个列网格线,右边框结束于第5根列网格线;上边框起始于第3个列网格线,下边框结束于第5根列网格线。其他项目都没有指定位置,容器中display近似于absolute表现,由浏览器自动布局。

这四个属性值还可以指定为网格线的名称或者使用span关键字,表示"跨越",即左右边框(上下边框)之间跨越多少个网格。

2、grid-column ,grid-row 

grid-column属性是grid-column-startgrid-column-end的合并简写形式,grid-row属性是grid-row-start属性和grid-row-end的合并简写形式。

在此不一一举例,有兴趣的读者可以自己试试。

3、 grid-area 

grid-area属性指定项目位置.

此属性必须要和容器属性中的grid-template-areas一起使用,这很好理解,只有设定父容器区域才能指定子元素在哪个区域。

.container {
    grid-template-columns: 50px 50px 50px 50px;
    grid-template-rows: 50px 50px 50px 50px;
    grid-template-areas: 'a b c d'
                         'e f g h'
                         'i j k l'
                         'm n o p';
    border: 1px solid red;
}
.item:nth-child(1){
    grid-area: g;
}

结果:

我们可以看到编号为1的变到了g区域。

grid-area 还可用作grid-row-startgrid-column-startgrid-row-endgrid-column-end的合并简写形式,直接指定项目的位置。

.item {
  grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
}

4、justify-self ,align-self ,place-self 

justify-self设置单元格内容在水平方向的位置(左中右),justify-selfjustify-items的用法完全一致,但只作用于单个项目。

align-self设置单元格内容的在垂直方向的位置(上中下),align-selfalign-items的用法完全一致,也是只作用于单个项目。

.item {
  justify-self: start | end | center | stretch;
  align-self: start | end | center | stretch;
}

这两个属性都可以取下面四个值。

  • start:对齐单元格的起始边缘。
  • end:对齐单元格的结束边缘。
  • center:单元格内部居中。
  • stretch:拉伸,占满单元格的整个宽度(默认值)。

place-self属性是align-self属性和justify-self属性的合并简写形式。如果省略第二个值,那么第二个值和第一个值相等。

三、参考资料:

1、CSS Grid 网格布局教程

2、A Complete Guide to Grid

3、[Grid布局] - 快到格子里来

4、Understanding the CSS Grid Layout Module

5、Basic Concepts of grid layout

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fullstack_lth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值