Responsive Layout In an Easy Way

在这里我们将实现一个基于窗口宽度的自适应布局,并且实现方法极为简单,不用在 HTML 文件中添加那些复杂的类名(col-sm-4col-md-8 之类的),也不需要为各种屏幕尺寸添加媒体查询。

The setup

我们使用下面的 HTML 模板:

1
2
3
4
5
6
7
8
<div class="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>

和 CSS:

1
2
3
4
5
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 50px 50px;
}

关于 Grid 栅格系统,可以看看这篇文章

Basic responsiveness

『 fraction unit 』在Grid 栅格系统中能够将一行分成均等的几个小单元,单位写作 fr

我们将每一列设置为一个单位的分数单元,再看看结果:

1
2
3
4
5
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 50px 50px;
}

你会发现每个元素都占据着一行的 1/3,并且随着行宽的改变而改变。

如果我们把 grid-template-columns 的值设为 1fr 2fr 1fr,第二列元素的宽度就会是其他元素的两倍,并且一行被分成了均等的四份。

Advanced responsiveness

上面的效果无论宽度怎么变化,栅格总是三列,并不是我们想要的响应式布局。我们想让栅格根据宽度的变化而改变列的数量。为了达到这个目的,还需要了解三个概念。

repeat( )

repeat() 方法很强大,比直接声明具体行数和列数要方便的多,我们把之前的代码用 repeat() 改一下:

1
2
3
4
5
.container {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(2, 50px);
}

也就是说 repeat(3, 100px)100px 100px 100px 是一样的,第一个参数指明你需要多少行或列,第二个参数指明宽度,所以这样改完后和我们一开始的效果是一样的:

auto-fit

接下来是 auto-fit,我们现在不把具体的列数写死,而是使用 auto-fit

1
2
3
4
5
6
.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, 100px);
grid-template-rows: repeat(2, 100px);
}

表现结果如下:

现在这个容器能够根据宽度改变而改变列的数量了。

它的表现行为是,尽可能多在一行里容纳下 100px 宽度的列。

然而将每一个固定为 100px 并不是我们想要的响应式布局,而且每次在页面右边都有一小片空白让人看得也很难受。

minmax( )

我们最后还需要一个属性 minmax(),现在我们将 100px 替换成 minmax(100px, 1fr),最后 CSS 是这样的:

1
2
3
4
5
6
.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-template-rows: repeat(2, 100px);
}

会得到下面的结果:

可以看出 minmax() 函数的功能是定义了一个大小的范围。

所以上面的代码会将列的宽度限定在 100px 以上,并且随着宽度的增加列数会适应性地增加。

Adding the images

最后我们添加上图片来实现本文开头那张图片的效果。

1
<div><img src="img/forest.jpg"/></div>

现在我们使用一个新的属性: object-fit: cover,它的功能是使图片覆盖包含它的整个容器,并且会将多余的部分自动剪裁。

Browser support

相关文章

CSS 栅格系统