CSS Grid

本文详细介绍了CSS Grid布局的强大功能,对比Flex布局,它支持二维布局,包括网格线、单元格、区域划分,以及各种容器和项目属性的使用。掌握grid-template-columns、grid-template-rows、grid-template-areas等关键属性,轻松实现复杂网页布局。

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

效果更好

Grid


网格布局(Grid)是最强大的 CSS 布局方案。 将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局。 Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局Grid 布局远比 Flex 布局强大。

.box{
	display:grid;
}

行元素使用flex布局;

.box{
	display:inline-grid;
}

<aside> 💡 注意,设为网格布局以后,容器子元素(项目)的floatdisplay: inline-blockdisplay: table-cellvertical-aligncolumn-* 等设置都将失效。

</aside>

浏览器支持情况

桌面(Desktop) 浏览器
ChromeOperaFirefoxIEEdgeSafari
57445211*(旧语法)1610.1
手机(Mobile) / 平板(Tablet)浏览器
iOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox
10.346No677063

基本概念


容器(Grid Container)和项目

采用网格布局的区域,称为"容器"(container)。

容器内部采用网格定位的子元素,称为"项目"(item)。

<div>
  <div><p>1</p></div>
  <div><p>2</p></div>
  <div><p>3</p></div>
</div>
  • 最外层的<div>元素就是容器,内层的三个<div>元素就是项目

<aside> 💡 注意:项目只能是容器的顶层子元素,不包含项目的子元素,比如上面代码的<p>元素就不是项目Grid 布局只对项目生效。

