CSS Grid 二维布局系统认知(一)

CSS Grid布局(又称为 “网格布局” ),是一个基于网格的二维布局系统。
一开始我们用表格(table),然后是浮动(float),再是定位(postion)和内嵌块(inline-block)来布局页面,但是所有这些方法本质上都是只是 hack 而已,并且遗漏了很多重要的功能(例如垂直居中)。Flexbox 很大程度上改善了我们的布局方式,但它只是解决了更简单的一维布局,而不是复杂的二维布局(实际上 Flexbox 和 Grid 能协同工作,而且配合得非常好)。Grid(网格) 布局是第一个专门为解决布局问题而创建的 CSS 模块。

这篇文章,我将使用 CSS Grid 进行快速布局。

HTML 结构:

<div class="container">
  <div class="header">HEADER</div>
  <div class="menu">MENU</div>
  <div class="content">CONTENT</div>
  <div class="footer">FOOTER</div>
</div>

设置基本的 CSS:

.container {
    display: grid;    
    grid-template-columns: repeat(12, 1fr);
    grid-template-rows: 50px 350px 50px;
    grid-gap: 5px;
}

在 container 元素设置 display: grid; ,将其设置为网格容器;
使用 grid-template-columns 属性创建一个 12 列的网格,每个列都是一个单位宽度(总宽度的 1/12 ),(注:其中, repeat(12, 1fr) 意思是 12 个重复的 1fr 值。 fr 是网格容器剩余空间的等分单位。)
使用 grid-template-rows 属性创建 3 行,第一行高度是 50px ,第二行高度是 350px 和第三行高度是 50px;
使用 grid-gap 属性在网格中的网格项之间添加一个间隙;

添加 grid-template-areas

.container {
    display: grid;
    grid-gap: 5px;    
    grid-template-columns: repeat(12, 1fr);
    grid-template-rows: 50px 350px 50px;
    grid-template-areas:
        "h h h h h h h h h h h h"
        "m m c c c c c c c c c c"
        "f f f f f f f f f f f f";
}

这个属性被称为网格区域,也叫模板区域。

grid-template-areas 属性背后的逻辑是你在代码中创建的网格可视化表示。正如你所看到的,它有 3 行 12 列,和我们在 grid-template-columnsgrid-template-rows 中定义的正好呼应。

每行代表一行,用网格术语来说是 网格轨道(Grid Track) ,每个字符( h,m,c,f)代表一个网格单元格。注:其实是 网格区域(Grid Area) 名称,你可以使用任意名称。四个字母中的每一个现在都形成一个矩形 grid-area

你可能已经猜到,我选择了字符 h,m,c,f,是因为他们是 header, menu, content 和 footer 的首字母。 当然,我可以把它们叫做任何想要的名称,但是使用他们所描述的东西的第一个字符更加容易让人理解。

给网格项设定网格区域名称:

现在将这些字符与网格中的 网格项 建立对应的连接。在网格项使用 grid-area 属性即可:

.header {
    grid-area: h;
}
.menu {
    grid-area: m;
}
.content {
    grid-area: c;
}
.footer {
   grid-area: f;
}

以下是完整的布局效果:
在这里插入图片描述
尝试其他布局:

Grid(网格) 布局 的精妙之处在于我们可以很容易地对布局进行修改尝试。只需修改 grid-template-areas 属性的字符即可。举个例子,把 menu 移到左边:

grid-template-areas:
        “h h h h h h h h h h h h”
        "c c c c c c c c c c m m”
        “f f f f f f f f f f f f”;

在这里插入图片描述
我们可以使用点 . 来创建空白的网格单元格。

grid-template-areas:
        “. h h h h h h h h h h .”
        "c c c c c c c c c c m m”
        “. f f f f f f f f f f .”;

修改的布局效果看起来是这样的:
在这里插入图片描述
添加响应式布局:

将 Grid(网格) 布局 与 响应式布局 结合起来,简直就是一个杀手锏。因为在 Grid(网格) 布局之前,仅使用 HTML 和 CSS 实现的响应式布局不可能的做到简单而又完美。

假设你想在移动设备上查看的是:标题旁边是菜单。那么你可以简单地这样做:

@media screen and (max-width: 640px) {
    .container {
        grid-template-areas:
            "m m m m m m h h h h h h"
            "c c c c c c c c c c c c"
            "f f f f f f f f f f f f";
    }
}

你可以看到以下效果:
在这里插入图片描述

会发现,所有这些更改都是使用纯 CSS 完成的,不需要修改 HTML 。 不管 div 标签在 HTML 中是怎么样的顺序结构,我们都可以随意转换。这点与 flexbox 类似,网格项(grid items)的源顺序无关紧要。CSS 可以以任何顺序放置它们,这使得用 媒体查询(media queries)重新排列网格变得非常容易。

这被称为结构和表现分离, Grid(网格) 布局真正做到了这点,对于 CSS 来说是一个巨大的进步。它允许 HTML 成为它想要的样子: 作为内容的标记。HTML 结构不再受限于样式表现,比如不要为了实现某种布局而多次嵌套,现在这些都可以让 CSS 来完成。

最终代码如下:

<!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>grid demo</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        .container {
            display: grid;
            grid-template-columns: repeat(12, 1fr);
            grid-template-rows: 50px 350px 50px;
            grid-gap: 5px;
            grid-template-areas:
                "h h h h h h h h h h h h"
                "m m c c c c c c c c c c"
                "f f f f f f f f f f f f"
            ;
        }

        @media screen and (max-width: 640px) {
            .container {
                grid-template-areas:
                    "m m m m m m h h h h h h"
                    "c c c c c c c c c c c c"
                    "f f f f f f f f f f f f";
            }
        }

        .header {
            grid-area: h;
            background: khaki;
        }

        .menu {
            grid-area: m;
            background: orchid;
        }

        .content {
            grid-area: c;
            background: goldenrod;
        }

        .footer {
            grid-area: f;
            background: lightcoral;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="header">HEADER</div>
        <div class="menu">MENU</div>
        <div class="content">CONTENT</div>
        <div class="footer">FOOTER</div>
    </div>
</body>

</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值