CSS3系列 12 栅格布局

栅格布局

基本介绍

CSS的栅格布局也被称为网格布局(Grid Layout),它是一种新兴的布局方式。

栅格布局是一个二维系统,这意味着它可以同时处理列和行,与弹性布局相似,栅格系统也是由栅格容器包裹栅格元素进行使用。

对于栅格布局来说,它的思想实际上非常简单,将一块区域绘制成格子,然后将元素填进去即可。

作为学习者应该从下面两个角度来学习栅格布局:

  • 怎么样画出栅格容器
  • 怎么样将元素放进栅格容器中的某一区域

值得一提的是,现在的一些旧版浏览器对于栅格布局并没有较好的支持性,所以这项技术的应用场景其实相比于传统式的浮动布局以及弹性布局来说会少一些。

CSS3系列 12 栅格布局

栅格容器

容器声明

使用display: grid或者display: inline-gid声明一个元素为栅格容器。

  • grid:块级栅格容器,独占一行
  • inline-grid:内联块级栅格容器,不独占一行

首先声明grid,即块级栅格容器,可以看见容器本身是独占一行的:

CSS3系列 12 栅格布局

其次是inline-grid,即内联块级栅格容器,容器本身不会独占一行:

CSS3系列 12 栅格布局

代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css_reset.css">
    <style>
        main {
            border: solid 5px silver;
            /* 声明容器 */
            display: inline-grid;
            /*
            display: grid;
            display: inline-grid;
            */
            
            
            /* 划分行列 */
            grid-template-rows: repeat(3, 100px);
            grid-template-columns: repeat(3, 100px);
        }

        main div {
            background: blueviolet content-box;
            padding: 10px;
            border: 1px #000 dashed;
            text-align: center;
            line-height: 80px;
            color: #fff;
        }
    </style>
</head>

<body>
    <main>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
        <div>6</div>
        <div>7</div>
        <div>8</div>
        <div>9</div>
    </main>
    <span>this is span element</span>
</body>

</html>

栅格容器之行列划分

划分行列

光有栅格容器没有用,我们还需要为栅格容器划分行列以及指定宽度。

  • grid-template-rows:划分行数
  • grid-template-columns:划分列数

下面介绍几种划分行列的方式。

固定宽高

如我们想画一个2行3列固定宽高的栅格容器,可以使用下面的方法进行绘制:

  • grid-template-rows: 100px 100px;
  • grid-template-columns: 100px 100px 100px;

渲染结果,高度200px,款度300px:

CSS3系列 12 栅格布局

代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css_reset.css">
    <style>
        main {
            border: solid 5px silver;
            /* 声明容器 */
            display: inline-grid;
            /* 划分行列 */
            grid-template-rows: 100px 100px;
            grid-template-columns: 100px 100px 100px;
        }

        main div {
            background: blueviolet content-box;
            padding: 10px;
            border: 1px #000 dashed;
            text-align: center;
            line-height: 80px;
            color: #fff;
        }
    </style>
</head>

<body>
    <main>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
        <div>6</div>
    </main>
</body>

</html>

百分比宽高

使用百分比来绘制行列线,使用这种方式你必须先指定栅格容器的宽高。

如下面示例中为一个300 * 300的栅格容器绘制出2行4列的线条:

  • grid-template-rows: 50% 50%;
  • grid-template-columns: 25% 25% 25% 25%;

渲染结果:

CSS3系列 12 栅格布局

代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css_reset.css">
    <style>
        main {
            border: solid 5px silver;
            width: 300px;
            height: 300px;
            /* 声明容器 */
            display: inline-grid;
            /* 划分行列 */
            grid-template-rows: 50% 50%;
            grid-template-columns: 25% 25% 25% 25%;
        }

        main div {
            background: blueviolet content-box;
            padding: 10px;
            border: 1px #000 dashed;
            text-align: center;
            line-height: 150px;
            color: #fff;
        }
    </style>
</head>

<body>
    <main>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
        <div>6</div>
        <div>7</div>
        <div>8</div>
    </main>
