CSS进阶实战2:grid使用技巧

  • 容器属性
    • 列宽、行高:grid-template-columns | grid-template-rows
    • 间距:row-gap | column-gap | gap
    • 对齐:justify-items | align-items
  • 项目属性
    • 跨度:grid-row | grid-column
    • 对齐:justify-self | align-self
  • Flexbox中使用gap属性

参考课程:Build Responsive Real-World Websites with HTML and CSS
视频 | 源码

基于React的响应式单页应用开发、优化和部署


参考:

CSS Grid 网格布局教程 - 阮一峰的网络日志

grid+less方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.grid(@col, @align: unset) {
display: grid;
column-gap: 6.4rem;
row-gap: 9.6rem;
grid-template-columns: repeat(@col, 1fr);
align-items: @align;

&:not(:last-child) {
margin-bottom: 9.6rem;
}
}

.grid--col2 {
.grid(2, center);
}

容器属性

定义在容器上的属性

1
display: grid

grid-template-columns

该属性定义每一列的列宽(定义行高为grid-template-rows)

列宽的单位可以是:

  • 像素:grid-template-columns: 100px 100px 100px
  • 百分比:grid-template-columns: 33.3% 33.3% 33.3%
  • fr关键字(fraction),数值表示列之间的宽度比:grid-template-columns: 1fr 1fr 1fr
  • 也可以结合使用:grid-template-columns: 150px 1fr 2fr;

语法糖:

repeat()接受两个参数,第一个参数是重复的次数(上例是3),第二个参数是所要重复的值。

1
2
3
4
5
6
7
8
9
10
11
12
grid-template-columns: 100px 100px 100px;
grid-template-columns: 33.3% 33.3% 33.3%;
grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: repeat(3, 1fr);

grid-template-columns: 70% 30%;
grid-template-columns: 7fr 3fr;

grid-template-columns: 150px 1fr 2fr; // px和fr混用
grid-template-columns: 1fr 1fr minmax(100px, 1fr); // minmax定义长度范围
grid-template-columns: 100px auto 100px; // auto自适应
grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4]; // 可以给网格线命名

row-gap | column-gap | gap

  • row-gap 属性设置行间距
  • column-gap 属性设置列间距
  • gap 属性是用来设置网格行与列之间的间隙,是上面两个的简写
    • 第一个参数为row-gap,第二个为column-gap
1
2
3
4
row-gap: 9.6rem;
column-gap: 6.4rem;

gap: 9.6rem 6.4rem;

justify-items | align-items

  • justify-items属性设置单元格内容的水平位置(左中右)

  • align-items属性设置单元格内容的垂直位置(上中下)

  • place-items属性是align-items属性和justify-items属性的合并简写形式

    • 第一个参数为align-items,第二个为justify-items
1
2
3
4
.container {
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
}

关键字含义

  • start:对齐单元格的起始边缘。
  • end:对齐单元格的结束边缘。
  • center:单元格内部居中。
  • stretch:拉伸,占满单元格的整个宽度(默认值)。

项目属性

定义在项目上的属性

grid-row | grid-column

1
2
3
4
.item {
grid-column: <start-line> / <end-line>;
grid-row: <start-line> / <end-line>;
}

两个参数,用斜杠/分隔,以grid-column为例

  • 第一个参数是起始列线(从1开始计数)
  • 第二个参数是结束列线

斜杠/和后面的第二个参数可省略,表示只跨越一格

顺序

可以将元素强制显示在某一行

1
2
grid-row: 1;
grid-row: 5;

跨度

span 后面写跨几格

1
2
3
grid-row: 1 / span 2;
grid-row: span 2;
grid-row: 1 / 3; // 等效写法

场景:表格第一行分三列,第二行分两列

  • 把grid声明为6列
  • 第一行元素跨度2,第二行元素跨度3
1
2
3
4
5
6
7
8
9
10
11
12
13
.nav-grid{
display: grid;
grid-template-columns: repeat(6, 1fr)
}

.nav-col {
grid-column: span 2;
grid-row: 1;
}

.addr-col {
grid-column: span 3;
}

Html

1
2
3
4
5
6
7
<div>
<div class=".addr-col"></div>
<div class=".addr-col"></div>
<div class=".nav-col"></div>
<div class=".nav-col"></div>
<div class=".nav-col"></div>
</div>

justify-self | align-self

对齐,但只作用于单个项目

  • justify-self属性设置单元格内容的水平位置(左中右)

  • align-self属性设置单元格内容的垂直位置(上中下)

  • place-self属性是align-self属性和justify-self属性的合并简写形式

    • 第一个参数为align-self,第二个为justify-self

关键字含义

  • start:对齐单元格的起始边缘。
  • end:对齐单元格的结束边缘。
  • center:单元格内部居中。
  • stretch:拉伸,占满单元格的整个宽度(默认值)。

场景:grid里三个元素,列数为2,希望单独成行的那一个元素能居中

在单独成行的那个元素上设置css属性:

1
2
3
4
.element {
grid-column: 1 / -1; // 横跨一整行
justify-self: center;
}

flex gap

Felxbox也可以用gap,用法跟grid一样,但是有些浏览器不兼容

image-20220513205338975

其他写法

1
2
3
4
5
6
.main-nav-list{
display: flex;
}
.main-nav-list li:not(:last-child) {
margin-right: 4.8rem;
}

修复兼容性

可以在项目中引入以下脚本

原理:

  • 检测浏览器是否支持flex gap
  • 如果不支持,在body元素注入no-flexbox-gap类
  • 在对应的css文件中手动写替换的flex样式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
///////////////////////////////////////////////////////////
// Fixing flexbox gap property missing in some Safari versions
function checkFlexGap() {
console.log("run check felx gap")
var flex = document.createElement("div");
flex.style.display = "flex";
flex.style.flexDirection = "column";
flex.style.rowGap = "1px";

flex.appendChild(document.createElement("div"));
flex.appendChild(document.createElement("div"));

document.body.appendChild(flex);
var isSupported = flex.scrollHeight === 1;
flex.parentNode.removeChild(flex);
console.log(isSupported);

if (!isSupported) document.body.classList.add("no-flexbox-gap");
}
checkFlexGap();

在css中是以嵌套css类选择器的形式实现

1
2
3
4
5
6
7
8
// CSS
.no-flexbox-gap .main-nav-list li:not(:last-child) {
margin-right: 4.8rem;
}

.no-flexbox-gap .list-item:not(:last-child) {
margin-bottom: 1.6rem;
}
------ 本文结束 ❤ 感谢你的阅读 ------
------ 版权信息 ------

本文标题:CSS进阶实战2:grid使用技巧

文章作者:Lury

发布时间:2022年05月12日 - 21:24

最后更新:2022年05月14日 - 20:13

原始链接:https://luryzhu.github.io/2022/05/12/CSS/omnifood2_grid/

许可协议:署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。