当前位置: 首页 > news >正文

【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 网格的组成部分

图 5.3 网格的组成部分

构建网格布局时会涉及到这些组成部分。例如,声明 grid-template-columns: 1fr 1fr 1fr 就能定义三个等宽且垂直的 网格轨道,同时还定义了四条垂直的的 网格线:一条位于网格的最左边;另外两条位于每个网格轨道之间,还有一条则位于网格的最右边。

上一章我们用 Flexbox 构建过一个示例页。不妨再回过头去看看当时的设计,考虑一下该怎样用网格布局再来实现一版。总体设计如图 5.4 所示,虚线标出了每个网格单元的位置。注意,某些区域跨越了好几个网格单元,即填充了更大的 网格区域

图 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.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-columnsgrid-template-rows 定义了网格轨道。因为列的分数单位分别为 2fr1fr,所以第一列的宽度是第二列的两倍。定义行的时候用到了一个新方法,即 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() 函数定制重复模式示意图

图 5.6 在网格模板定义里使用 repeat() 函数定制重复模式示意图

还可以将 repeat() 作为更长的模式的一部分进行简化。例如,grid-template-columns: 1fr repeat(3, 3fr) 1fr 定义了一个 1fr 宽的列,后面是连续三个宽度为 3fr 的列,最后又是一个宽 1fr 的列(即 1fr 3fr 3fr 3fr 1fr)。不难发现,完整版的模板定义乍一看未必直观,因此才有了 repeat() 这样的简化写法。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • digits Social Login插件 google OAuth 2.0登录 400 redirect_uri_mismatch错误解决
  • Python 从入门到实战14(字符串相关操作)
  • 电源自动测试系统有哪些原理和优势?
  • [综述笔记]Federated learning for medical image analysis: A survey
  • 决策树算法原理
  • 一文彻底了解DNS协议工作原理,恐怕没有比这更通俗易懂的了吧?
  • 1.C++入门1(c++编译过程,命名空间,C++输入输出,缺省参数)
  • es6(1)
  • 如何使用Spoon连接data-integration-server并在服务器上执行转换
  • 使用WordCloud报错‘ImageDraw‘ object has no attribute ‘textbbox‘
  • 2024年一区SCI-极光优化算法 Polar Lights Optimization-附Matlab免费代码
  • opencv的球面投影
  • 基于SpringBoot的大学生创新创业训练项目管理系统
  • 「OC」ViewController的生命周期
  • wakenet尾迹
  • Apache的基本使用
  • Bytom交易说明(账户管理模式)
  • CEF与代理
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • extjs4学习之配置
  • Rancher如何对接Ceph-RBD块存储
  • spring-boot List转Page
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • vue中实现单选
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 对JS继承的一点思考
  • 那些被忽略的 JavaScript 数组方法细节
  • 那些年我们用过的显示性能指标
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 关于Android全面屏虚拟导航栏的适配总结
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • ​学习笔记——动态路由——IS-IS中间系统到中间系统(报文/TLV)​
  • #stm32驱动外设模块总结w5500模块
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (06)金属布线——为半导体注入生命的连接
  • (2022 CVPR) Unbiased Teacher v2
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (libusb) usb口自动刷新
  • (PADS学习)第二章:原理图绘制 第一部分
  • (二)正点原子I.MX6ULL u-boot移植
  • (简单) HDU 2612 Find a way,BFS。
  • (力扣)1314.矩阵区域和
  • (一)基于IDEA的JAVA基础12
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • (转)http-server应用
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • **PHP分步表单提交思路(分页表单提交)
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .NET 8 跨平台高性能边缘采集网关
  • .net core 连接数据库,通过数据库生成Modell
  • .NET Micro Framework 4.2 beta 源码探析
  • .Net Remoting常用部署结构