CSS Grid 布局

我们提供了以下 HTML 与 CSS 布局:

html 复制代码
<!DOCTYPE html>
<html>

<head>
  <title>Using CSS Grid</title>
  <style>
    body {
      color: #fff;
      font-family: 'Nunito Semibold';
      text-align: center;
    }

    #content {
      max-width: 960px;
      margin: 0 auto;
    }

    #content div {
      background: #3bbced;
      padding: 30px;
    }

    #content div:nth-child(even) {
      background: #777;
      padding: 30px;
    }
  </style>
</head>

<body>

  <div id="content">

    <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>

</body>

</html>

运行效果如下

下面我们将进行 grid 布局的尝试

columns 列

grid-template-columns 通过设置每列占的比例进行布局。这里值里面写了几个,那么就有几列,各列按照比例选择宽度。

通过百分比布局

设置为三列,每列比例相同

css 复制代码
#content {
	display: grid; /* 首先说明这个大盒子为 grid 布局 */
    grid-template-columns: 33.3% 33.3% 33.3%; /* 三列,每列比例相同 */
    max-width: 960px;
  	margin: 0 auto;
}

效果如下:

设置为三列,每列所占比例为 30% 20% 50%

css 复制代码
#content {
	display: grid; /* 首先说明这个大盒子为 grid 布局 */
    grid-template-columns: 30% 20% 50%; /* 三列,每列所占比例为 30% 20% 50% */
    max-width: 960px;
  	margin: 0 auto;
}

效果如下:

通过分数(fraction)布局

设置为三列,每列比例 1 : 2 : 1

css 复制代码
#content {
	display: grid; /* 首先说明这个大盒子为 grid 布局 */
    grid-template-columns: 1fr 2fr 1fr; /* 三列,每列所占比例 1 : 2 : 1 */
    max-width: 960px;
  	margin: 0 auto;
}

效果如下

设置为三列,每列比例相同

css 复制代码
#content {
	display: grid; /* 首先说明这个大盒子为 grid 布局 */
    grid-template-columns: repeat(3, 1fr); /* 三列,每列所占比例相同 */
    max-width: 960px;
  	margin: 0 auto;
}

效果如下

rows 行

假设 #content 如下

css 复制代码
#content {
	display: grid; /* 首先说明这个大盒子为 grid 布局 */
    grid-template-columns: repeat(3, 1fr); /* 三列,每列所占比例相同 */
    max-width: 960px;
  	margin: 0 auto;
}

我们将第三个 <div> 内容修改为

html 复制代码
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nulla maiores quod eum consequuntur voluptate ad
consequatur nostrum, repellat minus consectetur laborum totam tempora temporibus, dolores expedita commodi
veritatis quos laudantium?
</div>

效果如下:

第一行的三个盒子因为第三个盒子内容过多被自动撑开了。

下面通过设置 row 行 来对每行高度进行设置:

设置盒子最小高度 100px,最大高度设置为 auto(随着文字增多变高)

css 复制代码
 #content {
      display: grid;/* 首先说明这个大盒子为 grid 布局 */
      grid-template-columns: repeat(3, 1fr); /* 三列,每列所占比例相同 */
      grid-auto-rows: minmax(100px, auto); /* 高度最低100px,最高auto */
      max-width: 960px;
      margin: 0 auto;
    }

效果如下:

设置每行高度相同,都为第三个盒子撑大的高度

css 复制代码
#content {
  display: grid;/* 首先说明这个大盒子为 grid 布局 */
  grid-template-columns: repeat(3, 1fr); /* 三列,每行所占比例相同 */
  grid-template-rows: repeat(3, 1fr);  /* 三行,每行所占比例相同 */
  max-width: 960px;
  margin: 0 auto;
}

效果如下:

如果改为:

css 复制代码
content {
  display: grid;/* 首先说明这个大盒子为 grid 布局 */
  grid-template-columns: repeat(2, 1fr); /* 三列,每行所占比例相同 */
  grid-template-rows: repeat(2, 1fr);
  max-width: 960px;
  margin: 0 auto;
}

效果如下:

改为:

css 复制代码
content {
  display: grid;/* 首先说明这个大盒子为 grid 布局 */
  grid-template-columns: repeat(3, 1fr); /* 三列,每行所占比例相同 */
  grid-template-rows: repeat(4, 1fr);
  max-width: 960px;
  margin: 0 auto;
}

效果如下:

发现多了一行,虽然这里没有盒子,但还是会占用空间(创建了网格)

gap 间隙

假设 #content 是这样:

