CSS Grid 布局
一、什么是Grid布局?
CSS Grid (网格布局),是一个基于二维网格布局的系统。网格由一组相交的水平线和垂直线组成,它定义了网格的列和行。我们可以将网格元素放置在与这些行和列相关的位置上。
二、浏览器支持情况(统计数据来自:http://caniuse.com/)
三、Grid基本概念
网格容器、网格项
将某一个元素的display属性值设置为grid或者inline-grid,该元素就被声明成为一个网格容器(Grid Container),它的所有子元素都会进入grid文档流,成为网格项(Grid item)
display : grid | inline-grid | subgrid
--grid
:定义一个块级的网格容器
--inline-grid
:定义一个内联的网格容器
--subgrid
:定义一个继承其父级网格容器的行和列的大小的网格容器,它是其父级网格容器的一个子项。
1 <div class="container"> 2 <div class="item">1</div> 3 <div class="item">2</div> 4 <div class="item">3</div> 5 <div class="item">4</div> 6 </div>
1 .container{ 2 display: grid; 3 } 4 .item{ 5 font-size: 20px; 6 7 display: flex; 8 9 box-sizing: border-box; 10 height: 100px; 11 padding: 20px; 12 13 color: #fff; 14 border: 1px solid #333; 15 border-radius: 5px; 16 background: #0091db; 17 18 justify-content: center; 19 align-items: center; 20 }
网格轨道
通过定义网格容器的grid-template-columns和grid-template-rows属性来定义网格中的行和列。这些属性定义了网格的轨道。一个网格轨道就是网格中任意两条线之间的空间。
在轨道清单中使用repeat()
在网格容器中定义重复的网格轨道可以使用 repeat()。例如网格定义:
1 .container{ 2 display: grid; 3 grid-template-columns: 1fr 1fr 1fr; 4 }
也可以写成:
1 .container{ 2 display: grid; 3 grid-template-columns: repeat(3, 1fr); 4 }
repeat() 也可以这么使用(container将会包括10个轨道,1个1fr的轨道后面跟着1个2fr的轨道,重复5次。):
1 .container{ 2 display: grid; 3 grid-template-columns: repeat(5, 1fr 2fr); 4 }
或者(起始轨道为10px,接着用repeat声明了8个1fr的轨道,然后再添加了一个20px的轨道):
1 .container{ 2 display: grid; 3 grid-template-columns: 10px repeat(8, 1fr) 20px; 4 }
网格线
当我们定义网格时,我们定义的是网格轨道,而不是网格线。Grid 会为我们创建带编号的网格线来让我们来定位每一个网格项目。 例如下面这个五列两行的网格中,就拥有6条纵向的网格线。
网格线的编号顺序取决于文章的书写模式。在从左至右书写的语言中,编号为 1 的网格线位于最左边。在从右至左书写的语言中,编号为 1 的网格线位于最右边。 网格线也可以被命名,并且一条网格线可以具有有多个名称,参照:
1 .container{ 2 grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end]; 3 grid-template-rows: [row1-start] 25% [row1-end] 100% [third-line] auto [last-line]; 4 }
隐式和显式网格
当我们显式定位行或列(使用 grid-template-rows/grid-template-columns属性)时,就会产生超出定义范围内的隐式网格轨道。按照默认,这些轨道将自动定义尺寸,所以会根据它里面的内容改变尺寸。
比如:使用grid-column 和 grid-row 来定位网格项
1 <div class="container"> 2 <div class="item a">1</div> 3 <div class="item b">2</div> 4 <div class="item c">3</div> 5 <div class="item d">4</div> 6 </div>
1 .container{ 2 display: grid; 3 grid-template-columns: 50px 50px; 4 grid-template-rows: 100px 100px; 5 grid-row-gap:1px; 6 grid-column-gap:1px; 7 background: #333; 8 } 9 .item{ 10 font-size: 20px; 11 12 display: flex; 13 14 box-sizing: border-box; 15 16 color: #fff; 17 background: #0091db; 18 19 justify-content: center; 20 align-items: center; 21 } 22 .a{ 23 grid-column: 1 / 2; 24 grid-row: 2 / 3; 25 } 26 .b{ 27 grid-column: 5 / 6; 28 grid-row: 2 / 3; 29 }
grid-auto-rows和grid-auto-columns属性就是用来指定隐式网格中自动生成的网格轨道的大小。
1 .container{ 2 grid-auto-columns: 50px; 3 }
轨道大小和minmax()
在设置一个显式的网格或者定义自动创建的行和列的大小的时候,我们也许想给网格一个最小的尺寸,但要确保他们能扩大到容纳他里面添加的内容。举个例子,我想让我的行的高度永远不会缩小到100像素以下,但是如果我的内容延伸到300像素高了我想让我的行高也延伸到这个高度。为了解决这个问题,就需要用到minmax()函数。例如:
1 .container{ 2 grid-auto-columns: minmax(100px, auto); 3 }
在本例中用minmax()作为grid-auto-rows的值。自动创建的行高将会是最小100px,最大为auto。用auto意味着行的尺寸将会根据内容的大小来自动变换。
跨轨道放置网格项目
使用grid-column-start,grid-column-end,grid-row-start,grid-row-end属性,当放置元素时,使用网格线定位,而非网格轨道。
1 .a{ 2 grid-column-start: 1; 3 grid-column-end: 2; 4 grid-row-start: 2; 5 grid-row-end: 3; 6 } 7 .b{ 8 grid-column-start: 5; 9 grid-column-end: 6; 10 grid-row-start: 2; 11 grid-row-end: 3; 12 }
也可以写成:
1 .a{ 2 grid-column: 1 / 2; 3 grid-row: 2 / 3; 4 } 5 .b{ 6 grid-column: 5 / 6; 7 grid-row: 2 / 3; 8 }
网格单元
一个网格单元是在一个网格元素中最小的单位, 从概念上来讲其实它和表格的一个单元格很像。现在再看回我们前面的一个例子, 一旦一个网格元素被定义在一个父级元素当中,那么他的子级项目将会排列在每个事先定义好的网格单元中。
网格区域
网格项目可以向行或着列的方向扩展一个或多个单元,并且会创建一个网格区域。网格区域的形状应该是一个矩形,也就是说你不可能创建出一个类似于“L”形的网格区域。
网格间距
在两个网格单元之间的网格横向间距或网格纵向间距可使用 grid-column-gap 和 grid-row-gap属性来创建,或者直接使用两个合并的缩写形式gard-gap 。
1 .container{ 2 display: grid; 3 grid-row-gap:10px; 4 grid-column-gap:10px; 5 background: #333; 6 }