</aside>

  • grid row

    • 容器里面的水平区域称为"",垂直区域称为""(column)。
  • 单元格grid cell

    • 行和列的交叉区域,称为"单元格"。

      例:正常情况下,n行和m列会产生n x m个单元格。比如,3行3列会产生9个单元格

  • 网格线grid line

    • 划分网格的线,称为"网格线"。水平网格线划分出行,垂直网格线划分出列。

    • n 行有n + 1 根水平网格线,m 列有m + 1 根垂直网格线,比如三行就有四根水平网格线

  • 网格轨道(Grid Track)

    • 两条相邻网格线之间的空间。你可以把它们想象成网格的。下图是第二条和第三条行网格线之间的 网格轨道(Grid Track)。

  • 网格区域(Grid Area)

    • 4条网格线包围的总空间。一个网格区域(Grid Area)可以由任意数量的网格单元格(Grid Cell)组成。

    • 下图是 行网格线1和3,以及列网格线1和3之间的网格区域

  • 单位

    • fr:(fraction的缩写,意为"片段”)剩余空间分配数。用于在一系列长度值中分配剩余空间,如果多个已指定了多个部分,则剩下的空间根据各自的数字按比例分配。
    • gr:网格数(w3c暂未收录)

容器属性(17)


  • grid-template-columns & grid-template-rows

    grid-template-columns属性定义每一列的列宽; grid-template-rows属性定义每一行的行高。

    .container {
      display: grid;
      grid-template-columns: 100px 100px 100px;
      grid-template-rows: 100px 100px 100px;
    }
    
    • 使用百分比

      .container {
        display: grid;
        grid-template-columns: 33.33% 33.33% 33.33%;
        grid-template-rows: 33.33% 33.33% 33.33%;
      }
      
    • repeat()

      .container {
        display: grid;
        grid-template-columns: repeat(3, 33.33%);
        grid-template-rows: repeat(3, 33.33%);
      }
      
      .container {
        display: grid;
      	/* grid-template-columns: 100px 20px 80px 100px 20px 80px; */
      	grid-template-columns: repeat(2, 100px 20px 80px);
        grid-template-rows: repeat(3, 33.33%);
      }
      
      
    • auto-fill

      • 单元格的大小是固定的,但是容器的大小不确定。每一行(或每一列)容纳尽可能多的单元格,可以使用auto-fill 关键字表示自动填充。
      .container {
        display: grid;
        grid-template-columns: repeat(auto-fill, 100px);
      }
      

      <aside> 💡 表示每列宽度100px ,然后自动填充,直到容器不能放置更多的列。

      </aside>

    • fr

      .container {
        display: grid;
        grid-template-columns: 1fr 1fr;
      	/* grid-template-columns: 50% 50%; */
      }
      
      .container {
        display: grid;
        grid-template-columns: 150px 1fr 2fr;
        /* 第一列150px 剩余空间分为3份, 第二列 1份 第三列 2份 */
      }
      
    • minmax()

      • minmax() 函数产生一个长度范围,表示长度就在这个范围之中。接受两个参数,分别为最小值和最大值。
      .container {
        display: grid;
        grid-template-columns: 1fr 1fr minmax(100px, 1fr)
      	/* 总共分为3份 第一列 1份 第二列 1份 第三列 1份(最小为100px,最大为1fr) */
      }
      
    • auto

      • auto 关键字表示由浏览器自己决定长度
      .container {
        display: grid;
        grid-template-columns: 100px auto 100px;
      	/* 第一列 100px 第二列 总共减去200px 第三列 100px */
      }
      
      .container {
        display: grid;
        grid-template-columns: auto 0.25fr .25fr .25fr;
      }
      

      <aside> 💡 后边三列 容器宽度 - “宽auto”字符宽度) * 0.25, 第一列 宽度为 字节宽度加上 0.25fr;

      </aside>

    • 网格线的名称

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

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

      </aside>

    • 实例

      • 两栏式布局只需要一行代码
      .container {
        display: grid;
        grid-template-columns: 70% 30%;
      }
      
      • 十二网格布局
      .container {
        display: grid;
        grid-template-columns: repeat(12, 1fr);
      }
      
  • grid-template-areas

    网格布局允许指定"区域"(area),一个区域由单个或多个单元格组成。grid-template-areas 属性用于定义区域。

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

    <aside> 💡 划分出9个单元格,然后将其定名为ai 的九个区域,分别对应这九个单元格

    </aside>

    • 多个单元格合并成一个区域

      grid-template-areas: 'a a a'
                           'b b b'
                           'c c c';
      
    • 某些区域不需要利用,则使用"点"(.)表示

      grid-template-areas: 'a . c'
                           'd . f'
                           'g . i';
      
    • 需要指定对应class为指定区域

      .container {
        display: grid;
      	grid-template-columns: 1fr 1fr 1fr;
        grid-template-rows: 1fr 1fr 1fr ;
        grid-template-areas:
              "header header header"
              "sidebar content content"
              "sidebar content content"
              "footer footer footer"
      }
      
      		.header {
            grid-area: header;
          }
          .sidebar {
            grid-area: sidebar;
          }
          .content {
            grid-area: content;
          }
          .footer{
            grid-area: footer;
          }
      
      <div class="container">
          <div class="header">头部</div>
          <div class="sidebar">侧边栏</div>
          <div class="content">内容</div>
          <div class="footer">底部</div>
      </div>
      

    <aside> 💡 注意,区域的命名会影响到网格线。每个区域的起始网格线,会自动命名为区域名-start,终止网格线自动命名为区域名-end。 比如,区域名为header,则起始位置的水平网格线和垂直网格线叫做header-start,终止位置的水平网格线和垂直网格线叫做header-end

    </aside>

    <aside> 💡 网格区域一定要形成规整的矩形区域,什么L形,凹的或凸的形状都是不支持的,会认为是无效的属性值。

    </aside>

  • grid-template(grid-template-rows**grid-template-columns****grid-template-areas** 简写)

    grid-templategrid-template-rowsgrid-template-columnsgrid-template-areas 属性的缩写。

    .container {
        grid-template: none;
    }
    .container {
        grid-template: <grid-template-rows> / <grid-template-columns>;
    }
    
    .container {
    		display: grid;
        grid-template:
            "header header header" 1fr
            "sidebar content content" 1fr
            "sidebar content content" 1fr
            "footer footer footer" 1fr
            / 1fr 1fr 1fr;
    }
    

    <aside> 💡 由于grid-template 不会重置一些隐式的grid属性(如grid-auto-columnsgrid-auto-rowsgrid-auto-flow), 因此,大多数时候,还是推荐使grid 代替grid-template

    </aside>

  • column-gap(grid-column-gap) & row-gap(grid-row-gap)

    grid-column-gap :设置列与列的间隔(列间距) grid-row-gap :设置行与行的间隔(行间距)

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

    <aside> 💡 根据最新标准,上面三个属性名的grid-前缀已经删除,grid-column-gapgrid-row-gap写成column-gaprow-gapgrid-gap写成gap

    </aside>

  • gap(grid-gap)(column-gaprow-gap 简写)

    grid-gap :grid-column-gapgrid-row-gap 的合并简写形式

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

    <aside> 💡 grid-gap省略了第二个值,浏览器认为第二个值等于第一个值。

    </aside>

  • justify-items

    justify-items 指定了网格元素的水平呈现方式,是水平拉伸显示,还是左中右对齐,单元格内容

    .container {
        justify-items: stretch | start | end | center;
    }
    
    • stretch(默认值):表现为水平填充。更正:默认值是legacy
    • start:表现为网格水平尺寸收缩为内容大小,同时沿着网格线左侧对齐显示(假设文档流方向没有变)。
    • end:表现为网格水平尺寸收缩为内容大小,同时沿着网格线右侧对齐显示(假设文档流方向没有变)。
    • center:表现为网格水平尺寸收缩为内容大小,同时在当前网格区域内部水平居中对齐显示(假设文档流方向没有变)。
  • align-items

    align-items 指定了网格元素的垂直呈现方式,是垂直拉伸显示,还是上中下对齐;单元格内容

    .container {
        align-items: stretch | start | end | center;
    }
    
    • stretch(默认值):拉伸。表现为垂直填充。
    • start:表现为网格垂直尺寸收缩为内容大小,同时沿着上网格线对齐显示。
    • end:表现为网格垂直尺寸收缩为内容大小,同时沿着下网格线对齐显示。
    • center:表现为网格垂直尺寸收缩为内容大小,同时在当前网格区域内部垂直居中对齐显示。
  • place-items(align-itemsjustify-items 简写)

    place-items 可以让align-itemsjustify-items 属性写在单个声明中;

    .container {
        place-items: <align-items> <justify-items>;
    }
    
    .container {
        place-items: start end;
    }
    

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

    </aside>

  • justify-content

    justify-content 指定了网格元素的水平分布方式;单元格

    justify-content: stretch | start | end | center | space-between | space-around | space-evenly;
    
    .container {
        display: grid;
        width: 300px;
        grid-template: 100px 100px/100px 100px;
        /* grid-template: auto auto/auto auto; */
    }
    
    • stretch(默认值):拉伸,宽度填满grid容器,拉伸效果需要网格目标尺寸设为auto时候才有效,如果定死了宽度,则无法拉伸。
    • start:逻辑CSS属性值,与文档流方向相关。默认表现为左对齐。
    • end:逻辑CSS属性值,与文档流方向相关。默认表现为右对齐。
    • center:表现为居中对齐。
    • space-between:表现为两端对齐。
    • space-around:视觉上边缘两侧的空白只有中间空白宽度一半。
    • space-evenly:间隙匀称、平等的分;
  • align-content

    align-content 则是指明垂直方向每一行grid元素的分布方式。单元格

    align-content: stretch | start | end | center | space-between | space-around | space-evenly;
    
    • stretch(默认值):每一行grid子元素都等比例拉伸。
    • start:逻辑CSS属性值,与文档流方向相关。默认表现为顶部堆砌。
    • end:逻辑CSS属性值,与文档流方向相关。默认表现为底部堆放。
    • center:表现为整体垂直居中对齐。
    • space-between:表现为上下两行两端对齐。剩下每一行元素等分剩余空间。
    • space-around:每一行元素上下都享有独立不重叠的空白空间。
    • space-evenly:每一行元素都完全上下等分。
  • place-content(align-contentjustify-content 简写)

    place-content 可以让align-contentjustify-content 属性写在一个CSS声明中,也就是俗称的缩写

    .container {
        place-content: <align-content> <justify-content>;
    }
    
  • grid-auto-columns & grid-auto-rows

    指定任何自动生成的网格轨道(也称为隐式网格轨道)的大小。 当网格项目多于网格中的单元格网格项目放置在显式网格之外时,将创建隐式轨道grid-auto-columns 属性和grid-auto-rows 属性用来设置,浏览器自动创建的多余网格的列宽和行高。 如果不指定这两个属性,浏览器完全根据单元格内容的大小,决定新增网格的列宽和行高。

    .container {
        display: grid;
        width: 150px;
        grid-template-columns: 60px 60px;
        grid-template-rows: 30px 90px;
        grid-auto-columns: 60px;
    }
    .item-a { 
        grid-column: 1 / 2;
        grid-row: 2 / 3;
    }
    .item-b { 
        /* 容器水平只有2个格子,但这里设定的是第3个,隐式网格创建 */
        grid-column: 3 / 4;
        grid-row: 2 / 3; 
        background-color: rgba(255,255,0, .5);
    }
    

  • grid-auto-flow

    划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是"先行后列",即先填满第一行,再开始放入第二行;

    .container {
      grid-auto-flow: row | column | row dense | column dense
    }
    
    • row(默认值):没有指定位置的网格依次水平排列优先。
    • column:没有指定位置的网格依次垂直排列优先。
    • row dense:表示"先行后列",并且尽可能紧密填满,尽量不出现空格。
    • column dense:表示"先列后行",并且尽量填满空格。
  • grid(grid-template-rows**grid-template-columns****grid-template-areasgrid-auto-columnsgrid-auto-rowsgrid-auto-flow 简写)**

