找回密码
 立即注册
首页 业界区 业界 Web前端入门第 37 问:多图细说 CSS grid 网格布局(二 ...

Web前端入门第 37 问:多图细说 CSS grid 网格布局(二)子元素相关属性

公西颖初 2025-6-2 21:31:06
学习本文之前,建议先学习上一篇了解父元素的相关属性。
前文对 grid 网格布局中父元素容器相关的 CSS 属性做了详细介绍,本篇将继续学习子元素相关的 CSS 属性。
网格布局的一大波样式属性,父元素占据了大半江山,子元素嘛相对就少了一些~~
本文中的中的示例基础代码:
  1.   A
  2.   B
  3.   C
  4.   D
复制代码
子元素相关的 CSS 属性

grid-column-start 控制子元素列从哪根线开始。
grid-column-end 控制子元素列在哪条网格线结束。
grid-column  简写属性 grid-column-start 、 grid-column-end。
grid-row-start  控制子元素行从哪根线开始。
grid-row-end  控制子元素行在哪条网格线结束。
grid-row  简写属性 grid-row-start 、 grid-row-end。
grid-area  指定子元素属于哪个命名区域或简写位置。
justify-self  覆盖容器的 justify-items,控制单个子元素的行对齐。
align-self  覆盖容器的 align-items,控制单个子元素的列对齐。
order  调整子元素的显示顺序(类似 Flexbox)。
z-index  控制子元素的层叠顺序。
设置子元素列的开始位置和结束位置

grid-column-start 用于设置子元素列的开始位置,从哪条网格线开始
grid-column-end 用于设置子元素列的结束位置,在哪条网格线结束
以 grid-column-start 为例:
  1. grid-column-start: auto; /* 默认值,自动分配 */
  2. grid-column-start: 4; /* 从第 4 根线开始 */
  3. grid-column-start: span 2; /* 定义跨两列 */
  4. grid-column-start: some-grid-area; /* 从命名区域 some-grid-area 开始 */
  5. grid-column-start: span some-grid-area; /* 未知的渲染方式 */
  6. grid-column-start: span some-grid-area 3; /* 未知的渲染方式 */
复制代码
使用数字和关键字 span 示例:
  1. .box {
  2.   /* 设置网格五行五列 */
  3.   grid-template-columns: repeat(5, 1fr);
  4.   grid-template-rows: repeat(5, 1fr);
  5. }
  6. .box .item:nth-child(1) {
  7.   /* 第一个子元素从第 4 根线开始 */
  8.   grid-column-start: B;
  9. }
  10. .box .item:nth-child(2) {
  11.   /* 第二个子元素跨两列 */
  12.   grid-column-start: span 2;
  13. }
复制代码
注意看右侧网格线,由于第二个子元素要占用两列,网格放不下了,所以从第二行开始。显示效果:
1.png

使用命名区域设置子元素开始位置:
  1. .box {
  2.   grid-template-areas:
  3.     "A1 A1 F2 G3 G3"
  4.     "A1 A1 F2 B4 B4"
  5.     "C5 C5 C5 C5 C5"
  6.     "D6 D6 D6 D6 D6"
  7.     "E7 E7 E7 E7 E7";
  8. }
  9. .box .item:nth-child(1) {
  10.   grid-column-start: F2; /* 从 F2 开始 */
  11. }
  12. .box .item:nth-child(2) {
  13.   grid-column-start: span G3; /* 无效 */
  14. }
  15. .box .item:nth-child(3) {
  16.   grid-column-start: span D6 4; /* 无效 */
  17. }
复制代码
重点:不知道是我姿势不对,还是 MDN 文档有问题, grid-column-start: span G3; 和 grid-column-start: span D6 4; 两种写法浏览器解析了,没报无效值,但是实际没啥效果~~头大....
2.png

不过 MDN 上找到这么一个例子:
  1. .box {
  2.   grid-template-columns: repeat(6, [col1-start] 1fr [col2-start] 3fr);
  3. }
  4. .item:nth-child(1) {
  5.   grid-column: col1-start / col2-start 2;
  6. }
  7. .item:nth-child(2) {
  8.   grid-row: 2;
  9.   grid-column: col1-start 2 / span 2 col1-start;
  10. }
复制代码
实际使用是正常可以显示的,那么 grid-column-start: span D6 4; 这种写法应该是用于重复的命名行线,而不是命名区域。
同时设置列起始和结束位置:
grid-column-end 与 grid-column-start 写法一样。
使用数字比较好理解:
  1. .box {
  2.   /* 设置网格五行五列 */
  3.   grid-template-columns: repeat(5, 1fr);
  4.   grid-template-rows: repeat(5, 1fr);
  5. }
  6. .box .item:nth-child(1) {
  7.   /* 从第 2 根线开始,结束在第 4 根线结束 */
  8.   grid-column-start: 2;
  9.   grid-column-end: 4;
  10. }
  11. .box .item:nth-child(2) {
  12.   /* 从第 2 根线开始,横跨四列 */
  13.   grid-column-start: 2;
  14.   grid-column-end: span 4;
  15. }
复制代码
显示效果:
3.png

使用命名区域设置时候又出幺蛾子了,感觉命名区域设置就不能带上 span 关键字~~
  1. .box {
  2.   grid-template-areas:
  3.     "A1 A1 F2 G3 G4"
  4.     "A1 A1 F2 B4 B4"
  5.     "C5 C5 C5 C5 C5"
  6.     "D6 D6 D6 D6 D6"
  7.     "E7 E7 E7 E7 E7";
  8. }
  9. .box .item:nth-child(1) {
  10.   /*  从 F2 开始,在 G3 结束 */
  11.   grid-column-start: F2;
  12.   grid-column-end: G3;
  13. }
  14. .box .item:nth-child(2) {
  15.   /* 嘿~不好意思,无效,span 只能跟数字,其他值都无效,还会导致网格多一列 */
  16.   grid-column-start: F2;
  17.   grid-column-end: span G3;
  18. }
  19. .box .item:nth-child(3) {
  20.   /* 也不是说此方法无效,它在表格后面多绘制了 10 列,无语了.... */
  21.   grid-column-start: F2;
  22.   grid-column-end: span G3 10;
  23. }
复制代码
看效果:
4.png

grid-column-end: span G3 10; 这种写法你说他无效吧,它在网格后面多绘制了 10 列,你说有效吧,又没办法理解浏览器的绘制方式。
按照 MDN 的说法,还支持 grid-column-end: 10 G3 span; 这种写法,实际效果与上面一样,还是给网格多绘制了 10 列。
但如果使用 grid-template-columns: repeat(5, 1fr); 控制了网格列数,那么就不会多绘制那么多列了,但也无法理解他的绘制方式。
可能跟上面一样,用于重复的命名行线,而不是命名区域。
设置子元素行的开始位置和结束位置

grid-row-start 用于设置子元素行的开始位置,从哪条网格线开始
grid-row-end 用于设置子元素行的结束位置,在哪条网格线结束
设置行的两个属性与设置列的属性一样,使用 命名区域 有 span 关键字时设置行起始和结束位置还是会出幺蛾子,就不再一一演示。
看能理解的示例:
  1. .box {
  2.   grid-template-areas:
  3.     "A1 A1 F2 G3 G4"
  4.     "A1 A1 F2 B4 B4"
  5.     "C5 C5 C5 C5 C5"
  6.     "D6 D6 D6 D6 D6"
  7.     "E7 E7 E7 E7 E7";
  8. }
  9. .box .item:nth-child(1) {
  10.   grid-column-start: 1;
  11.   grid-column-end: 3;
  12.   grid-row-start: 1;
  13.   grid-row-end: 3;
  14. }
  15. .box .item:nth-child(2) {
  16.   grid-column-start: 2;
  17.   grid-column-end: span 2;
  18.   grid-row-start: 2;
  19.   grid-row-end: span 2;
  20. }
  21. .box .item:nth-child(3) {
  22.   grid-column-start: F2;
  23.   grid-column-end: G3;
  24.   grid-row-start: G3;
  25.   grid-row-end: B4;
  26. }
复制代码
显示效果:
5.png

行列的简写属性

使用 grid-column 和 grid-row 可简写列和行的开始结束位置。毕竟一次写四个属性太麻烦了,只写两个就省了一半。
  1. .box {
  2.   grid-template-areas:
  3.     "A1 A1 F2 G3 G4"
  4.     "A1 A1 F2 B4 B4"
  5.     "C5 C5 C5 C5 C5"
  6.     "D6 D6 D6 D6 D6"
  7.     "E7 E7 E7 E7 E7";
  8. }
  9. .box .item:nth-child(1) {
  10.   grid-column: 1 / 3;
  11.   grid-row: 1 / 3;
  12. }
  13. .box .item:nth-child(2) {
  14.     grid-column: 2 / span 2;
  15.     grid-row: 3 / span 2;
  16. }
  17. .box .item:nth-child(3) {
  18.   grid-column: span 3 / 2; /* 表示此单元格跨 3 列,在第二根网格线结束 */
  19.   grid-row: 3 / span 2; /* 表示此单元格行从第三根网格线开始,跨 2 行 */
  20. }
  21. .box .item:nth-child(4) {
  22.   grid-column: F2 / G3;
  23.   grid-row: G3 / B4;
  24. }
复制代码
显示效果:
6.png

设置位置时,可使用负数,表示倒数,比如:grid-column: -1 / span 2; 表示从倒数第一根网格线开始,跨 2 列。
使用命名行线

虽然个人觉得这种用法有点难理解,但浏览器是支持这种写法的,可以不用,但不能不会,对不~
  1. .box {
  2.   grid-template:
  3.     [header-left] "head head" 30px [header-right]
  4.     [main-left] "nav  main" 1fr [main-right]
  5.     [footer-left] "nav  foot" 30px [footer-right]
  6.     / 120px 1fr;
  7. }
  8. .box .item:nth-child(1) {
  9.   grid-row: header-left / footer-left;
  10. }
复制代码
显示效果:

使用 grid-area 插旗

前文介绍过 grid-template-areas 用于划分地盘,子元素就使用 grid-area 来插旗,指定子元素在哪块地盘。
看看经典的管理系统结构:
  1. .box {
  2.   grid-template-areas:
  3.     "header header header"
  4.     "left main right"
  5.     "footer footer footer";
  6.   grid-template-columns: 10% 1fr 10%;
  7.   grid-template-rows: 30px 1fr 40px;
  8. }
  9. .box .item:nth-child(1) {
  10.   grid-area: header;
  11. }
  12. .box .item:nth-child(2) {
  13.   grid-area: left;
  14. }
  15. .box .item:nth-child(3) {
  16.   grid-area: main;
  17. }
  18. .box .item:nth-child(4) {
  19.   grid-area: right;
  20. }
  21. .box .item:nth-child(5) {
  22.   grid-area: footer;
  23. }
复制代码
显示效果:
8.png

覆盖父元素的对齐方式

justify-self 和 align-self 可用于覆盖父元素设置的对齐方式(justify-items / align-items)。某个子元素想要特立独行的时候,就可以派上用场了。
  1. .box {
  2.   grid-template-columns: repeat(4, 1fr);
  3.   grid-template-rows: repeat(4, 1fr);
  4.   align-items: center;
  5.   justify-items: center;
  6. }
  7. .box .item {
  8.   width: 40px;
  9.   height: 40px;
  10. }
  11. .box .item:nth-child(2) {
  12.   align-self: flex-start;
  13. }
  14. .box .item:nth-child(3) {
  15.   justify-self: flex-end;
  16. }
复制代码
显示效果:
9.png

调整子元素顺序

接上例中的代码,直接添加 order 属性可调整子元素顺序。
排序规则:越小值则越靠前,默认值为 0。
  1. .box .item:nth-child(1) {
  2.   order: 3; /* 第一个子元素排第三位 */
  3. }
  4. .box .item:nth-child(2) {
  5.   order: 2; /* 第二个子元素排第二位 */
  6. }
  7. .box .item:nth-child(3) {
  8.   order: 1; /* 第三个子元素排第一位 */
  9. }
  10. .box .item:nth-child(4) {
  11.   order: 4; /* 第四个子元素排第四位 */
  12. }
  13. .box .item:nth-child(5) {
  14.   order: 5; /* 第五个子元素排第五位 */
  15. }
复制代码
显示效果:
10.png

控制子元素的层叠顺序

当网格布局中两个子元素叠在一起显示时候,这会可拿出 z-index 属性控制子元素层叠顺序,想谁在上面谁就在上面。
规则:谁的 z-index 值大谁就在上面。
  1. .box .item:nth-child(1) {
  2.   grid-column: 1 / span 2;
  3.   grid-row: 1 / span 2;
  4.   background-color: red;
  5. }
  6. .box .item:nth-child(2) {
  7.   grid-column: 2 / span 2;
  8.   grid-row: 1 / span 2;
  9.   background-color: yellow;
  10. }
  11. /* 控制第二个 box 中的第一个子元素在上面 */
  12. .box:nth-child(2) .item:nth-child(1) {
  13.   z-index: 2;
  14. }
复制代码
以上代码由于 grid-row 值相同,所以两个子元素会叠在一起,然后使用 z-index 控制了第二个盒子的第一个子元素。
显示效果:
11.png

总结

网格布局这一壶终于喝完了,它包含的内容太多太广了,要熟练使用还需要多加练习才行,后续文章还会更新弹性盒子与网格布局的对比,以及它俩的应用场景,敬请期待。
2023 版本的 CSS 规范还提出了子网格 Subgrid 概念,如需了解更多请参阅后文中的参考资料链接。
参考资料:
https://developer.mozilla.org/en-US/docs/Web/CSS/grid
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Subgrid

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册