网格布局(栅格系统)
官方解释:CSS 网格布局擅长于将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系(前提是HTML生成了这些区域)。 像表格一样,网格布局让我们能够按行或列来对齐元素。 然而在布局上,网格比表格更可能做到或更简单。 例如,网格容器的子元素可以自己定位,以便它们像CSS定位的元素一样,真正的有重叠和层次。个人理解: 要说这个栅格系统玩过地图编辑器的同学就很好理解,因为栅格概念在地图编辑上早就普遍应用了。没玩过地图编辑器,总玩过游戏吧(帝国、魔兽、模拟人生、植物大战僵尸、皇帝、海岛奇兵。。。)但凡带点策略性质,需要建造或放置单位的对栅格概念都不会陌生。都没玩过也没关系,页面就相当于客厅的空白平面图,栅格就相当于地板砖。以后摆家具就参考地砖划定的边界来摆放。(茶几放在哪几块地砖上,沙发放在哪几块地砖上。)将容器设置为网格模式(默认块级)
display: grid;将容器设置为行内网格模式 (多个网格容器可以在一行)
display: inline-grid;开启网格模式后当前元素就变成了一个网格容器,它的所有直系子元素将成为网格元素。
所有代码可以在线调试:https://codepen.io/jerryjin/pen/xxVvYgV
<article id="hrd"> <div>曹操</div> <div>关羽</div> <div>张飞</div> <div>赵云</div> <div>马超</div> <div>黄忠</div> <div>卒</div> <div>卒</div> <div>卒</div> <div>卒</div> </article> <article id="a1"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> <div>7</div> <div>8</div> <div>9</div> </article> * { padding: 0; margin: 0; } /* article 基础样式 */ article { width: 150px; height: 150px; border: solid 5px silver; margin: 10px; /* 宽、高、边框、外边距 */ display: inline-grid; /* 开始网格模式 */ overflow:hidden; } article:nth-of-type(n+7){ height: auto; /* 覆写高度,允许撑开 */ overflow: visible; /* 覆写超出为显示 */ } /* 所有 div 基础样式 */ div { background: lightgreen; /* 背景色 */ background-clip: content-box; /* 背景色应用到内容区域。还可选:border-box, padding-box */ padding: 5px; /* 内边距 */ border: solid 1px #ddd; /* 边框 */ text-align: center; line-height: 35px; /* 文字水平垂直居中 */ } /* ---------------------------------------------------------------------------- */ #hrd { width: 400px; height: 500px; grid-template: repeat(5, 1fr) / repeat(4, 1fr); grid-template-areas: "赵云 曹操 曹操 黄忠" "赵云 曹操 曹操 黄忠" "张飞 关羽 关羽 马超" "张飞 卒1 卒2 马超" "卒3 . . 卒4" } #hrd>div:nth-of-type(1){ grid-area: 曹操; line-height: 200px;} #hrd>div:nth-of-type(2){ grid-area: 关羽; line-height: 100px;} #hrd>div:nth-of-type(3){ grid-area: 张飞; line-height: 200px;} #hrd>div:nth-of-type(4){ grid-area: 赵云; line-height: 200px;} #hrd>div:nth-of-type(5){ grid-area: 马超; line-height: 200px;} #hrd>div:nth-of-type(6){ grid-area: 黄忠; line-height: 200px;} #hrd>div:nth-of-type(7){ grid-area: 卒1; line-height: 100px;} #hrd>div:nth-of-type(8){ grid-area: 卒2; line-height: 100px;} #hrd>div:nth-of-type(9){ grid-area: 卒3; line-height: 100px;} #hrd>div:nth-of-type(10){ grid-area: 卒4; line-height: 100px;} /* ---------------------------------------------------------------------------- */ #a1 { grid-template-rows: 50px 50px 50px; grid-template-columns: 50px 50px 50px; } #a2 { grid-template-rows: 33% 34% 33%; grid-template-columns: 33% 34% 33%; } #a3 { grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr; } #a4 { grid-template-rows: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr); } #a5 { grid-template: 1fr 1fr 1fr/ 1fr 1fr 1fr; } #a6 { grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr; grid-gap: 5px; /* 同时设置行列边距 */ } #a7 { grid-template-rows: 1fr; /* 定义1行 */ grid-template-columns: 1fr 1fr; /* 定义2行 */ grid-auto-rows: 80px; /* 设置隐式行轨道 */ grid-auto-columns: 80px; /* 设置隐式列轨道 */ } #a7>div:nth-of-type(7){ background: red; /* 背景色红 */ background-clip: content-box; /* 背景色应用于内容区域 */ grid-row: 1 / 3; /* 定位行到网格线 开始1 => 结束3 */ grid-column: 3 / 4; /* 定位列到网格线 开始3 => 结束4 */ } #a8 { grid-template-rows: [r1s] 1fr [r1e r2s] 1fr [r2e r3s] 1fr [r3e]; /* 显示定义名称 */ grid-template-columns: repeat(3, [cs] 1fr [ce]); /* 自动定义名称 */ } #a8>div:nth-of-type(5){ background: red; /* 背景色红 */ background-clip: content-box; /* 背景色应用于内容区域 */ grid-area: r3s / cs 3 / r3s / ce 3; /* 通过名称定位 */ } #a8>div:nth-of-type(6){ background: red; /* 背景色红 */ background-clip: content-box; /* 背景色应用于内容区域 */ grid-area: 4 / cs 3 / 5 ; } #a8>div:nth-of-type(7){ background: red; /* 背景色红 */ background-clip: content-box; /* 背景色应用于内容区域 */ grid-area: 5 / cs 3 ; } #a8>div:nth-of-type(8){ background: red; /* 背景色红 */ background-clip: content-box; /* 背景色应用于内容区域 */ grid-area: 6; } #a9 { grid-template: repeat(4, 1fr) / repeat(3, 1fr); } #a9>div:nth-of-type(1){ background: red; /* 背景色红 */ background-clip: content-box; /* 背景色应用于内容区域 */ grid-area: span 3 / span 3; } #a10 { width: 150px; height: 150px; grid-template: repeat(auto-fill, minmax(20px, 1fr) ) / repeat(auto-fill, minmax(20px, 1fr)); } #a10>div{ padding: 0; /* 内边距 */ line-height: 20px; } #a10>div:nth-of-type(1){ grid-area: 1 / 1 / 2 / 7; } #a10>div:nth-of-type(2){ grid-area: 1 / 7 / 7 / 8; } #a10>div:nth-of-type(3){ grid-area: 7 / 2 / 7 / 8; } #a10>div:nth-of-type(4){ grid-area: 2 / 1 / 8 / 2; } #a10>div:nth-of-type(5){ grid-area: 2 / 2 / 3 / 6; } #a10>div:nth-of-type(6){ grid-area: 2 / 6 / 6 / 7; } #a10>div:nth-of-type(7){ grid-area: 6 / 3 / 7 / 7; } #a10>div:nth-of-type(8){ grid-area: 3 / 2 / 7 / 3; } #a10>div:nth-of-type(9){ grid-area: 3 / 3 / 5 / 5; } #a11 { width: 500px; height: 150px; grid-template: repeat(auto-fit, minmax(20px, 1fr) ) / repeat(auto-fit, minmax(20px, 1fr)); } #a12 { grid-template: repeat(3, 1fr) / repeat(1, 1fr) ; grid-auto-flow: column; } #a13{ grid-template: repeat(1, 1fr) / repeat(3, 1fr) ; grid-auto-flow: row; } #a14{ width: 400px; height: 100px; grid-template: repeat(1, 30px) / repeat(9, 30px) ; place-content: space-evenly space-evenly; } #a14>div{width:20px; height: 20px; line-height: 20px;} #a15{ width: 400px; height: 400px; grid-template: repeat(3, 1fr) / repeat(3, 1fr); place-items: center center; } #a15>div{width:40px; height: 40px;} #a15>div:nth-of-type(5){ place-self: end end; } let ele = document.querySelector("#a1"); // 选择 article // 克隆 article 凑齐 15 个 for(let i = 2; i <= 15; i++){ let temp = ele.cloneNode(true); temp.id = "a" + i; ele.parentNode.appendChild(temp); }给所有容器设置默认行列轨道大小 grid-template-rows、grid-template-columns 取值规则:
值例子像素 pxgrid-template-rows: 50px 50px 50px;百分比 %grid-template-rows: 33% 34% 33%;n等分 nfrgrid-template-rows: 1fr 1fr 1fr;重复 repeatgrid-template-rows: repeat(2, 50%); // 等同于上一行效果minmax(min, max)minmax(10px, 2fr) // 最小时10px,最大时2fr前四个,分别使用四种单位设置。其他默认行列轨道大小
同时设置:grid-template-rows、grid-template-columns 实现和前面相同的行列轨道效果。
#a5 { grid-template: 1fr 1fr 1fr/ 1fr 1fr 1fr; }设置行、列边距
自定义网格线名称和使用:
显示定义名称:在轨道的左右用[]写上网格线名称即可自动定义名称:repeat(3, [开始标识] 1fr [结束标识])。使用: 开始标识 + 空格 + 行或列号注意: 这里行的单位使用了像素50px。经过测试如果使用1fr,span 跨越行数必须小于 定义行数。否则跨度失效,只会占用一行。 将定义行数设置到合理。比如:(显示设置 4 行)可以解决。
#a9 { grid-template: repeat(4, 1fr) / repeat(3, 1fr); } #a9>div:nth-of-type(1){ background: red; /* 背景色红 */ background-clip: content-box; /* 背景色应用于内容区域 */ grid-area: span 3 / span 3; }网格项大小固定,系统在容器中自动判断应该分配多少行/列。 auto-fit:网格项不足以填满一行时。各项平分剩余空间 auto-fill:网格项不足以填满一行时。保留剩余空间
虽然可以直接写固定值,但范围值 minmax(20px, 1fr) 更适用。
符号点.用于跳过单元格
对齐属相相对独立并不是网格系统的专属,所以分开演示
序号属性对象简写说明1align-content容器控制如何沿着弹性盒子布局的纵轴和网格布局的主轴在内容项之间和周围分配空间2justify-content容器控制如何分配顺着弹性容器主轴(或网格行轴) 的元素之间及其周围的空间。3place-content容器是语法 <'align-content'> <'justify-content'>?4align-items容器控制元素在垂直方向的对齐方式。(开头、末尾、拉伸)5justify-items容器控制元素在水平方向的对齐方式。(开头、末尾、拉伸)6place-items容器是语法 <'align-items'> <'justify-items'>?7align-self元素控制当前元素在垂直方向的对齐方式。(开头、末尾、拉伸)8justify-self元素控制当前元素在水平方向的对齐方式。(开头、末尾、拉伸)9place-self元素是语法 <'align-self'> <'justify-self'>?</font———————————注意:对齐效果,要在有多余空间,时才看的出效果。不然元素填满了网格,怎么排看上去效果都一样。
MDN 网格布局 后盾人:栅格系统 阮一峰的网络日志》CSS Grid 网格布局教程