css 复制代码
#content {
  display: grid;/* 首先说明这个大盒子为 grid 布局 */
  grid-template-columns: repeat(3, 1fr); /* 三列,每行所占比例相同 */
  grid-template-rows: repeat(3, 1fr);
  max-width: 960px;
  margin: 0 auto;
}

效果:

我们来设置每行每列的间隙

先设置每列的间隙:

css 复制代码
#content {
  display: grid;/* 首先说明这个大盒子为 grid 布局 */
  grid-template-columns: repeat(3, 1fr); /* 三列,每行所占比例相同 */
  grid-template-rows: repeat(3, 1fr);
  grid-column-gap: 20px;
  max-width: 960px;
  margin: 0 auto;
}

效果如下:

每行也设置:

css 复制代码
#content {
    display: grid;/* 首先说明这个大盒子为 grid 布局 */
    grid-template-columns: repeat(3, 1fr); /* 三列,每行所占比例相同 */
    grid-template-rows: repeat(3, 1fr);
    max-width: 960px;
    grid-column-gap: 20px;
    grid-row-gap: 20px;
    margin: 0 auto;
}

效果如下:

我们来检查一下,发现盒子并没有添加 margin

(单个盒子检查)

原来是盒子之间添加了间隙,但间隙不是这些小盒子的属性,是这个网格布局的属性

column & row lines

现在更新一下 <div id="content"> 中的内容为 6 个盒子,且每个盒子都加了class

html 复制代码
<div id="content">
    <div class="one">1</div>
    <div class="two">2</div>
    <div class="three">3</div>
    <div class="four">4</div>
    <div class="five">5</div>
    <div class="six">6</div>
</div>

#content 为:

css 复制代码
#content{
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    grid-template-rows: repeat(4, minmax(150px, auto));
    grid-gap: 10px;  /* 注意:也支持这样设置间隙 */
    max-width: 960px;
    margin: 0 auto;
}

也就是我们有 6 个盒子,画了一个 (6+1)*(4+1) 的网格。

效果如下:

下面我们开始布局

对第一个盒子设置:

css 复制代码
.one {
  grid-column-start: 1;
  grid-column-end: 3;
  /* 或者 grid-column: 1 / 3; */
}

效果如下:

还可以设置 row

css 复制代码
.one {
  grid-column: 1 / 3;
  grid-row: 1 / 3;
}

效果如下:

其他的盒子设置方法相同

nested grids 网格布局里面套一个网格布局

假设我们有#content大盒子下面的 6 个盒子

html 复制代码
<div id="content">
    <div>1</div>
    <div>2</div>
    <div>3</div>

    <div class="nested">
        <p>1</p>
        <p>2</p>
        <p>3</p>
        <p>4</p>
    </div>

    <div>5</div>
    <div>6</div>

其中 #content

css 复制代码
#content{
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 10px;
    max-width: 960px;
    margin: 0 auto;
}

在第四个盒子我们给他设置 grid 布局:

css 复制代码
.nested{
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-gap: 10px;
    /*grid-column: span 3;*/
}
.nested p{
    border: 1px solid #fff;
    padding: 20px;
    margin: 0;
}

效果如图:

aligning & justifying items 设置盒子的位置

align-jtems & justify-items 默认是 stretch 拉伸属性

给出盒子:

html 复制代码
<div id="content">
    <div class="one">1 with content</div>
    <div class="two">2</div>
    <div class="three">3</div>
    <div class="four">4</div>
    <div class="five">5</div>
    <div class="six">6</div>
</div>

#content 样式:

css 复制代码
#content{
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: minmax(150px, auto);
    grid-gap: 10px;
    max-width: 960px;
    margin: 0 auto;
}

效果如下:

由于这两个属性默认是 stretch,所以盒子会铺满整个划分出来的网格,我们可以通过手动设置不让盒子铺满网格,还能设置盒子出现的位置。

align-items#content盒子中的所有盒子出现在网格垂直方向的上、中、下位置

出现在上位置(start)、中位置(center)、下位置(end)

下面以上位置举例

css 复制代码
#content{
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: minmax(150px, auto);
    grid-gap: 10px;
    max-width: 960px;
    margin: 0 auto;
    align-items: start;
}

效果如下:

可以看到,这些小盒子目前在垂直方向 不再是 stretch 拉伸状态了,然而在水平位置还是 stretch 状态

justify-items#content 盒子中所有盒子出现在网格水平方向左、中、右位置

出现在左位置(start)、中位置(center)、右位置(end)

下面以中位置举例:

我们使用已经设置了 align-items: start 开始:

css 复制代码
#content{
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: minmax(150px, auto);
    grid-gap: 10px;
    max-width: 960px;
    margin: 0 auto;
    align-items: start;
    justify-items: center;
}

效果如下:

盒子出现在了水平方向上的中位置

