【CSS in Depth 2 精译_029】5.2 Grid 网格布局中的网格结构剖析(上)
当前内容所在位置(可进入专栏查看其他译好的章节内容)
- 第一章 层叠、优先级与继承(已完结)
- 1.1 层叠
- 1.2 继承
- 1.3 特殊值
- 1.4 简写属性
- 1.5 CSS 渐进式增强技术
- 1.6 本章小结
- 第二章 相对单位(已完结)
- 2.1 相对单位的威力
- 2.2 em 与 rem
- 2.3 告别像素思维
- 2.4 视口的相对单位
- 2.5 无单位的数值与行高
- 2.6 自定义属性
- 2.7 本章小结
- 第三章 文档流与盒模型(已完结)
- 3.1 常规文档流
- 3.2 盒模型
- 3.3 元素的高度
- 3.4 负的外边距
- 3.5 外边距折叠
- 3.6 容器内的元素间距问题
- 3.7 本章小结
- 第四章 Flexbox 布局(已完结)
- 4.1 Flexbox 布局原理
- 4.2 弹性子元素的大小
- 4.3 弹性布局的方向
- 4.4 对齐、间距等细节处
- 4.5 本章小结
- 第五章 网格布局 ✔️
- 5.1 构建基础网格
- 5.2 网格结构剖析 (上篇,已完成 ✔️)
- 5.2.1 网格线的编号(下篇,精译中 ⏳)
- 5.2.2 网格与 Flexbox 配合(下篇,精译中 ⏳)
文章目录
- 5.2 网格结构剖析
译者按
上一节,我们通过一个 2行 × 3列 的简单网格了解了网格布局中的两个核心概念 —— 网格容器(grid container)和网格元素(grid items),并认识了一个新的尺寸单位fr(表示 fraction unit,即分数单位)。这一节,作者将结合上一章 Flexbox 布局使用的示例页,对网格布局的结构进行抽丝剥茧的深入讲解,一起来看看吧(由于内容相对较多,拟分为上篇、下篇两个部分发表,本篇为上篇)。
5.2 网格结构剖析
了解网格的各个部分非常重要。前面已经学习了 网格容器 和 网格元素,它们是网格布局的基本要素。还有四个重要概念如图 5.3 所示:
- 网格线(grid line):网格线构成了网格的框架结构,分水平网格线和垂直网格线两种,分别位于某行或某列的任意一侧。如果指定了间隙
gap,那间隙就在网格线上。 - 网格轨道(grid track):它是两条相邻网格线之间的空间。网格可以有多个水平轨道(多行),以及多个垂直轨道(多列)。
- 网格单元(grid cell):它是网格上的一块单独空间,是水平和垂直网格轨道交叉重叠的部分。
- 网格区域(grid area):它是网格上的矩形区域,由一个或多个网格单元组成;该区域位于两条垂直网格线和两条水平网格线之间。

图 5.3 网格的组成部分
构建网格布局时会涉及到这些组成部分。例如,声明 grid-template-columns: 1fr 1fr 1fr 就能定义三个等宽且垂直的 网格轨道,同时还定义了四条垂直的的 网格线:一条位于网格的最左边;另外两条位于每个网格轨道之间,还有一条则位于网格的最右边。
上一章我们用 Flexbox 构建过一个示例页。不妨再回过头去看看当时的设计,考虑一下该怎样用网格布局再来实现一版。总体设计如图 5.4 所示,虚线标出了每个网格单元的位置。注意,某些区域跨越了好几个网格单元,即填充了更大的 网格区域。