</body>

</html>

重复划分

若每行或每列的间距是相同的,则直接可以使用重复绘制更加简便的划分行列。

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

CSS3系列 12 栅格布局

代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css_reset.css">
    <style>
        main {
            border: solid 5px silver;
            /* 声明容器 */
            display: inline-grid;
            /* 划分行列 */
            grid-template-rows: repeat(3, 100px);
            grid-template-columns: repeat(3, 100px);
        }

        main div {
            background: blueviolet content-box;
            padding: 10px;
            border: 1px #000 dashed;
            text-align: center;
            line-height: 80px;
            color: #fff;
        }
    </style>
</head>

<body>
    <main>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
        <div>6</div>
        <div>7</div>
        <div>8</div>
        <div>9</div>
    </main>
</body>

</html>

我们也可以重复绘制不同宽度的单元格,比如奇数项的列要宽一点,偶数项的列要窄一点:

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

CSS3系列 12 栅格布局

代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css_reset.css">
    <style>
        main {
            border: solid 5px silver;
            /* 声明容器 */
            display: inline-grid;
            /* 划分行列 */
            grid-template-rows: repeat(3, 100px);
            /*
            重复2次, 奇数项列宽为100px、偶数项列宽为50px
            最终总列数 = 重复次数 * 后面跟上的个数
            即 2 * 2 = 4列
            */
            grid-template-columns: repeat(2, 100px 50px);
        }

        main div {
            background: blueviolet content-box;
            padding: 10px;
            border: 1px #000 dashed;
            text-align: center;
            line-height: 80px;
            color: #fff;
        }
    </style>
</head>

<body>
    <main>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
        <div>6</div>
        <div>7</div>
        <div>8</div>
        <div>9</div>
        <div>10</div>
        <div>11</div>
        <div>12</div>
    </main>
</body>

</html>

自动划分

自动划分是指不指定划分多少行或者列,而是只给他一个行列占比的具体数值,它会自动根据容器的大小来进行划分。

我们想在一个宽和高都是300px的栅格容器中进行绘制,而每个单元格的宽高都是100px,那就设置一下交给他自动绘制。

  • grid-template-rows: repeat(auto-fill, 100px);
  • grid-template-columns: repeat(auto-fill, 100px);

CSS3系列 12 栅格布局

代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css_reset.css">
    <style>
        main {
            width: 300px;
            height: 300px;

            border: solid 5px silver;
            /* 声明容器 */
            display: inline-grid;
            /* 划分行列 */
            grid-template-rows: repeat(auto-fill, 100px);
            grid-template-columns: repeat(auto-fill, 100px);
        }

        main div {
            background: blueviolet content-box;
            padding: 10px;
            border: 1px #000 dashed;
            text-align: center;
            line-height: 80px;
            color: #fff;
        }
    </style>
</head>

<body>
    <main>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
        <div>6</div>
        <div>7</div>
        <div>8</div>
        <div>9</div>
    </main>
</body>

</html>

比例划分

如果你的栅格容器已设置宽高,则我们可以按照空间比例进行行列划分。单位是fr。

如下所示,这是一个3行3列的栅格容器,第一行和最后一行的高度都为3fr,中间一行的高度为4fr,第一列和最后一列的宽度都为2fr,中间一列的宽度为6fr:

  • grid-template-rows: 3fr 4fr 3fr;
  • grid-template-columns: 2fr 6fr 2fr;

CSS3系列 12 栅格布局

代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css_reset.css">
    <style>
        main {
            width: 300px;
            height: 300px;

            border: solid 5px silver;
            /* 声明容器 */
            display: inline-grid;
            /* 划分行列 */
            grid-template-rows: 3fr 4fr 3fr;
            grid-template-columns: 2fr 6fr 2fr;
        }

        main div {
            background: blueviolet content-box;
            padding: 10px;
            border: 1px #000 dashed;
            text-align: center;
            line-height: 80px;
            color: #fff;
        }
    </style>
</head>

<body>
    <main>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
        <div>6</div>
        <div>7</div>
        <div>8</div>
        <div>9</div>
    </main>
</body>

</html>

组合定义

grid-template是grid-template-rows、grid-template-columns、grid-template-areas 的三个属性的简写。

但是我们目前还没有介绍到grid-template-areas,所以仅演示用grid-template来划分行列。

如下将采用组合定义的方式构建出一个3行3列宽高均为100px的栅格容器:

  • 注意:先行后列
  • grid-template: repeat(3, 100px) / repeat(3, 100px);

CSS3系列 12 栅格布局

代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css_reset.css">
    <style>
        main {
            border: solid 5px silver;
            /* 声明容器 */
            display: inline-grid;
            /* 划分行列 先行后列 */
            grid-template: repeat(3, 100px) / repeat(3, 100px);
        }

        main div {
            background: blueviolet content-box;
            padding: 10px;
            border: 1px #000 dashed;
            text-align: center;
            line-height: 80px;
            color: #fff;
        }
    </style>
</head>

<body>
    <main>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
        <div>6</div>
        <div>7</div>
        <div>8</div>
        <div>9</div>
    </main>
</body>

</html>

minmax划分

如果你的栅格容器设置了宽高,且栅格容器中单元格的宽高大于整体栅格容器的宽高就会发生溢出现象。

我们在划分行列时,可以指定minmax,为行线或者列线设定一个动态的取值数值来防止溢出的发生。

CSS3系列 12 栅格布局

上面这个例子中,栅格容器宽高为200px 300px,但是行列划分时设定是3列3行100px,所以就造成了列溢出。

此时我们可以在列划分时设置minmax来进行单元格的自动缩容或者扩容:

  • 释义:列线3根,最小取值范围为50px,最大取值范围为100px
  • grid-template: repeat(3, 100px) / repeat(3, minmax(50px, 100px));

CSS3系列 12 栅格布局

栅格容器之间距定义

行间距 row-gap

栅格容器中每一个元素,现在看是紧密挨在一起的。我们可以对栅格元素本身进行margin或者padding来将彼此之前撑开留出间隙,也可以使用栅格容器提供的方法。

使用row-gap设置行间距。

CSS3系列 12 栅格布局
<!DOCTYPE html>
<html lang="en">

<head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
                * {
                        padding: 0;
                        margin: 0;
                }

                body {
                        padding: 100px;
                }

                main {
                        width: 300px;
                        /* height: 300px; */
                        
                        border: solid 5px silver;
                        display: grid;

                        /* 行数,列数 */
                        grid-template: repeat(3,100px)/repeat(3,minmax(50px,100px));
                        /* 行间距 */
                        row-gap:30px ;
                }

                section {
                        background-color: blueviolet;
                        background-clip: content-box;
                        padding: 10px;
                        border: dashed 1px black;

                        text-align: center;
                        line-height: 78px;
                        color: #fff;
                }
        </style>
</head>

<body>

        <main>
                <section>1</section>
                <section>2</section>
                <section>3</section>
                <section>4</section>
                <section>5</section>
                <section>6</section>
                <section>7</section>
                <section>8</section>
                <section>9</section>
        </main>

</body>

</html>

列间距 columns-gap

使用column-gap定义列间距。

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
                * {
                        padding: 0;
                        margin: 0;
                }

                body {
                        padding: 100px;
                }

                main {
                        width: 300px;
                        /* height: 300px; */
                        
                        border: solid 5px silver;
                        display: grid;

                        /* 行数,列数 */
                        grid-template: repeat(3,100px)/repeat(3,minmax(50px,100px));
                        /* 列间距 */
                        column-gap:30px ;
                }

                section {
                        background-color: blueviolet;
                        background-clip: content-box;
                        padding: 10px;
                        border: dashed 1px black;

                        text-align: center;
                        line-height: 78px;
                        color: #fff;
                }
        </style>
</head>

<body>

        <main>
                <section>1</section>
                <section>2</section>
                <section>3</section>
                <section>4</section>
                <section>5</section>
                <section>6</section>
                <section>7</section>
                <section>8</section>
                <section>9</section>
        </main>

