CSS3中Grid的整理

566 阅读6分钟

之前整理了Flexbox,就顺便整理一下grid。

介绍

网格布局是 CSS 中最强大的布局系统。 这是一个二维系统,这意味着它可以处理列和行,不同于flexbox,其中大部分是一维系统。 通过将 CSS 规则应用于父元素(成为 Grid Container)和该元素的子元素(成为 Grid Items) ,您可以使用 Grid Layout。

兼容性

背景

   CSS总是被用来布置我们的网页,但它从来没有做好它的工作。 首先,我们使用table,然后float,positioning和inline-block,但所有这些方法本质上都是 应对,省略了许多重要的功能(例如,垂直居中)。 Flexbox 提供了帮助,但它的目的是更简单的一维布局,而不是复杂的二维布局。 网格是第一个专门为解决布局问题而创建的 CSS 模块,只要我们一直在做网站,我们就一直在努力解决布局问题。

Grid Container:网格容器,应用 display: grid 的元素。 它是所有网格项的直接父类。
Grid Item: 网格项目,网格容器的子容器(即直接子容器)。
Grid Line: 网格线,构成网格结构的分界线。 它们既可以是垂直的(“列网格线”) ,也可以是水平的(“行网格线”) ,并且位于行或列的两侧。
Grid Track: 两个相邻网格线之间的距离。 可以将它们看作是网格的列或行。
Grid Cell: 两个相邻行和两个相邻列网格线之间的空间。 这是一个单一的“单位”的网格。
Grid Area: 四条网格线包围的总空间。 一个网格区域可以由任意数量的网格单元组成。

父类属性(Grid Container)

1. display

将元素定义为网格容器,并为其内容建立新的网格格式上下文。

.container {
  display: grid | inline-grid;
}

2. grid-template-columns  /  grid-template-rows

使用空格分隔的值列表定义网格的列和行。 这些值表示距离大小,它们之间的空间表示网格线。

.container {
  grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
  grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}

line-name 比较随便,也可以空白

track-size 可以是长度,百分数, auto 或者fr单位

2.1 fr

fr是css3中引入了一个新的单位(fraction),中文意思为“分数”,用于替代百分比,因为百分比(小数)存在除不尽的情况,用分数表示可以避免多位小数的写法。例如三列等宽可以写成

css:
grid-template-columns: 1fr 1fr 1fr;

2.2 repeat

repeat方法来简化column或者row的写法,repeat方法接受两个参数,第一个参数表示重复的次数,第二个参数表示重复的内容。所以,三列等宽的grid我们还可以表示为:
css: grid-template-columns: repeat(3, 1fr);

效果:

2.3 minmax

给row设置完一个固定,如果grid-item里面的内容比较多,可能部分内容就无法显示出来了。为解决这个问题,css提供了minmax函数,让我们可以设置row的最小高度和最大高度,最大高度取auto后便可以让row的高度自适应,如下:

css:

grid-template-rows: repeat(3, minmax(60px, auto));

效果

2.4 grid-gap

grid-gap是在行跟列之间增加间隔。

css:

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 40px);
  grid-gap: 5px;
}

效果

也可以分开来设置

.container {
  grid-column-gap: <line-size>;
  grid-row-gap: <line-size>;
}

3. grid-template-areas

通过引用用 grid-area 属性指定的网格区域的名称定义网格模板。 重复网格区域的名称会导致内容跨越这些单元格。 "."表示空单元格。

.grid-container {
  grid-template-areas: 
    "<grid-area-name> | . | none | ..."
}

grid-area-name - 指定的网格区域的名称grid-area
. - 句点表示空的网格单元格
none - 没有定义网格区域

例子:

.section-a{
  grid-area: header;
}
.section-b {
  grid-area: main;
}
.section-c {
  grid-area: sidebar;
}
.section-d {
  grid-area: footer;
}

.grid-container {
  text-ailgn: center;
  display: grid;
  grid-template-columns: repeat(4, 50px);
  grid-gap:2px;
  grid-template-rows: auto;
  grid-template-areas: 
    "header header header header"
    "main main . sidebar"
    "footer footer footer footer";
}

效果:

4. justify-items, align-items, place-item

前两个同flex,对item内容统一水平或垂直布局。

.grid-container {
  justify-items: start | end | center | stretch;
}
.grid-container {
  align-items: start | end | center | stretch;
}

place-item是 align-items / justify-items,如果只会有一个值,那就是两个值一样处理。 除了 Edge 之外,所有主流浏览器都支持 place-items 简写属性。

5. justify-content, align-content, place-content

前两个是对容器整体进行水平,垂直布局。

.grid-container {
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;	
}
.grid-container {
  align-content: start | end | center | stretch | space-around | space-between | space-evenly;	
}

plance-content是 align-content / justify-content,如果只会有一个值,那就是两个值一样处理。 除了 Edge 之外,所有主流浏览器都支持 place-content 简写属性。

6. grid-auto-flow

如果没有显式放置在网格上的网格项,那么自动放置算法将自动放置这些项。

.grid-container {
  grid-auto-flow: row | column | row dense | column dense;
}

例子: 定义一个五行两列的网格
HTML如下

<section class="grid-container">
  <div class="item-a">A</div>
  <div class="item-b">B</div>
  <div class="item-c">C</div>
  <div class="item-d">D</div>
  <div class="item-e">E</div>
</section>

CSS:

.grid-container {
  display: grid;
  grid-template-columns: repeat(5, 60px);
  grid-template-rows: repeat(2, 60px);
  grid-auto-flow: row;
}

.item-a {
  grid-column: 1;
  grid-row: 1 / 3;
}
.item-e {
  grid-column: 5;
  grid-row: 1 / 3;
}

效果:

grid-auto-flow改成column,
CSS:

.grid-container {
  display: grid;
  grid-template-columns: repeat(5, 60px);
  grid-template-rows: repeat(2, 60px);
  grid-auto-flow: column;
}

.item-a {
  grid-column: 1;
  grid-row: 1 / 3;
}
.item-e {
  grid-column: 5;
  grid-row: 1 / 3;
}

效果:

子类属性(Grid Items)

1. Grid line

Grid line就是将屏幕等分, 通过定义grid-item的始末实现对实际面积的控制。

.grid-container {
  display: grid;
  grid-template-columns: repeat(8, 50px);
  grid-template-rows: repeat(8, 50px);
  grid-gap: 5px;
}
.grid-item {
  grid-column-start: 3;
  grid-column-end: 6;
  grid-row-start: 3;
  grid-row-end: 6;
}

或者简写成

.grid-item {
  grid-column: 3 / 6;
  grid-row: 3 / 6;
}
2. grid-area

在grid-template-areas中已经涉及,给出项的名称,以便可以通过使用 grid-template-areas 属性创建的模板引用该项。

3. justify-self, align-self, place-self

前两个是grid-item自身的水平,垂直方向的分布。

.grid-item {
  justify-self: start | end | center | stretch;
}
.grid-item {
  align-self: start | end | center | stretch;
}

place-self 即align-self / justify-self,只会有一个值即两个值相同。 重点:除了 Edge 之外,所有主流浏览器都支持place-self。

结语:

在实际开发中,grid用的比较少,就按照使用频率的多少,从多到少整理了一下。期待会在项目中使用到grid。