图 5.4 用网格创建的网页布局效果图。虚线标出了每个网格单元的位置
上面的网格布局包含四行两列,其中前两个水平网格轨道分别是页面标题(Ink)部分和主导航菜单部分。主区域填满了第一个垂直轨道剩余的两个网格单元,而侧边栏的两个板块则分置于第二个垂直轨道剩余的两个网格单元内。
说明
布局设计无需填满每一个网格单元。在想留白的地方空出对应的网格单元即可。
使用 Flexbox 布局时,必须按照一定的方式去嵌套元素。第 5 章我们先用 Flexbox 定义了两列,然后在右侧边栏嵌套了另一个 Flexbox 来定义两个子板块所在的行(详见代码清单 5.1)。要用网格实现同样的布局效果,就得改改页面的 HTML 结构:将嵌套的 HTML 拉平,使得放置在网格内的每个页面元素都必须是主网格容器(main grid container)的子元素。新的 HTML 标记如代码清单 5.3 所示。创建一个新页面,并按以下代码更新页面内容(或者直接修改第五章中的示例页)。
代码清单 5.3 网格布局对应的 HTML 结构
<body><div class="container"><!-- 这里的“容器”即网格容器 --><header><!-- 每个网格元素都必须是网格容器的子元素 --><h1 class="page-heading">Ink</h1></header><nav><!-- 每个网格元素都必须是网格容器的子元素 --><ul class="site-nav"><li><a href="/">Home</a></li><li><a href="/features">Features</a></li><li><a href="/pricing">Pricing</a></li><li><a href="/support">Support</a></li><li class="nav-right"><a href="/about">About</a></li></ul></nav><main class="main tile"><!-- 每个网格元素都必须是网格容器的子元素 --><h1>Team collaboration done right</h1><p>Thousands of teams from all over theworld turn to <b>Ink</b> to communicateand get things done.</p></main><div class="sidebar-top tile"><!-- 每个网格元素都必须是网格容器的子元素 --><form class="login-form"><h3>Login</h3><p><label for="username">Username</label><input id="username" type="text"name="username"/></p><p><label for="password">Password</label><input id="password" type="password"name="password"/></p><button type="submit">Login</button></form></div><div class="sidebar-bottom tile centered stack"><!-- 每个网格元素都必须是网格容器的子元素 --><small>Starting at</small><div class="cost"><span class="cost-currency">$</span><span class="cost-dollars">20</span><span class="cost-cents">.00</span></div><a class="cta-button" href="/pricing">Sign up</a></div></div>
</body>
新版页面将所有内容区域都变成了网格元素:标题、菜单(nav)、主区域外加两个侧边栏。主区域和两个侧边栏都加上了 tile 样式类,因为它们都是白色背景,也有相同的内边距。
接着对新页面应用网格布局,并将各部分内容指定到对应区域。稍后我们将基于第五章的这版示例页引入大量新的样式,现在不妨先看看网格生效后的页面渲染情况,如图 5.5 所示。

图 5.5 基础网格布局生效后的示例页效果图
然后新建一张样式表,并关联到该页面。样式内容如代码清单 5.4 所示:
代码清单 5.4 最外层设置的网格布局样式
*,
::before,
::after {box-sizing: border-box;
}:root {--gap-size: 1.5rem;
}body {background-color: #709b90;font-family: Helvetica, Arial, sans-serif;
}.stack > * + * {margin-block-start: 1.5em;
}.container {display: grid;grid-template-columns: 2fr 1fr; /* 定义两个垂直的网格轨道 */grid-template-rows: repeat(4, auto); /* 定义四个大小为 auto 水平网格轨道 */gap: var(--gap-size);max-inline-size: 1080px; margin-inline: auto;
}header,
nav {grid-column: 1 / 3; /* 垂直网格线从1号线跨越至3号线 */grid-row: span 1; /* 恰好跨越一条水平轨道 */
}.main {/* 将其他网格元素定位到不同的网格线之间 */grid-column: 1 / 2;grid-row: 3 / 5;
}.sidebar-top {/* 将其他网格元素定位到不同的网格线之间 */grid-column: 2 / 3;grid-row: 3 / 4;
}.sidebar-bottom {/* 将其他网格元素定位到不同的网格线之间 */grid-column: 2 / 3;grid-row: 4 / 5;
}.tile {padding: 1.5em;background-color: #fff;
}.tile > :first-child {margin-top: 0;
}
这段样式代码引入了很多新的写法,下面来逐个击破——
首先对 .container 设置了网格容器,并用 grid-template-columns 和 grid-template-rows 定义了网格轨道。因为列的分数单位分别为 2fr 和 1fr,所以第一列的宽度是第二列的两倍。定义行的时候用到了一个新方法,即 repeat() 函数,用于简化多个网格轨道的声明。
声明 grid-template-rows: repeat(4, auto) 定义了四个高度为 auto 的水平网格轨道。这种写法相当于声明 grid-template-rows: auto auto auto auto 。轨道大小指定为 auto,表示轨道尺寸将根据自身内容进行调整。
repeat() 简化表示法还可以用来定义不同的重复模式,比如 repeat(3, 2fr 1fr) 会重复三遍 2fr 1fr,从而定义出六个网格轨道,重复的结果为 2fr 1fr 2fr 1fr 2fr 1fr,效果如图 5.6 所示。