</body>

</html>

组合定义 gap

使用gap规则可以一次定义行、列间距,如果间距一样可以只设置一个值。

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
                * {
                        padding: 0;
                        margin: 0;
                }

                body {
                        padding: 100px;
                }

                main {
                        width: 300px;
                        /* height: 300px; */
                        
                        border: solid 5px silver;
                        display: grid;

                        /* 行数,列数 */
                        grid-template: repeat(3,100px)/repeat(3,minmax(50px,100px));
                        /* 行列间距 */
                        gap:30px ;
                }

                section {
                        background-color: blueviolet;
                        background-clip: content-box;
                        padding: 10px;
                        border: dashed 1px black;

                        text-align: center;
                        line-height: 78px;
                        color: #fff;
                }
        </style>
</head>

<body>

        <main>
                <section>1</section>
                <section>2</section>
                <section>3</section>
                <section>4</section>
                <section>5</section>
                <section>6</section>
                <section>7</section>
                <section>8</section>
                <section>9</section>
        </main>

</body>

</html>

栅格容器之栅格线命名

基础知识

可以发现,其实最少有2条线的数据就可以定位一个栅格元素所在的位置。

CSS3系列 12 栅格布局

如果我们想将元素放入正中间,可以这样设置:

  • 行线开始位:2号线开始或者1号线结束位置
  • 列线开始位:2号线开始或者1号线结束位置
  • 行线结束位:3号线开始或者2号线结束位置
  • 列线结束位:3号线开始或者2号线结束位置

那么这样,我们就可以将元素定位在该容器正中,并且大小只占据1个单元格。

CSS3系列 12 栅格布局

独立命名

我们可以为每一条栅格线都进行独立命名,现在就来将上面的伪代码实现一下。

  • grid-template-rows: [r1-start] 100px [r1-end r2-start] 100px [r2-end r3-start] 100px [r3-end];
  • grid-template-columns: [c1-start] 100px [c1-end c2-start] 100px [c2-start c3-start] 100px [c3-end];

每条线可以有多个名字,在使用的时候可以使用其任意的且具有的名字。

当我们需要定位的时候,使用如下格式对一个元素进行定位:

  • grid-row-start: r2-start;
  • grid-column-start:c1-end;
  • grid-row-end: r2-end;
  • grid-column-end: c3-start;

注意!默认的栅格容器是不会展示栅格线的,此时需要打开浏览器的检查功能就会看到栅格线。

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 300px;
            /* height: 300px; */

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template-rows: [r1-start] 100px [r1-end r2-start] 100px [r2-end r3-start] 100px [r3-end];
            grid-template-columns: [c1-start] 100px [c1-end c2-start] 100px [c2-start c3-start] 100px [c3-end];
        }

        section {
            background-color: blueviolet;
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;

            text-align: center;
            line-height: 78px;
            color: #fff;

            grid-row-start: r2-start;
            grid-column-start: c1-end;
            grid-row-end: r2-end;
            grid-column-end: c3-start;
        }
    </style>
</head>

<body>

    <main>
        <section>中间</section>
    </main>

</body>

</html>

自动命名

对于重复设置的栅格容器系统会为它自动命名,使用时使用r1、c2的方式定位栅格。

  • r代表行
  • c代表列

重复设置,命名前缀:

  • grid-template-rows: repeat(3, [r-start] 100px [r-end]);
  • grid-template-columns: repeat(3, [c-start] 100px [c-end]);

在使用自动命名的栅格线进行定位时,应该按照如下格式:

  • grid-row-start: r-start 2;
  • grid-column-start: c-start 2;
  • grid-row-end: r-start 2;
  • grid-column-end: c-end 2;

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 300px;
            /* height: 300px; */

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template-rows: repeat(3, [r-start] 100px [r-end]);
            grid-template-columns: repeat(3, [c-start] 100px [c-end]);

        }

        section {
            background-color: blueviolet;
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;

            text-align: center;
            line-height: 78px;
            color: #fff;

            grid-row-start: r-start 2;
            grid-column-start: c-start 2;
            grid-row-end: r-start 2;
            grid-column-end: c-end 2;

        }
    </style>