项目属性(10)


  • grid-column-start & grid-column-end

    grid-column-start属性:左边框所在的垂直网格线 grid-column-end属性:右边框所在的垂直网格线

    .item {
        grid-column-start: <number> | <name> | span <number> | span <name> | auto
        grid-column-end: <number> | <name> | span <number> | span <name> | auto
    }
    
  • grid-row-start & grid-row-end

    grid-row-start属性:上边框所在的水平网格线 grid-row-end属性:下边框所在的水平网格线

    .item {
        grid-row-start: <number> | <name> | span <number> | span <name> | auto
        grid-row-end: <number> | <name> | span <number> | span <name> | auto
    }
    
    • <number> 起止与第几条网格线。
    • <name> 自定义的网格线的名称。
    • span <number> 表示当前网格会自动跨越指定的网格数量。
    • span <name> 表示当前网格会自动扩展,直到命中指定的网格线名称。
    • auto 全自动,包括定位,跨度等。
    .container {
        grid-template-columns: [第一根纵线] 80px [纵线2] auto [纵线3] 100px [最后的结束线];
        grid-template-rows: [第一行开始] 25% [第一行结束] 100px [行3] auto [行末];
    }
    .item-a {
        grid-column-start: 2;
        grid-column-end: 纵线3;
        grid-row-start: 第一行开始;
        grid-row-end: 3;
    }
    
    <div class="container">
        <div class="item-a"></div>
    </div>
    

    • grid-column-start:2 表示.item-a网格左侧起始于<number>2的线;
    • grid-column-end:纵线3 表示.item-a网格右侧结束于<name>纵线3的线;
    • grid-row-start:第一行开始 表示.item-a网格上方开始于<name>第一行开始的线;
    • grid-row-end:3 表示.item-a网格下方结束于<number>3的线。
    .item-b {
        grid-column-start: 2;
        grid-column-end: span 纵线3;
        grid-row-start: 第一行开始;
        grid-row-end: span 3;
    }
    
    <div class="container">
        <div class="item-b"></div>
    </div>
    

    • grid-row-end:span 3 表示当前网格需要覆盖3个格子;

    <aside> 💡 对于命名的网格线,有span 和没有span 没有区别(包括多个同名网格线)。

    </aside>

  • grid-column(grid-column-startgrid-column-end 简写) & grid-row(grid-row-startgrid-row-end 简写)

    .item {
        grid-column: <start-line> / <end-line> | <start-line> / span <value>;
        grid-row: <start-line> / <end-line> | <start-line> / span <value>;
    }
    
    • 管道分隔符| 表示“或者”
    • <start-line> 就是grid-*-start 属性值,
    • <end-line> 就是grid-*-end 属性值
    .item-b {
        grid-column: 2 / span 纵线3;
        grid-row: 第一行开始 / span 3;
    }
    

    <=>

    .item-b {
        grid-column-start: 2;
        grid-column-end: span 纵线3;
        grid-row-start: 第一行开始;
        grid-row-end: span 3;
    }
    
  • grid-area(grid-row-startgrid-column-startgrid-row-endgrid-column-end | grid-template-areas 简写)

    grid-area 表示当前网格所占用的区域 grid-area 其实是grid-row-startgrid-column-startgrid-row-end 以及 grid-column-end 属性的缩写, 以及额外支持grid-template-areas 设置的网格名称而已

    .item {
        grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
    }
    
    • <name> 区域名称。由grid-template-areas属性创建。
    • <row-start> / <column-start> / <row-end> / <column-end> 占据网格区域的纵横起始位置。
    .container {
        grid-template: 1fr 1fr 1fr/1fr 1fr 1fr 1fr;
    }
    .item-c { 
        grid-area: 1 / 2 / 3 / 4;
    }
    

  • justify-self

    justify-self 属性设置单元格中内容的水平位置(左中右)

    .item {
      justify-self: start | end | center | stretch;
    }
    
    • stretch(默认值):拉伸。表现为水平填充
    • start:表现为网格水平尺寸收缩为内容大小,同时沿着网格线左侧对齐显示。
    • end:表现为网格水平尺寸收缩为内容大小,同时沿着网格线右侧对齐显示。
    • center:表现为网格水平尺寸收缩为内容大小,同时在当前网格区域内部水平居中对齐显示。
  • align-self

    align-self 属性设置单元格中内容的垂直位置(上中下)

    .item {
      align-self: start | end | center | stretch;
    }
    
    • stretch(默认值):拉伸。表现为垂直填充。
    • start:表现为网格垂直尺寸收缩为内容大小,同时沿着上网格线对齐显示。
    • end:表现为网格垂直尺寸收缩为内容大小,同时沿着下网格线对齐显示。
    • center:表现为网格垂直尺寸收缩为内容大小,同时在当前网格区域内部垂直居中对齐显示。
  • place-self(align-selfjustify-self 简写)

    place-items 可以让align-selfjustify-self 属性写在单个声明中

    .item {
        place-self: <align-self> <justify-self>?
    }
    

