CSS Grid Layout 从入门到入门
Lidia9919
8年前
<p>CSS 的 Grid Layout 已经开始在浏览器上有资词啦!</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/7e0d9c08fc26d456a19b560ecfcf6411.jpg"></p> <p>可以看到在 FF 的52版本以上已经支持了,Chrome 从57开始支持,如果用 dev 版本或者 canary 版本都可以了,safari 包括10.1和 tp 版都已经支持了。</p> <p>可以愉快的搞起来啦。</p> <p>友情提醒,如果想看到某些代码的效果,请在上文提到的支持 Grid 的浏览器中查看本文,移动端浏览器通通不支持。</p> <h2>基本概念</h2> <p>一个 Grid 其实就是由一系列相交的线组成的结构,其主要的概念如下</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/6cfd539cefb049423de3539c46970e0c.jpg"></p> <ul> <li><em>grid lines</em> 组成 grid 的线,垂直或者水平,并且从1开始计数</li> <li><em>grid tracks</em> 在 grid 中的行和列,其中水平的为行(row),竖直的为列(column)</li> <li><em>grid cells</em> 行和列的交点</li> <li><em>grid area</em> 由一系列相邻的 cells 组成的长方形区域</li> </ul> <h2>创建一个 Grid</h2> <p>首先就是一个新的 display 值,叫做 grid 。</p> <p>将某个元素的 display 设置为 grid 就可以创建一个 grid layout 了。</p> <pre> <code class="language-css"><div class="grid"> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> </div> </code></pre> <p>然后写点 CSS</p> <pre> <code class="language-css">.grid { display: grid; grid-template-columns: 100px 100px 100px 100px; grid-template-rows: 100px 100px; grid-gap: 20px; } .grid div { background-color: grey; } </code></pre> <p>然后就可以看到如下效果啦:</p> <p>See the Pen aJypqZ by Yang Cong ( @nighting ) on CodePen .</p> <p>grid-template-columns 属性,定义了 grid 的各个列的宽度</p> <p>grid-template-rows 属性,定义了grid 的各个行的高度</p> <p>这样就可以画出一整个 grid 了</p> <p>而 grid-gap 属性,定义了各个 grid cells 之间的距离</p> <h2>自适应的 Grid</h2> <p>如你发现,上面的定义只是创建了一个 grid,并没能自适应屏幕。</p> <p>Grid 标准引入了一个新的单位,fr,我们可以使用 fr 单位来做自适应。</p> <p>1fr 是一个『分数单位』,用来表示『元素剩余的空间』 — MDN</p> <pre> <code class="language-css">.grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-rows: 200px 200px; grid-gap: 20px; } .grid div:nth-child(2n) { background-color: darkgrey; } .grid div:nth-child(2n+1) { background-color: grey; } </code></pre> <p>效果如下</p> <p>See the Pen ZeJerK by Yang Cong ( @nighting ) on CodePen .</p> <h2>minmax()</h2> <p>我们可能不单单需要一个简单的长度,也不一定需要某个元素无限扩大或收缩。这时候就可以使用 minmax 函数,这个函数接收两个参数,分别是 min 和 max 的长度,比如</p> <pre> <code class="language-css">grid-template-columns: minmax(300px, 1fr) minmax(200px, 400px) 300px; </code></pre> <p>效果如下</p> <h2>使用 repeat()</h2> <p>你可能也发现了,如果我需要四列,那我需要写4个长度,如果需要100列……天呐,无法想象。机智的劳动人民怎么会允许这种事情的发生,于是随带着 Grid 一起的还有个CSS函数,repeat()</p> <pre> <code class="language-css">repeat(times:Number, length:Length) </code></pre> <p>如下</p> <ul> <li>repeat(4, 1pr) === 1pr 1pr 1pr 1pr</li> <li>repeat(3, 100px) === 100px 100px 100px</li> </ul> <p>因此上面的 CSS 也可以改写成如下:</p> <pre> <code class="language-css">.grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(2, 200px); grid-gap: 20px; } </code></pre> <p>效果还是如上!</p> <h2>auto-fit & auto-fill</h2> <p>有时候我们并不需要确定行数和列数,可能我们希望能根据浏览器的窗口大小来自动的适应。这时候我们就会用到 auto-fill 和 auto-fit 属性。两者的区别我也不是很清楚,貌似 auto-fill 会尽可能多得去增加行数和列数,而 auto-fit 则相反。</p> <p>我们可以看到下面两张图的差别:</p> <p><img src="https://simg.open-open.com/show/53c5f04c9450c0d4943743d1f0510d8c.jpg"></p> <p>以及</p> <p><img src="https://simg.open-open.com/show/7aea1581be9f5eeee580599b3edb59fb.jpg"></p> <p>从表现上看,auto-fit 不会产生空的行或者列。</p> <h2>template areas</h2> <p>Grid 还提供了一种用于排版的方法,也就是 template areas,手动得将想要的layout 设置,而且还是『可视化』的哦</p> <p>具体代码如下</p> <pre> <code class="language-css"><div class="grid"> <header class="box"></header> <aside class="box"></aside> <article class="box"></article> <footer class="box"></footer> </div> </code></pre> <p>这是我们很常见的头部+导航+主要内容+底部的布局</p> <pre> <code class="language-css">header { grid-area: hd; background-color: #ff2e9c; } aside { grid-area: sidebar; background-color: #61dae4; } article { grid-area: at; background-color: #73d545; } footer { grid-area: ft; background-color: #f2ee3e; } .grid { display: grid; grid-gap: 20px; grid-template-rows: 50px 400px 50px; grid-template-areas: "hd hd" "sidebar at" "sidebar ft"; } .box { border-radius: 8px; } </code></pre> <p>最主要的代码就是 grid-template-areas 这个属性啦,里面的值生动得呈现了最终的效果。</p> <h2>定位和占位</h2> <p>有时候我们并不想按照特定的顺序来排列,也有某些部分想要更多的 cell</p> <p>我们可以使用属性 grid-column-start 和 grid-column-end 以及对应的 grid-row-start 和 grid-row-end 来进行定位和占位</p> <p>为了方便,我们可以使用缩写属性 grid-column 和 grid-row</p> <pre> <code class="language-css"><div class="grid"> <div id="a"></div> <div id="b"></div> </div> </code></pre> <pre> <code class="language-css">.grid { display: grid; grid-template-columns: repeat(5, 100px); grid-template-rows: repeat(5, 100px); grid-gap: 20px; } #a { background-color: #ff2e9c; grid-column: 2 / 3; grid-row: 3 / 4; } #b { background-color: #61dae4; grid-column: 3 / 5; grid-row: 2 / span 3; } </code></pre> <p>最终的结果是酱的:</p> <p>See the Pen NpvjMa by Yang Cong ( @nighting ) on CodePen .</p> <p>其中出现了一个 span 的值,表示跨度。</p> <p>还记得开头出现的 <em>gird lines</em> 吗,是从1开始计数的,这里我们定位的值即是 grid lines 的标号。</p> <p>比如 grid-row: 2 / span 3 ,表示该元素纵向从第二根线开始,并且占据3个 cell。</p> <h2>对齐</h2> <h2>align-content 和 justify-content</h2> <p>justify-content 用于定义 grid 在水平方向 如何对齐</p> <p>align-content 用于定义 grid 在垂直方向 如何对齐</p> <p>他们有如下几个值</p> <ul> <li>start</li> <li>center</li> <li>end</li> <li>space-between</li> <li>space-around</li> <li>space-evenly</li> <li>stretch</li> </ul> <p>具体表现如下:</p> <p>DOM结构</p> <pre> <code class="language-css"><div class="grid"> <div></div> <div></div> <div></div> <div></div> </div> </code></pre> <p>CSS</p> <pre> <code class="language-css">.grid { display: grid; grid-template-rows: 100px 100px; grid-template-columns: 150px 150px 150px; height: 500px; width: 650px; border: 1px solid grey; } .grid div:nth-child(1) { grid-column: 1 / 3; grid-row: 1; background-color: #ff2e9c; } .grid div:nth-child(2) { gird-column: 1; grid-row: 2; background-color: #61dae4; } .grid div:nth-child(3) { gird-column: 2; grid-row: 2; background-color: #73d545; } .grid div:nth-child(4) { gird-column: 3; grid-row: 1 / 3; background-color: #f2ee3e; } </code></pre> <ul> <li>align-content: strat; justify-content: start;</li> </ul> <p style="text-align:center"><img src="https://simg.open-open.com/show/66f598a24ea614069f025c418bc64ce9.jpg"></p> <ul> <li>align-content: center; justify-content: center;</li> </ul> <p style="text-align:center"><img src="https://simg.open-open.com/show/7bc0fd0ffd416174f82e83a9edb5b209.jpg"></p> <ul> <li>align-content: end; justify-content: end;</li> </ul> <p style="text-align:center"><img src="https://simg.open-open.com/show/b4392e1f16e7e5318e68b5224b849d5d.jpg"></p> <ul> <li>align-content: center; justify-content: space-evenly;</li> </ul> <p style="text-align:center"><img src="https://simg.open-open.com/show/a9ba3141567fc00cf579bd11cd04e1e2.jpg"></p> <ul> <li>align-content: space-around; justify-content: center;</li> </ul> <p style="text-align:center"><img src="https://simg.open-open.com/show/b4392e1f16e7e5318e68b5224b849d5d.jpg"></p> <ul> <li>align-content: space-between; justify-content: center;</li> </ul> <p style="text-align:center"><img src="https://simg.open-open.com/show/1926ff2a3250ae608eb53b0f80d70a62.jpg"></p> <h2>justify-self 和 align-self</h2> <p>justify-self 用于定义grid 内元素在水平方向的排列</p> <p>align-self 用于定于 grid 内元素在垂直方向的排列</p> <p>有如下几种值</p> <ul> <li>start</li> <li>end</li> <li>center</li> <li>stretch 默认值</li> </ul> <p>使用和效果如下:</p> <p>See the Pen ZeJdvg by Yang Cong ( @nighting ) on CodePen .</p> <p>这俩属性是用在子元素上的,如果想给某个 grid 内的所有元素统一添加,可以使用</p> <ul> <li>align-items</li> <li>justify-items</li> </ul> <p>这两个属性</p> <p>在 webkit 官网的介绍中也有这样一张能够一目了然的图</p> <p><img src="https://simg.open-open.com/show/9f58ce407d44ecf91618bcdc11b6f5a6.jpg"></p> <h2>从入门到入门</h2> <p>有了 Grid 布局,我们可以很方便得完成非常多复杂的布局。</p> <p>譬如之前研究过的双飞翼布局和圣杯布局,通过 Grid 来写的话,是非常方便的。</p> <p>再譬如一些非常复杂的图文混排的布局,grid 也可以非常轻松的实现。</p> <p>不过现在 grid 的支持度还很低,从目前还有无数公司兼容 IE6的生态来讲,想在生产环境用上 grid 仿(jiu)佛(shi)是个遥不可及的事情……</p> <p>不过这也抵不住前端汪折腾的心啊。</p> <p> </p> <p>来自:http://nighting.me/2017/03/14/CSS-Grid-Layout-从入门到入门/</p> <p> </p>