</head>

<body>

    <main>
        <section>中间</section>
    </main>

</body>

</html>

栅格元素之元素定位

定位方法

我们可以使用以下方法对栅格元素进行定位,但是关于如何定位又分为很多种。

选项 描述
grid-row-start 行开始栅格线
grid-row-end 行结束栅格线
grid-column-start 列开始栅格线
grid-column-end 列结束栅格线

栅格线位置定位

栅格线位置定位实际上就是数数,在水平的第几根线,在垂直的第几根线。

还是老办法,规定行开始线位置与行结束线位置以及列开始线位置和列结束线位置。

如下,可以看到,单纯的就是数数,非常的简单粗暴。

  • grid-row-start: 2;
  • grid-column-start: 2;
  • grid-row-end: 2;
  • grid-column-end: 2;

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 300px;
            /* height: 300px; */

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template-rows: repeat(3, 100px);
            grid-template-columns: repeat(3, 100px);

        }

        section {
            background-color: blueviolet;
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;

            text-align: center;
            line-height: 78px;
            color: #fff;

            grid-row-start: 2;
            grid-column-start: 2;
            grid-row-end: 2;
            grid-column-end: 2;

        }
    </style>
</head>

<body>

    <main>
        <section>中间</section>
    </main>

</body>

</html>

栅格线名称定位

我们说过栅格线有独立命名和自动命名。

根据栅格线名称也可以进行定位,这里不再举例,具体参见栅格线命名一章。

偏移量定位

这个其实也比较简单,我们只需要指定行线的开始位置以及列线的开始位置即可,关于结束为止也是数数,使用span来数,往后走一根线还是两根线。

  • grid-row-start: 1;
  • grid-column-start: 1;
  • /* 代表从行线开始位置向后数3根线 */
  • grid-row-end: span 3;
  • /* 代表从列线开始位置向后数3根线 */
  • grid-column-end: span 3;

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 300px;
            /* height: 300px; */

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template-rows: repeat(3, 100px);
            grid-template-columns: repeat(3, 100px);

        }

        section {
            background-color: blueviolet;
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;

            text-align: center;
            line-height: 300px;
            color: #fff;

            grid-row-start: 1;
            grid-column-start: 1;
            /* 代表从行线开始位置向后数3根线 */
            grid-row-end: span 3;
            /* 代表从列线开始位置向后数3根线 */
            grid-column-end: span 3;

        }
    </style>
</head>

<body>

    <main>
        <section>全占</section>
    </main>

</body>

</html>

简写模式

可以使用grid-row设置行开始栅格线,使用grid-column设置结束栅格线。

  • grid-row: 3/span 3;
  • grid-column: 2/span 3;

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 300px;
            /* height: 300px; */

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template-rows: repeat(3, 100px);
            grid-template-columns: repeat(3, 100px);

        }

        section {
            background-color: blueviolet;
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;

            text-align: center;
            line-height: 78px;
            color: #fff;


            grid-row: 3/span 3;
            grid-column: 2/span 3;

        }
    </style>
</head>

<body>

    <main>
        <section>右下角两格</section>
    </main>

</body>

</html>

极简模式

grid-area是对上面的简写模式grid-row以及grid-column的再次简写,它的语法结构如下:

  • 行线开始/列线开始/行线结束/列线结束
  • grid-area: 2/1/span 1/span 3;

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 300px;
            /* height: 300px; */

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template-rows: repeat(3, 100px);
            grid-template-columns: repeat(3, 100px);

        }

        section {
            background-color: blueviolet;
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;

            text-align: center;
            line-height: 78px;
            color: #fff;


            grid-area: 2/1/span 1/span 3;

        }
    </style>
</head>

<body>

    <main>
        <section>中间三格</section>
    </main>

</body>

</html>

bootstrap 栅格原理

