【CSS in Depth 2 精译_034】5.4 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.3 两种替代语法(已完结)
      • 5.3.1 命名网格线
      • 5.3.2 命名网格区域
    • 5.4 显式网格与隐式网格(上)
      • 5.4.1 添加变化 (中)
      • 5.4.2 让网格元素填满网格轨道(下) ✔️
    • 5.5 子网格

文章目录

      • [5.4.2 让网格元素填满网格轨道 Adjusting grid items to fill the grid track](#5.4.2 让网格元素填满网格轨道 Adjusting grid items to fill the grid track)

《CSS in Depth》新版封面

译者按

经过了 上篇中篇 的历练,不知道大家对隐式网格这个知识点掌握得怎么样?虽然也尽量考虑图文并茂,但我自己总感觉少了点实战的味道。好在我新发现了 CSDN 一个类似 CodePen 一样的模块,有时间的话我会尝试把这个"下篇"中的内容放进去看看效果。先对隐式网格这个知识点来个收尾吧。

5.4.2 让网格元素填满网格轨道 Adjusting grid items to fill the grid track

至此,您已经实现了相当复杂的页面布局,其间也没有花太多精力去设置每个元素的精确位置,而是将这些计算的活儿都交给了浏览器。

还剩最后一个问题:图片放大后并没有完全填满所在的网格单元,于是图片下方就空出一小段空白来。理想情况下,每个网格元素无论顶部还是底部,都应该与同一轨道上的其他元素对齐。现在顶部倒是对齐了,但底部却没有,如图 5.16 所示:

图 5.16 图片没能完全填满网格单元,留下了多余的空间

下面来解决这个问题。回想一下,每个网格元素都是一个 <figure>。它包含了一张图片和一个标题这两个子元素:

html 复制代码
<figure class="featured">
  <img src="images/monkey.jpg" alt="monkey" />
  <figcaption>Monkey</figcaption>
</figure>

默认情况下,每个 网格元素 都会通过拉伸来填满整个网格区域,但 子元素 例外,从而空出了多余的高度。一个简单点的解决办法是使用 Flexbox 布局。如代码清单 5.11 所示,将每个 <figure> 元素都视为一个竖直方向上的弹性容器,内部元素就会从上到下垂直排列;接着再给图片指定一个 flex-grow 值,就可以强制拉伸图片来填满空白区域。

只不过拉伸图片并不可取,因为会改变图片的宽高比(height-to-width ratio),从而导致图片变形。好在 CSS 提供了一个特殊的属性 object-fit 来处理这个问题。默认情况下,一个 <img> 图片元素的 object-fit 的属性值为 fill,也就是通过缩放整个图片来填满 <img> 元素。您也可以改成其他值来进行调节。

例如,object-fit 的属性值还可以是 covercontain(如图 5.17 所示)。这些值会告诉浏览器,要在不改变图片纵横比(aspect ratio)的情况下,调整渲染容器中图片大小,具体用法如下:

  • cover:通过扩展图片来填满容器(会导致图片被部分裁剪)。
  • contain:通过缩放来让图片在容器内完整展示(会导致容器内留白)。

图 5.17 使用 object-fit 控制图片在容器盒内的渲染方式

这里一定要区分清楚两个概念:一个是宽高由 <img> 元素决定的容器盒(the box),另一个是要渲染的图片。默认情况下,二者的尺寸大小是相等的。object-fit 属性只能对容器盒内的图片尺寸进行控制,而容器盒本身的大小则保持不变。

因为要用 flex-grow 拉伸图片,这里应该给它加上 object-fit: cover 以防变形。这样会裁剪掉图像的一小部分边缘------这也是必要的妥协。最终效果如图 5.18 所示。有关 object-fit 属性的更多详情,可以参考 CSS-Tricks 网站的文章《A Quick Overview of object-fit and object-position》。

图 5.18 所有图片都填满了网格区域并完美对齐后的效果图

至此,所有图片和标题的上下边缘都跟网格轨道对齐了,相关样式如代码清单 5.11 所示。请将它们更新到您的样式表中:

代码清单 5.11 使用垂直方向的 Flexbox 拉伸图片并填充网格区域的样式代码

css 复制代码
.portfolio > figure {
  display: flex; /* 令每个网格元素都成为垂直的 Flexbox */
  flex-direction: column; /* 令每个网格元素都成为垂直的 Flexbox */
  margin: 0;
}

.portfolio img {
  flex: 1; /* 使用 flex-grow 让图片填满弹性容器的可用空间 */
  object-fit: cover; /* 允许图片在不被拉伸变形的情况下填满容器(而是裁掉边缘) */
  max-inline-size: 100%;
}

这样,您的摄影作品墙就大功告成了!所有元素都整整齐齐地排列在网格里,浏览器决定了垂直网格轨道的数量和尺寸大小。布局算法启用紧凑型自主流动(dense auto-flow)模式后,浏览器也可以干净利落地填满所有的空白区域。

增补彩蛋

为方便大家在浏览本文时可以对隐式网格有个直观的认识,我专门在 InsCode 同步创建了一个示例项目,有点类似 CodePen 和 JSFiddle 这样的第三方沙箱工具。页面上方还加了两个效果切换按钮,模拟源码中样式生效前与生效后的两个状态,如下所示。欢迎多提宝贵意见,共同进步!!!



关于《CSS in Depth》(中译本书名《深入解析 CSS》)

第 1 版 第 2 版
读者评分 原版:4.7 (亚马逊);中文版:9.3(豆瓣) 原版:5.0(亚马逊);中文版:暂无,待出版
出版时间 原版:2018 年 3 月 ;中文版:2020 年 4 月 原版:2024 年 7 月;中文版:暂无,待出版
原价 原版:$44.99 ;中文版:¥139.00 原版:$59.99;中文版:暂无,待出版
现价 原版:$36.49 ;中文版:¥52.54 起步 原版:$52.09;中文版:暂无,待出版
原版国内预订 起步价 ¥461.00 起步价 ¥750.00

本专栏为该书第 2 版高分译文专栏,全网首发,精译精校,持续更新,计划今年内完成全书翻译,敬请期待!!!

相关推荐
致博软件F2BPM7 分钟前
Element Plus和Ant Design Vue深度对比分析与选型指南
前端·javascript·vue.js
慧一居士1 小时前
flex 布局完整功能介绍和示例演示
前端
DoraBigHead1 小时前
小哆啦解题记——两数失踪事件
前端·算法·面试
一斤代码6 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子7 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年7 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子7 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina7 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路8 小时前
React--Fiber 架构
前端·react.js·架构
伍哥的传说8 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js