网格布局
理解网格布局的基本元素
网格布局是一个由行和列组成的二维布局方式,元素放置在网格的一个单元格中或占据多行多列(网格区域)。
- grid-template-column与grid-template-row:指定网格中每列每行的大小。这里可以使用一种新单位fr,代表每一列(行)的分数单位,可以理解为“1fr表示占据一份”;也可以使用px,em或百分数。
- grid-gap:定义每个网格单元之间的间距,使用两个数值可以分别指定垂直与水平方向的间距。
- grid-column与grid-row:用网格线的编号指定网格元素的位置,"/"是"grid- * -start和grid- * -end的简写形式。
- grid-auto-flow:决定元素的放置顺序。默认值为row,按“先行后列”的顺序放置,也即先排满一行再换下一行。
代码实现:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .container{ display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 1fr 1fr 1fr 1fr; grid-gap: 1em; background-color: white; } div{ background-color: darkgray; color: white; padding: 2em; border-radius: 0.5em; text-align: center; } .b{ grid-column: span 2; /*表示水平网格轨道上跨越两个单元格*/ grid-row: span 2; } .c{ grid-row: 2/5; /*表示垂直网格轨道上,元素占据2号网格线到5号网格线之间的位置,也即跨越3个单元格*/ } .f{ grid-column: 2/4; } </style> </head> <body> <div class="container"> <div class="a">a</div> <div class="b">b</div> <div class="c">c</div> <div class="d">d</div> <div class="e">e</div> <div class="f">f</div> </div> </body> </html>
效果如下:
隐式网格
前面使用grid-template- * 属性定义网格轨道时,创建的是显式网格。但在某些场景下,我们可能不知道从数据库中获取的元素数量,或者说当处理大量网格元素时挨个指定元素的位置太过繁琐,我们可以使用隐式网格。隐式网格以一种宽松的方式定义网格,网格元素的布局交给布局算法来操作。
- grid-auto-column:用于指定隐式创建的列轨道大小。
- grid-auto-row:用于指定隐式创建的行轨道大小。
代码实现:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> body{ background-color: #709b90; font-family: Helvetica,Arial,sans-serif; } .portfolio{ display: grid; /* auto--fill:在可用空间内尽可能生成多的网格列*/ /* minmax()指定每列宽度的最小值和最大值,最大值为1fr可以使每列等宽*/ grid-template-columns: repeat(auto-fill,minmax(200px,1fr)); grid-auto-rows: 1fr; grid-gap: 1em; } .portfolio>figure{ margin: 0; } .portfolio img{ max-width: 100%; } .portfolio figcaption{ padding: 0.3em 0.8em; background-color: rgba(0,0,0,0.5); color: white; text-align: right; } .portfolio .featured{ grid-row: span 2; grid-column: span 2; } </style> </head> <body> <div class="portfolio"> <figure class="featured"> <img src="images/monkey.jpg" alt="monkey"/> <figcaption>Monkey</figcaption> </figure> <figure> <img src="images/eagle.jpg" alt="eagle"/> <figcaption>Eagle</figcaption> </figure> <figure class="featured"> <img src="images/bird.jpg" alt="bird"/> <figcaption>Bird</figcaption> </figure> <figure> <img src="images/bear.jpg" alt="bear"/> <figcaption>Bear</figcaption> </figure> <figure class="featured"> <img src="images/swan.jpg" alt="swan"/> <figcaption>Swan</figcaption> </figure> <figure> <img src="images/elephants.jpg" alt="elephants"/> <figcaption>Elephants</figcaption> </figure> <figure> <img src="images/owl.jpg" alt="owl"/> <figcaption>Owl</figcaption> </figure> </div> </body> </html>
说明:<figure>创建一个可附标题内容元素,代表一段独立的内容,通常与<figcaption>(与其相关联的图片的标题或说明)配合使用。
代码使用隐式网格创建一个照片墙,代码中网格行是隐式创建的,这样网页不必关心照片的数量以及视口的大小,当需要换行时就会隐式创建新的一行。但当图片大小不一致时,由于图片是按HTML文档中的顺序排列的,某些图片较大时会导致某一行的空间无法容纳它而使他移动到下一行,导致前面一行有空白区域。如下图所示:
解决方法是使用grid-auto--flow属性的另一个属性值来控制布局算法的行为:grid-auto-flow:dense。该值表示让算法紧凑地填满网格里的空白,能让小元素“回填”大元素在此的空白区域,尽管这样会改变网格元素在HTML文档中的顺序。
.portfolio{ display: grid; grid-template-columns: repeat(auto-fill,minmax(200px,1fr)); grid-auto-rows: 1fr; grid-gap: 1em; grid-auto-flow: dense; }
如下图所示,图片已经改变顺序形成紧凑排布,但可以发现仍存在一些缺陷需要完善(图中虚线为网格线)。虽然默认情况下,网格元素<figure>会扩展并填满整个网格区域,但网格元素的子元素(如<img>和<figcaption>)并不会,因此会造成图中的空白区域。
可以利用前面学过的弹性盒布局,将整个<figure>元素定义为弹性容器,同时声明主轴方向为垂直方向,让元素从上到下排布。另外,给<img>设置flew-grow属性进行拉伸来填充空白区域(拉伸<figcaption>并不美观)。但我们拉伸图片会改变图片高度,造成原来的宽高比改变导致图片变形,因此这里使用object-fit:cover对图片边缘进行裁剪,再进行宽高等比例拉伸使其填充整个网格单元。
.portfolio>figure{ display: flex; flex-direction: column; margin: 0; } .portfolio img{ flex: 1; object-fit: cover; max-width: 100%; }

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)