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>