Grid Garden

写给自己看的display: grid布局教程 " 张鑫旭-鑫空间-鑫生活

### CSS Grid 布局教程与使用示例 #### 1. CSS Grid 基本概念 CSS Grid 是一种用于二维布局的系统,允许开发者精确地控制页面上的行列分布。它是一种强大的工具,能够解决传统浮动和 Flexbox 难以处理的复杂布局问题[^1]。 #### 2. 创建基本的 Grid 容器 要启用 Grid 布局,需将父级容器的 `display` 属性设置为 `grid` 或 `inline-grid`。以下是创建一个基础 Grid 的方法: ```css .container { display: grid; } ``` 此代码片段会将 `.container` 转换为一个网格容器[^5]。 #### 3. 定义网格列和行 通过 `grid-template-columns` 和 `grid-template-rows` 属性可以分别定义网格中的列宽和行高。例如: ```css .container { display: grid; grid-template-columns: 1fr 2fr 1fr; /* 列比例分别为 1:2:1 */ grid-template-rows: 100px 200px 100px; /* 行高度固定 */ gap: 10px; /* 设置行间和列间的间隔 */ } ``` 这里,`gap` 属性用来指定网格项之间的间距[^3]。 #### 4. 单元格定位 可以通过 `grid-column` 和 `grid-row` 来精确定位某个子元素的位置。例如: ```css .item1 { grid-column: 1 / 3; /* 从第1列跨越至第3列前 */ grid-row: 1 / 2; /* 位于第1行 */ } .item2 { grid-column: 2 / 3; grid-row: 2 / 3; } ``` 这种语法使得单元格可以在任意位置放置并跨多个区域[^4]。 #### 5. 响应式布局支持 利用 `fr` 单位可轻松实现响应式的等比分割。当视口大小变化时,各部分的比例保持不变。例如: ```css .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); /* 动态生成三列,每列占总宽度的三分之一 */ grid-gap: 20px; } ``` 这段代码展示了如何动态调整列数以及它们所占据的空间份额[^2]。 #### 6. 综合实例 下面是一个完整的 HTML 结构及其对应的样式表来展示以上知识点的应用场景: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CSS Grid Example</title> <style> .grid-container { display: grid; grid-template-columns: 1fr 2fr 1fr; grid-template-rows: 100px 200px 100px; gap: 10px; width: 600px; margin: 50px auto; border: 1px solid black; } .item { background-color: lightblue; text-align: center; padding: 20px; font-size: 20px; } .item1 { grid-area: 1 / 1 / 2 / 3; } /* 跨越第一第二列 */ .item2 { grid-area: 2 / 2 / 3 / 3; } .item3 { grid-area: 2 / 3 / 3 / 4; } </style> </head> <body> <div class="grid-container"> <div class="item item1">Item 1</div> <div class="item item2">Item 2</div> <div class="item item3">Item 3</div> </div> </body> </html> ``` 这个例子综合运用了前面提到的各种技巧,包括但不限于显式设定行列尺寸、应用间隙参数以及自定义项目覆盖范围等功能特性[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值