bootstrap中的栅格系统将整个栅格容器分为了12个块,其实它的原理非常简单。

CSS3系列 12 栅格布局

我们用目前所学的知识也能开发类似的组件,如下图:

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        .row {
            padding: 10px;
            width: 600px;
            border: solid 5px silver;
            display: grid;
            grid-template-columns: repeat(12, 1fr);
            gap: 10px 10px;
        }

        .col-1 {
            grid-column-end: span 1;
        }

        .col-2 {
            grid-column-end: span 2;
        }

        .col-3 {
            grid-column-end: span 3;
        }

        .col-4 {
            grid-column-end: span 4;
        }

        .col-5 {
            grid-column-end: span 5;
        }

        .col-6 {
            grid-column-end: span 6;
        }

        .col-7 {
            grid-column-end: span 7;
        }

        .col-8 {
            grid-column-end: span 8;
        }

        .col-9 {
            grid-column-end: span 9;
        }

        .col-10 {
            grid-column-end: span 10;
        }

        .col-11 {
            grid-column-end: span 11;
        }

        .col-12 {
            grid-column-end: span 12;
        }


        [class^="col-"] {
            background-color: blueviolet;
            background-clip: content-box;
            height: 30px;
            text-align: center;
            color: #fff;



        }
    </style>
</head>

<body>

    <main>
        <div class="row">
            <section class="col-8">col-8</section>
            <section class="col-4">col-4</section>
            <section class="col-4">col-4</section>
            <section class="col-4">col-4</section>
            <section class="col-4">col-4</section>
            <section class="col-6">col-6</section>
            <section class="col-6">col-6</section>
        </div>

    </main>

</body>

</html>

栅格容器之栅格区域

基础介绍

栅格区域说白了就是一堆栅格的单元格组成的区域,一个单元格也是一个区域。

我们可以使用栅格区域更方便的放置元素而不用再慢慢的数线放置,栅格区域放置元素通常用在大布局上。

使用grid-template-areas声明栅格区域时需要注意一点,栅格区域放置元素必须是矩形的。

你不能这样放置这样的一个元素:

CSS3系列 12 栅格布局

区域命名

来看一个简单的案例,如何使用grid-template-areas对栅格区域进行命名并填充元素。

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 300px;
            /* height: 300px; */

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template-rows: repeat(3, 100px);
            grid-template-columns: repeat(3, 100px);

            grid-template-areas:
                "top top top"
                "mid mid mid"
                "bottom bottom bottom";

            /* 由于绘制了9*9的单元格,我们必须给每个单元格进行了命名 ,而且一定要是这种格式*/

        }

        main * {
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;
        }

        main header {
            /* 完整的写法,推荐使用下面的简写方式*/
            /* grid-area: top-start/top-start//top-start/top-end/top-end/top-end; */
            grid-area: top;
            background-color: blueviolet;
        }

        main article {
            grid-area: mid;
            background-color: violet;
        }

        main footer {
            grid-area: bottom;
            background-color: yellowgreen;
        }
    </style>
</head>

<body>

    <main>
        <header></header>
        <article></article>
        <footer></footer>
    </main>

</body>

</html>

自动命名

栅格容器中的每个单元格的列行线都会根据单元格名称自动进行命名,如下图所示:

CSS3系列 12 栅格布局

按图中这种命名来进行实验:

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 300px;
            /* height: 300px; */

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template-rows: repeat(3, 100px);
            grid-template-columns: repeat(3, 100px);

            grid-template-areas:
                "top-left top-center top-right"
                "mid-left mid-center mid-right"
                "bottom-left bottom-center bottom-right";

            /* 由于绘制了9*9的单元格,我们必须给每个单元格进行了命名 ,而且一定要是这种格式*/

        }

        main * {
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;
        }

        main div:first-of-type {
            grid-area: top-left-start/top-left-start/mid-center-end/mid-center-end;
            background-color: blueviolet;
        }

        main div:last-of-type {
            grid-area: bottom-left-start/bottom-left-start/bottom-right-end/bottom-right-end;
            background-color: violet;
        }
    </style>