图 5.6 在网格模板定义里使用 repeat() 函数定制重复模式示意图
还可以将 repeat() 作为更长的模式的一部分进行简化。例如,grid-template-columns: 1fr repeat(3, 3fr) 1fr 定义了一个 1fr 宽的列,后面是连续三个宽度为 3fr 的列,最后又是一个宽 1fr 的列(即 1fr 3fr 3fr 3fr 1fr)。不难发现,完整版的模板定义乍一看未必直观,因此才有了 repeat() 这样的简化写法。
相关文章:
【CSS in Depth 2 精译_029】5.2 Grid 网格布局中的网格结构剖析(上)
当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一章 层叠、优先级与继承(已完结) 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位(已完结) 2.1 相对…...
ZYNQ LWIP(RAW API) TCP函数学习
1 LWIP TCP函数学习 tcp_new()–新建控制块 这个函数用于分配一个TCP控制块,它通过tcp_alloc()函数分配一个TCP控制块结构来存储TCP控制块的数据信息, 如果没有足够的内容分配空间,那么tcp_alloc()函数就会尝试释放一些不太重要的TCP控制块, 比如就会释放处于TIME_WAIT、C…...
Spring Boot,在应用程序启动后执行某些 SQL 语句
在 Spring Boot 中,如果你想在应用程序启动后执行某些 SQL 语句,可以利用 spring.sql.init 属性来配置初始化脚本。这通常用于在应用启动时创建数据库表、索引、视图等,或者填充默认数据。data-locations 和 schema-locations 指定了 SQL 脚本…...
【SQL】百题计划:SQL最基本的判断和查询。
[SQL]百题计划 Select product_id from Products where low_fats "Y" and recyclable "Y";...
04_Python数据类型_列表
Python的基础数据类型 数值类型:整数、浮点数、复数、布尔字符串容器类型:列表、元祖、字典、集合 列表 列表(List)是一种非常灵活的数据类型,它可以用来存储一系列的元素。容器类型,能够存储多个元素的…...
F5设备绑定EIP
公网IP 公网IP(Public IP Address)是指可以直接在互联网上访问的IP地址,用于标识网络上的设备或主机。它允许外部网络访问您的云服务器,如提供远程登录服务、访问Web服务器等。然而,这并不意味着公网IP不需要路由。 …...
使用 PyCharm 新建 Python 项目详解
使用 PyCharm 新建 Python 项目详解 文章目录 使用 PyCharm 新建 Python 项目详解一 新建 Python 项目二 配置环境1 项目存放目录2 Python Interpreter 选择3 创建隔离环境4 选择你的 Python 版本5 选择 Conda executable 三 New Window 打开项目四 目录结构五 程序编写运行六 …...
从0开始学习 RocketMQ:分布式事务消息的实现
消息队列中的事务,主要是解决消息生产者和消息消费者数据一致性的问题。 应用场景 比如订单系统创建订单后,会发消息给购物车系统,将已下单的商品从购物车中删除。 由于购物车删除商品这一步骤并不是用户下单支付这个主流程中的核心步骤&a…...
MySQL 查询数据库的数据总量
需求:查看MySQL数据库的数据总量,以MB为单位展示数据库占用的磁盘空间 实践: 登录到MySQL数据库服务器。 选择你想要查看数据总量的数据库: USE shield;运行查询以获取数据库的总大小: SELECT table_schema AS Datab…...
[C++]——vector
🌇个人主页:_麦麦_ 📚今日小句:快乐的方式有很多种,第一种便是见到你。 目录 一、前言 二、vector的介绍及使用 2.1 vector的介绍 2.2 vector的使用 2.2.1 vector的定义(构造函数) 2.2.2…...
自动驾驶:LQR、ILQR和DDP原理、公式推导以及代码演示(七、CILQR约束条件下的ILQR求解)
(七)CILQR约束条件下的ILQR求解 CILQR((Constrained Iterative Linear Quadratic Regulator)) 是为了在 iLQR 基础上扩展处理控制输入和状态约束的问题。在这种情况下,系统不仅要优化控制输入以最小化代价函数&#x…...
随想录笔记-二叉树练习题
合并二叉树 617. 合并二叉树 - 力扣(LeetCode) dfs递归 class Solution {public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {if(root1null||root2null){return root1null?root2:root1;}return dfs(root1,root2);}public TreeNode dfs(Tre…...
华雁智科前端面试题
1. var 变量的提升 题目: var a 1 function fun() {console.log(b)var b 2 } fun() console.log(a) 正确输出结果:undefined、1答错了,给一个大嘴巴子,错误答案输出结果为:2,1 此题主要考察 var 定义的变量&…...
【iOS】单例模式
【iOS】单例模式 什么是单例模式? 定义 单例模式,简单地说就是一个类只对应一个对象,每次使用这个类时,都只能获取到那一个对象。它的详细定义如下: 如果一个类始终只能创建一个实例,则这个类被称为单例…...
Linux | 探索 Linux 信号机制:信号的产生和自定义捕捉
信号是 Linux 操作系统中非常重要的进程控制机制,用来异步通知进程发生某种事件。理解信号的产生、阻塞、递达、捕捉等概念,可以帮助开发者更好地编写健壮的应用程序,避免由于未处理的信号导致程序异常退出。本文将带你从基础概念开始&#x…...
递归的时间复杂度分析
确定回溯算法的时间复杂度通常比较复杂,因为它取决于搜索空间的大小以及你的剪枝效率。对于生成从1到n的所有长度为k的组合。分析这类算法的时间复杂度时,我们通常需要考虑递归树的所有可能路径。 组合数 生成的组合数量是从n个元素中选择k个的组合数&…...
C++: 二叉树进阶面试题
做每件事之前都心存诚意, 就会事半功倍. 目录 前言1. 根据二叉树创建字符串2. 二叉树的层序遍历Ⅰ3. 二叉树的层序遍历Ⅱ4. 二叉树的最近公共祖先5. 二叉搜索树与双向链表6. 根据一棵树的前序遍历与中序遍历构造二叉树7. 根据一棵树的中序遍历与后序遍历构造二叉树8. 二叉树的…...
【HarmonyOS NEXT】实现网络图片保存到手机相册
【问题描述】 给定一个网络图片的地址,实现将图片保存到手机相册 【API】 phAccessHelper.showAssetsCreationDialog【官方文档】 https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-photoaccesshelper-V5#showassetscreationdialog…...
Pytorch详解-数据模块
Pytorch详解-数据模块 torch.utils.data.Dataset数据交互模块—Dataset的功能示例系列APIsconcatSubsetrandom_splitsampler unsqueeze DataLoaderDataLoader功能支持两种形式数据集读取自定义采样策略自动组装成批数据多进程数据加载自动实现锁页内存(Pinning Memo…...
浅谈openresty
熟悉了nginx后再来看openresty,不得不说openresty是比较优秀的。 对nginx和openresty的历史等在这此就不介绍了。 首先对标nginx,自然有优劣 一、开发难度 nginx: 毫无疑问nginx的开发难度比较高,需要扎实的c/c基础ÿ…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
