【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 版高分译文专栏,全网首发,精译精校,持续更新,计划今年内完成全书翻译,敬请期待!!!

相关推荐
活宝小娜1 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点1 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow1 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o1 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
开心工作室_kaic2 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā2 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
沉默璇年4 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder4 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
2401_882727574 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
SoaringHeart4 小时前
Flutter进阶:基于 MLKit 的 OCR 文字识别
前端·flutter