</head>

<body>

    <main>
        <div></div>
        <div></div>
    </main>

</body>

</html>

占位命名

栅格区域命名占位就是说有的区域不想给他取名,那么就直接.就行。

为什么要这么做呢?看下图以及代码就能理解,我们在进行区域划分的时候就想好了这一块区域是来干什么的,应该有多大,那么多余的地方直接.占位即可。

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 300px;
            /* height: 300px; */

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template-rows: repeat(3, 100px);
            grid-template-columns: repeat(3, 100px);

            grid-template-areas:
                "top top top"
                "mid mid ."
                "bottom . .";

            /* 由于绘制了9*9的单元格,我们给每个单元格进行了命名 ,一定要是这种格式*/

        }

        main * {
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;
        }

        main header {
            /* 完整的写法,推荐使用下面的简写方式*/
            /* grid-area: top-start/top-start//top-start/top-end/top-end/top-end; */
            grid-area: top;
            background-color: blueviolet;
        }

        main article {
            grid-area: mid;
            background-color: violet;
        }

        main footer {
            grid-area: bottom;
            background-color: yellowgreen;
        }
    </style>
</head>

<body>

    <main>
        <header></header>
        <article></article>
        <footer></footer>
    </main>

</body>

</html>

栅格元素之元素排序

排序方式

默认情况下,整个栅格元素都是以行(水平)进行填充排序,我们可以在容器中设置grid-auto-flow属性可以改变元素排序的方式。

描述
column 按列排序
row 按行排列

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 300px;
            height: 300px;

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template: repeat(3, 100px)/repeat(3, 100px);
            /* 排序方式:垂直 */
            grid-auto-flow: column;
        }

        section {
            background-color: blueviolet;
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;

            text-align: center;
            line-height: 78px;
            color: #fff;
        }
    </style>
</head>

<body>

    <main>
        <section>1</section>
        <section>2</section>
        <section>3</section>
        <section>4</section>
        <section>5</section>
        <section>6</section>
        <section>7</section>
        <section>8</section>
        <section>9</section>
    </main>

</body>

</html>

空间填充

当元素在栅格中放不下时,将会发生换行产生留白,使用grid-auto-flow: row dense; 可以执行填充空白区域操作。

如下图,产生了两个空间。

CSS3系列 12 栅格布局

当设置之后可以发现,1和2的位置都没变,3和4填充了上来:

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 300px;
            height: 300px;

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template: repeat(3, 100px)/repeat(3, 100px);
            /* 排序方式:水平  是否填充空间:填充 */
            grid-auto-flow: row dense;

        }

        section {
            background-color: blueviolet;
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;

            text-align: center;
            line-height: 78px;
            color: #fff;
        }

        main section:nth-of-type(1) {
            /* 列线 第1根开始往后数2根的区域 */
            grid-column: 1/span 2;
        }

        main section:nth-of-type(2) {
            /* 列线 第2根开始往后数2根的区域 */
            grid-column: 2/span 2;
        }
    </style>
</head>

<body>

    <main>
        <section>1</section>
        <section>2</section>
        <section>3</section>
        <section>4</section>
    </main>

</body>

</html>

对齐方式

对齐选项

可以通过属性方便的定义栅格容器内栅格元素的对齐方式,可用值包括 start | end | center | stretch | space-between | space-evenly | space-around。

下面是提供对齐的属性:

属性 描述 对象
align-items 栅格内所有元素的垂直排列方式 栅格容器
justify-items 栅格内所有元素的横向排列方式 栅格容器
justify-content 所有栅格在容器中的水平对齐方式,容器有额外空间时 栅格容器
align-content 所有栅格在容器中的垂直对齐方式,容器有额外空间时 栅格容器
align-self 元素在栅格中垂直对齐方式 栅格元素
justify-self 元素在栅格中水平对齐方式 栅格元素

下面是属性中可填入的值:

