Open evantianx opened 7 years ago
无特殊说明,均以下列 HTML 和 CSS 为模版:
<div class="grid">
<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>
.grid {
display: grid;
/* grid-gap 是 grid-column-gap 和 grid-rows-gap 的简写*/
grid-gap: 20px;
}
.grid div {
background: #41B883;
}
有三个属性可以定义该容器为 grid 容器
grid
创建一个 block 级别的 Grid 容器。默认情况下,子元素按行排列,每行都占满整个容器。
inline-grid
创建一个 inline-block 级别的 Grid 容器。默认情况下,子元素按行排列,每行根据子元素内容确定宽度。
subgrid
目前没有浏览器对其有支持。
作用是:使当前容器作为其父级 grid 容器的子容器来确定宽高,而非自己决定。
不过使用display: contents
可以达到相同的效果。
display: contents
causes an element's children to appear as if they were direct children of the element's parent, ignoring the element itself. This can be useful when a wrapper element should be ignored when using CSS grid or similar layout techniques.
grid-template-rows
和grid-template-columns
可以直接设置像素值(或者相对单位也可以)作为行高或列宽:
.grid {
grid-template-rows: 100px 50px;
grid-template-columns: 100px 100px 200px;
}
由于没有设置第三行行高,故第三行的高度由子元素内容高度确定。
也可以设置 fractions 来进行响应式布局:
.grid {
grid-template-rows: 2fr 1fr 1fr;
grid-template-columns: 1fr 2fr 1fr;
}
当然,两者结合也是 ok 的:
.grid {
grid-template-columns: 100px 25% 1fr 2fr;
}
此时的 1fr = ((容器宽度) - 100px - 25%(容器宽度)) /3
若容器没有设置该方向的尺寸且如
grid-template-columns: repeat(4, 1fr)
设置时,将按照元素实际占用宽高来决定宽高尺寸
利用minmax()
也可以进行响应式设计布局:
该函数接受两个参数,第一个是最小值,第二个是最大值。(参数可以为百分比,像素值或者 auto)
利用repeat()
来减少书写量
接受两个参数,第一个是重复次数,第二个为宽度或高度
.grid {
grid-template-rows: repeat(4, 100px);
grid-template-columns: repeat(3, 1fr);
}
repeat()也可以和其他值进行组合
可以对 lines 进行命名:
.grid {
/* 是可以有多个命名的 */
grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}
命名可以运用于repeat()中:
.grid { grid-template-columns: repeat(3, 20px [col-start]); }
grid-template-areas
Repeating the name of a grid area causes the content to span those cells.
值可以为某个子元素的
grid-area
值,或者.
(表示一个空位),或者none
<div class="grid"> <div class="item-a">1</div> <div class="item-b">2</div> <div class="item-c">3</div> <div class="item-d">4</div> </div>
.item-a { grid-area: header; } .item-b { grid-area: main; } .item-c { grid-area: sidebar; } .item-d { grid-area: footer; }
.grid { display: grid; grid-template-columns: 50px 50px 50px 50px; grid-template-rows: auto; grid-template-areas: "header header header header" "main main . sidebar" "footer footer footer footer"; }
![2017-05-20 1 34 32](https://cloud.githubusercontent.com/assets/17511710/26273337/19b2990e-3d61-11e7-907d-f534f5e5af62.png)
> .表示空位
> Notice that you're not naming lines with this syntax, just areas. When you use this syntax the lines on either end of the areas are actually getting named automatically. If the name of your grid area is foo, the name of the area's starting row line and starting column line will be foo-start, and the name of its last row line and last column line will be foo-end. This means that some lines might have multiple names, such as the far left line in the above example, which will have three names: header-start, main-start, and footer-start
#### `grid-column-gap` / `grid-row-gap`
设定 cell 间隙
> The gutters are only created between the columns/rows, not on the outer edges.
> **不在外边缘产生间隙**
#### `justify-items`
调整**水平**方向上 cell 的位置,会作用于 container 内所有 cell
可取值有: `start` 、`center`、`end`、`stretch`(默认)
> 单个 grid-item 可以采用 `justify-self` 单独调整
#### `align-items`
调整竖直方向上 cell 的摆放位置,类似于 `justify-items`。
> 对应 grid-item 属性为 `align-self`
#### `justify-content` / `align-content`
有时候如果只采用绝对单位如 `px`, 可能父容器未被子项目填满,那么 `justify-content` 和 `align-content` 就是用来调整整体 grid-item 在父级中的位置的
可取值: `start`、`center`、`end`、`stretch`、`space-between`、`space-around`、`space-evenly`
> 已经确定尺寸的不会受到影响
> 那还有啥意义呢??❓
### grid-item 属性
#### `grid-column-start` / `grid-column-end` / `grid-row-start` / `grid-row-end`
确定 grid-item 的位置
#### `grid-area`
不仅仅可以传名字,也可以传界限: 顺序为(`grid-row-start` + `grid-column-start` + `grid-row-end`+ `grid-column-end`) **逆时针顺序**
```css
.item-d {
grid-area: 1 / col4-start / last-line / 6
}
.grid {
/* 每个子元素水平方向定位,默认为 stretch */
justify-items: start | end | center | stretch;
/* 每个子元素竖直方向定位,默认为 stretch */
align-items: start | end | center | stretch;
/* 整体子元素水平方向定位 */
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
/* 整体子元素竖直方向定位 */
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
grid-template
⽗grid-template-columns
、grid-template-rows
、grid-template-areas
三者的缩写
在 grid-template-areas
中写的例子可以简写为:
.grid {
display: grid;
grid-template:
[row1-start] "header header header header" 40px [row1-end]
[row2-start] "main main . sidebar" auto [row2-end]
[row3-start] "footer footer footer footer" 30px [row3-end]
/ repeat(4, 50px);
}
经测试,后面的
repeat(4, 50px)
在 Chrome 中无效,只能用50px 50px 50px 50px
grid-gap
⽗grid-row-gap
和 grid-column-gap
的简写
若有一个不存在则赋予两者相同值
grid
⽗比 grid-template
更为强大,增加了 grid-auto-flow
的简写
.container {
grid: column 1fr / auto;
}
grid-column
/ grid-row
⼦简写 grid-column-start
/ grid-column-end
/ grid-row-start
/ grid-row-end
.item-a {
grid-row: 1/3;
grid-column: 2/7;
}
类似
grid-row: 2
这样的写法表示从 2 开始占一个 cell
grid-column: 1/-1
代表该子项目列占位从头开始到尾,数字代表 Grid tracks。-1
始终代表最后的那个 grid line。
grid-auto-columns
/ grid-auto-rows
声明一个 track 的 size,如:
.container {
grid-auto-columns: 60px;
grid-auto-rows: 60px;
}
然后在 grid-item 中可以根据 line 定位,如:
.item-b {
/* item-b 占位竖直线1-2,水平线4-7 */
grid-column: 1/2;
grid-row: 4/7;
}
grid-auto-flow
确定当没有指定位置时,grid item 的填充方式
即优先填充水平列还是竖直列
可取值为: row
、column
、dense
auto-fill
vs auto-fit
Grid 布局中有 repeat
功能来方便我们避免书写重复的属性值,如:
.grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
}
这样浏览器根据视口自适应调整每个 grid item 的大小,弊端在于当视口很小时, grid item 也会变得非常窄,不甚美观,好在我们有 minmax()
:
grid-template-columns: repeat(12, minmax(250px, 1fr));
问题又来了, 小屏幕上这样做会溢出,排版很乱,此时祭出 auto-fit
或 auto-fill
(会自动 wrap)
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
两者区别在于:
auto-fill FILLS the row with as many columns as it can fit. So it creates implicit columns whenever a new column can fit, because it's trying to FILL the row with as many columns as it can. The newly added columns can and may be empty, but they will still occupy a designated space in the row.
auto-fit FITS the CURRENTLY AVAILABLE columns into the space by expanding them so that they take up any available space. The browser does that after FILLING that extra space with extra columns (as with auto-fill ) and then collapsing the empty ones.
个人理解:
auto-fill
遵循的原则: 添加尽可能多的 column 无论它是否被某个元素占据
auto-fit
遵循的原则:没有元素占据的 column 保持为空,有元素占据的 column 占据尽可能大的空间
目前在 IE11 上支持,但必须添加前缀,且有一些意外情况:
grid-column
和 grid-row
问题IE requires you to manually specify start and span values using specific properties. Autoprefixer sadly doesn't do this transformation automatically so we have to take care of it ourselves.
<main>
元素不支持将其设置为 grid 子项目解决方法:
<div role="main"></div>
26 ⏎ 关于 flex 的一切
参考文章: