跟着 MDN 学CSS day_42:等分轨道、层叠放置与混合布局

本文通过MDN网格布局技能测试的四道实战题目,解析CSS Grid在实际场景中的应用技巧。内容涵盖:grid-template-columns创建等分三列布局、基于网格线的跨轨道与层叠放置、grid-template-areas区域命名与元素映射、以及Grid与Flexbox混合使用构建复合卡片布局。每道题目均包含问题分析、完整代码方案和底层机制讲解。

1. 等分三列与自动行放置

第一道题目要求创建一个三列网格,四子项自动排列,列宽等分可用空间,行列间距均为20像素。这是Grid布局中最基础的轨道定义场景。

题目给出的HTML结构包含一个grid容器和四个div子项:

html 复制代码
<div class="grid">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
</div>

初始CSS中.grid没有任何样式,四个div按照默认的块级行为垂直堆叠。要完成题目要求,需要同时解决三个问题:创建三列、列宽等分、设置间距。

css 复制代码
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 20px;
}

display: grid将容器转变为grid容器。grid-template-columns: 1fr 1fr 1fr定义了三列轨道,每个轨道的宽度为1fr。三个1fr意味着浏览器将容器可用宽度三等分,每列获得完全相等的份额。使用1fr而非固定像素值,确保了列宽随容器缩放始终保持等分比例。

gap: 20px同时设置行间距和列间距为20像素。gap是grid-gap的标准写法,可以接受一个值同时应用于行和列,也可以接受两个值分别指定行间距和列间距。间隙空间在轨道之间创建,不影响轨道边缘与容器边缘的距离。

子项的自动放置由Grid的自动放置算法完成。四个子项依次填入网格单元格:One进入第1行第1列,Two进入第1行第2列,Three进入第1行第3列,Four进入第2行第1列。子项数量超过三列时自动折行,这一行为由隐式网格机制处理。题目未要求定义行轨道,因此隐式行的高度根据内容自动调整,auto为默认值。

这里有一个重要细节:题目没有使用repeat函数简化书写。grid-template-columns: 1fr 1fr 1fr等价于grid-template-columns: repeat(3, 1fr)。在列数确定且较少时两者效果相同,但当列数增多时repeat更简洁且易于修改。

2. 跨轨道放置与z-index层叠控制

第二道题目基于已定义的4列3行网格,要求两个子项跨越多个轨道,并且第二个子项覆盖在第一个子项上方。这涉及grid-column和grid-row的精确跨度控制,以及层叠上下文的z-index管理。

题目给出的网格容器已经定义好:

css 复制代码
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 100px 100px 100px;
  gap: 10px;
}

四列等宽,三行固定100像素高度,间隙10像素。两个子项item1和item2需要分别指定跨越的轨道范围。

css 复制代码
.item1 {
  grid-column: 1 / 4;
  grid-row: 1 / 3;
}

.item2 {
  grid-column: 2 / 5;
  grid-row: 2 / 4;
}

item1设置grid-column: 1 / 4,表示从第1条列线起始,延伸到第4条列线结束,跨越第1、2、3列,共三列宽度。grid-row: 1 / 3从第1条行线到第3条行线,跨越第1行和第2行,共两行高度。item1占据的区域是一个3列乘2行的矩形。

item2设置grid-column: 2 / 5,从第2条列线到第5条列线,跨越第2、3、4列。grid-row: 2 / 4从第2条行线到第4条行线,跨越第2行和第3行。item2占据的区域同样是一个3列乘2行的矩形。

两个元素的放置区域存在重叠部分。item1占据列1到3、行1到2;item2占据列2到4、行2到3。重叠发生在列2到3、行2的区域,即第2行中间两列的位置。

默认情况下,后出现的DOM元素在重叠时显示在上方,item2在源码中位于item1之后,因此item2覆盖item1。题目明确要求这个层叠关系,所以不需要额外设置z-index。如果实际需求与默认顺序相反,需要给item1设置较高的z-index值来调整堆叠顺序。

这种跨轨道放置的技术在创建非对称布局、杂志风格版面、以及需要特定元素突出显示的卡片设计中非常实用。网格线编号提供了精确到单元格级别的定位能力。

3. grid-template-areas的区域命名与元素映射

第三道题目要求使用grid-template-areas属性将四个子项按照指定布局排列,而不是使用基于线号的放置方式。这种方法的优势在于布局结构在CSS代码中直观可见。

题目给出的grid容器定义了两列不等宽的结构:

css 复制代码
.grid {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 10px;
}

第一列占可用空间的一份,第二列占两份,即1比2的宽度比例。四个子项分别是one、two、three、four,需要将它们放置到对应的网格区域。

解决方案分两步。第一步是在容器上使用grid-template-areas定义区域布局:

css 复制代码
.grid {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 10px;
  grid-template-areas:
    "one one"
    "two three"
    "four four";
}

grid-template-areas定义了3行2列的命名区域矩阵。第一行两个单元格都填写"one",表示名为one的元素横跨整行。第二行左侧"two"右侧"three",两个元素各占一列。第三行两个单元格都是"four",four同样横跨整行。

第二步是将每个子项通过grid-area属性绑定到对应的区域名称:

css 复制代码
.one {
  grid-area: one;
}

.two {
  grid-area: two;
}

.three {
  grid-area: three;
}

.four {
  grid-area: four;
}

grid-area的值直接引用grid-template-areas中定义的区域名称,不需要加引号。浏览器根据名称匹配关系自动将子项放入对应区域,无需计算线号或列数。

观察这个布局的几何特征:one和four各自横跨两列,利用了grid-template-areas中相同名称重复出现即表示跨列的特性。two和three各占一列,位于中间一行。整个布局形成一个头部横跨、中间分栏、底部横跨的经典三段式结构。

grid-template-areas的约束规则需要特别注意:同名区域必须形成矩形,不能出现在多个不连续的位置。例如"one"不能出现在第一行左侧和第二行右侧,这会形成L形区域,不是矩形,浏览器将拒绝渲染该布局。

4. Grid与Flexbox的混合嵌套布局

第四道题目要求同时使用Grid和Flexbox完成一个卡片列表布局,且不能修改HTML结构。题目展示了一个典型的混合布局场景:外层使用Grid控制卡片整体排列,内层使用Flexbox控制标签的流式排列。

题目给出的HTML结构是container包含四个card,每个card内部有一张图片和一个ul标签列表:

html 复制代码
<div class="container">
  <div class="card">
    <img src="balloons1.jpg" alt="a single red balloon" />
    <ul class="tags">
      <li>balloon</li>
      <li>red</li>
      <li>sky</li>
      <li>blue</li>
      <li>Hot air balloon</li>
    </ul>
  </div>
  <!-- 三个类似的card -->
</div>

外层容器需要将卡片排列为两行两列。这使用Grid布局最合适:

css 复制代码
.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}

两列等宽,卡片按顺序自动填充。前两个卡片占据第一行的两列,后两个卡片占据第二行的两列。使用1fr确保列宽随容器等分缩放,间隙20像素提供卡片之间的呼吸空间。

内层标签列表需要横向排列并自动换行。标签数量不一,有的卡片5个标签,有的4个。这使用Flexbox的wrap模式最合适:

css 复制代码
.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  list-style: none;
  padding: 0;
  margin: 10px 0 0 0;
}

.tags li {
  background-color: #eee;
  padding: 5px 10px;
  border-radius: 10px;
  font-size: 14px;
}

display: flex将ul转为flex容器,li标签沿主轴横向排列。flex-wrap: wrap是关键声明,当一行放不下所有标签时自动折行。每个li设置了背景色和内边距,呈现标签外观。标签之间的间距通过gap或margin控制。

这种Grid与Flexbox的混合使用反映了现代CSS布局的最佳实践。Grid负责宏观的页面结构划分,处理行与列的二维排布。Flexbox负责微观的组件内部排列,处理一维的内容流。两者各司其职,互不冲突。

在嵌套关系中,card既是Grid容器的一个网格项,又可以是Flexbox容器的父级,或者直接包含其他布局内容。card本身没有设置display: flex,它内部的img和ul按照默认文档流垂直排列,img在上,标签列表在下。如果卡片内部需要更复杂的排列,可以进一步给card设置display: flex改变其内部布局。

5. 四个题目覆盖的Grid核心能力总结

四道题目由浅入深地覆盖了Grid布局的核心能力,梳理其关联有助于形成完整的知识结构。

第一题聚焦轨道定义,是Grid的入门操作。grid-template-columns配合fr单位定义等分列,gap控制间距,子项自动放置。这是大多数Grid布局的起点,掌握了这一步就能处理基本的等分网格需求。

第二题引入网格线定位,是Grid精确控制的体现。通过指定起止线号,元素可以跨越任意数量的轨道,也可以与其他元素重叠。这种基于线的放置方式给予开发者像素级的位置控制,适合非对称布局和特殊视觉效果。层叠配合z-index可以创造丰富的视觉层次。

第三题切换到区域命名方式,是Grid的另一种放置策略。grid-template-areas让布局结构在CSS中以文本图形的方式呈现,可读性极强。对于结构规整、区域明确的布局,这种方式的维护成本低于手动计算线号。两种放置方式可以混合使用,但通常选择一种作为主导策略。

第四题扩展到与Flexbox的协作,是真实项目中Grid的典型使用方式。Grid不排斥其他布局模型,一个页面可以同时使用Grid做整体框架、Flexbox做局部组件、甚至普通文档流处理简单内容。理解各种布局模型的适用边界,在合适的场景选择合适的工具,是CSS布局能力成熟的标志。


还在纠结 CSS 样式写得杂乱无章、布局频频踩坑?收藏此文持续跟进,后续分享 CSS 高效简写、兼容适配方案、经典布局案例、样式避坑干货,从基础样式到实战排版一站式学透,快速提升前端页面编写能力!

相关推荐
Demon1_Coder1 小时前
Day1-SpringAI-1.0.0版本
java·开发语言·前端
Cheney95011 小时前
Vue 项目字体文件打包后 fonts 文件夹“消失”?原因分析与解决方案
前端·javascript·vue.js
问心无愧05131 小时前
ctf show web入门68,69
android·前端·笔记
jingling5551 小时前
Flutter | 从基本跳转到路由守卫
服务器·前端·网络·flutter·前端框架
神奇的代码在哪里1 小时前
【单机离线版】大学考试题库复习工具:前端离线Excel解析 + localStorage持久化 + Playwright
前端·html·ai编程·题库复习·刷题软件·大学考试
daols881 小时前
vxe-table 实现数据分组统计与表尾合计
前端·javascript·vue.js·vxe-table
向日的葵0061 小时前
Vue 函数定义、事件绑定与列表渲染精讲
前端·javascript·vue.js
神奇的代码在哪里1 小时前
【单机离线版】excel转json软件,纯HTML+JS零依赖实现Excel转JSON工具,一个index.html搞定所有转换!
html·json·excel·excel转json·xlsx转json·xls转json
神秘代码行者1 小时前
pnpm zip命令详解
前端·npm·pnpm