描述
start 元素按排序方式顺序排列
end 元素按排序方式倒序排列
center 元素在容器中
space-between 第一个元素靠起点,最后一个元素靠终点,余下元素平均分配空间
space-around 每个元素两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍
space-evenly 元素间距离平均分配

整体区域对齐

其实这些和弹性布局中的用法都差不多,可以看一下前一章写的弹性布局,那么这里就举例一个平均分配吧。

平均分布指的是,栅格容器中的栅格区域(即单元格),在栅格容器中的对齐方式。

注意:栅格容器一定要有多余空间。

指定所有区域对齐方式使用justify-content与align-content:

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 600px;
            /* 宽度和高度要足够大 */
            height: 600px;

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template: repeat(3, 100px)/repeat(3, 100px);
            /* 水平平均 */
            justify-content: space-evenly;
            /* 垂直平均 */
            justify-content: space-evenly;
            align-content: space-evenly;

        }

        section {

            background-color: blueviolet;
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;

            text-align: center;
            line-height: 78px;
            color: #fff;
        }
    </style>
</head>

<body>

    <main>
        <section>1</section>
        <section>2</section>
        <section>3</section>
        <section>4</section>
        <section>5</section>
        <section>6</section>
        <section>7</section>
        <section>8</section>
        <section>9</section>
    </main>

</body>

</html>

所有元素对齐

指的是栅格区域中具体的栅格元素的对齐方式,比如说一个单元格太大了,那么里面内容又太小了该怎么做。

指定所有栅格区域中的具体元素使用:justify-items与align-items

注意:栅格区域一定要有多余空间。

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 300px;
            height: 300px;

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template: repeat(3, 100px)/repeat(3, 100px);

            /* 控制具体元素在单元格中的位置 */
            justify-items: center;
            align-items: center;

        }

        section {
            background-color: blueviolet;
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;

            text-align: center;
            color: #fff;

            width: 30px;
            height: 30px;
            line-height: 30px;

        }
    </style>
</head>

<body>

    <main>
        <section>1</section>
        <section>2</section>
        <section>3</section>
        <section>4</section>
        <section>5</section>
        <section>6</section>
        <section>7</section>
        <section>8</section>
        <section>9</section>
    </main>

</body>

</html>

单个元素对齐

如果想控制单个元素对齐方式,使用justify-self与align-self即可。

注意:盛放该元素的栅格区域一定要有多余空间。

CSS3系列 12 栅格布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            padding: 100px;
        }

        main {
            width: 300px;
            height: 300px;

            border: solid 5px silver;
            display: grid;

            /* 行数,列数 */
            grid-template: repeat(3, 100px)/repeat(3, 100px);

            /* 控制具体元素在单元格中的位置 */
            justify-items: center;
            align-items: center;

        }

        section {
            background-color: blueviolet;
            background-clip: content-box;
            padding: 10px;
            border: dashed 1px black;

            text-align: center;
            color: #fff;

            width: 30px;
            height: 30px;
            line-height: 30px;

        }

        main section:nth-of-type(1) {
            justify-self: end;
            align-self: end;
        }

        main section:nth-of-type(2) {
            justify-self: start;
            align-self: end;
        }

        main section:nth-of-type(4) {
            justify-self: end;
            align-self: start;
        }

        main section:nth-of-type(5) {
            justify-self: start;
            align-self: start;
        }
    </style>
</head>

<body>

    <main>
        <section>1</section>
        <section>2</section>
        <section>3</section>
        <section>4</section>
        <section>5</section>
        <section>6</section>
        <section>7</section>
        <section>8</section>
        <section>9</section>
    </main>

</body>

</html>

简写模式

1)place-content用于控制栅格中所有区域的对齐方式,语法如下:

place-content: <align-content> <justify-content>

2)place-items用于控制所有区域中所有元素的对齐方式,语法如下:

place-items: <align-items> <justify-items>

3)place-self用于控制区域中单个元素的对齐方式,语法如下:

place-self: <align-self> <justify-self>
上一篇:布局方式,两列三列布局中间自适应


下一篇:Linux性能优化(四)——BCC性能监控工具