align-self & justify-self 设置单个盒子(自己)的位置

假设 #content 样式:

css 复制代码
#content{
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: minmax(150px, auto);
    grid-gap: 10px;
    max-width: 960px;
    margin: 0 auto;
}

效果如下:

是默认的 stretch 拉伸样式。

我们来试试设置第一个盒子位置,设置为左下位置:

css 复制代码
.one {
  align-self: end;
  justify-self: start;
}

效果如下:

实例测试 Example: create a 12-column grid

使用 grid 进行简单的布局,并且还设置了一个点击按钮显示出辅助线的功能:

html 复制代码
<!DOCTYPE html>
<html>
<head>
<title>Using CSS Grid</title>
<style>
    body{
        color: #fff;
        font-family: 'Nunito Semibold';
        text-align: center;
    }
    #content{
        display: grid;
        grid-template-columns: repeat(12, 1fr);
        grid-auto-rows: minmax(100px, auto);
        grid-gap: 10px;
        max-width: 960px;
        margin: 0 auto;
        position:relative;
    }
    #content > *{
        background: #3bbced;
        padding: 30px;
    }
    header{
        grid-column: 1 / 13;
    }
    main{
        grid-column: 4 / 13;
        grid-row: 2 / 4;
    }
    aside{
        grid-column: 1 / 4;
    }
    nav{
        grid-column: 1 / 4;
    }
    section{
        grid-column: 1 / 13;
        grid-row: 4 / 6;
    }
    footer{
        grid-column: 1 / 13;
    }

    #grid{
        position: absolute;
        top: 0;
        left: 0;
        display: grid;
        grid-template-columns: repeat(12, 1fr);
        grid-auto-rows: minmax(100%, auto);
        width: 100%;
        height: 100%;
        background: transparent;
        padding: 0;
        display: none;
    }
    input:checked + #content #grid{
        display: grid;
    }
    #grid p{
        border: 1px solid;
        background: #000;
        margin: 0;
        opacity: 0.2;
    }
</style>
</head>
<body>

<input type="checkbox" />
<div id="content">

    <div id="grid">
        <p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p>
    </div>

    <header>Header</header>
    <main>Main</main>
    <section>Section</section>
    <aside>Aside</aside>
    <nav>Nav</nav>
    <footer>Footer</footer>

</div>

</body>
</html>

效果如下:

unchecked:

checked:

grid areas

可以通过这个功能快速构建出网页布局框架

给出如下 HTML 结构:

html 复制代码
<body>

<div id="content">

    <header>Header</header>
    <main>Main</main>
    <section>Section</section>
    <aside>Aside</aside>
    <nav>Nav</nav>
    <footer>Footer</footer>

</div>

</body>

CSS 样式

CSS 复制代码
body{
    color: #fff;
    font-family: 'Nunito Semibold';
    text-align: center;
}
#content{
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: minmax(100px, auto);
    grid-gap: 10px;
    max-width: 960px;
    margin: 0 auto;
}
#content > *{
    background: #3bbced;
    padding: 30px;
}

效果如下:

给每个盒子取一个 area 名字,然后通过简单的字符串组合布局( . 表示该网格中没盒子)

css 复制代码
#content{
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: minmax(100px, auto);
    grid-gap: 10px;
    max-width: 960px;
    margin: 0 auto;
    grid-template-areas:
        "header header header header"
        "aside . main main"
        "nav . main main"
        "section section section section"
        "section section section section"
        "footer footer footer footer";
}
header{
    grid-area: header;
}
main{
    grid-area: main;
}
aside{
    grid-area: aside;
}
nav{
    grid-area: nav;
}
section{
    grid-area: section;
}
footer{
    grid-area: footer;
}

效果如下:

references 参考文献

相关推荐
懒羊羊大王呀21 分钟前
CSS——属性值计算
前端·css
看到请催我学习2 小时前
如何实现两个标签页之间的通信
javascript·css·typescript·node.js·html5
昨天;明天。今天。4 小时前
案例-任务清单
前端·javascript·css
秋殇与星河6 小时前
CSS总结
前端·css
神之王楠7 小时前
如何通过js加载css和html
javascript·css·html
软件开发技术深度爱好者10 小时前
用HTML5+CSS+JavaScript庆祝国庆
javascript·css·html5
昨天;明天。今天。17 小时前
案例-表白墙简单实现
前端·javascript·css
金灰1 天前
CSS3练习--电商web
前端·css·css3
TonyH20021 天前
webpack 4 的 30 个步骤构建 react 开发环境
前端·css·react.js·webpack·postcss·打包
王小二(海阔天空)1 天前
个人文章合集 - 前端相关
前端·css·vue·jquery