在这里我们将实现一个基于窗口宽度的自适应布局,并且实现方法极为简单,不用在 HTML 文件中添加那些复杂的类名(col-sm-4
、col-md-8
之类的),也不需要为各种屏幕尺寸添加媒体查询。
The setup
我们使用下面的 HTML 模板:
1 | <div class="container"> |
和 CSS:
1 | .container { |
关于 Grid 栅格系统,可以看看这篇文章。
Basic responsiveness
『 fraction unit 』在Grid 栅格系统中能够将一行分成均等的几个小单元,单位写作 fr
。
我们将每一列设置为一个单位的分数单元,再看看结果:
1 | .container { |
你会发现每个元素都占据着一行的 1/3
,并且随着行宽的改变而改变。
如果我们把 grid-template-columns
的值设为 1fr 2fr 1fr
,第二列元素的宽度就会是其他元素的两倍,并且一行被分成了均等的四份。
Advanced responsiveness
上面的效果无论宽度怎么变化,栅格总是三列,并不是我们想要的响应式布局。我们想让栅格根据宽度的变化而改变列的数量。为了达到这个目的,还需要了解三个概念。
repeat( )
repeat()
方法很强大,比直接声明具体行数和列数要方便的多,我们把之前的代码用 repeat()
改一下:
1 | .container { |
也就是说 repeat(3, 100px)
和 100px 100px 100px
是一样的,第一个参数指明你需要多少行或列,第二个参数指明宽度,所以这样改完后和我们一开始的效果是一样的:
auto-fit
接下来是 auto-fit
,我们现在不把具体的列数写死,而是使用 auto-fit
:
1 | .container { |
表现结果如下:
现在这个容器能够根据宽度改变而改变列的数量了。
它的表现行为是,尽可能多在一行里容纳下 100px
宽度的列。
然而将每一个固定为 100px
并不是我们想要的响应式布局,而且每次在页面右边都有一小片空白让人看得也很难受。
minmax( )
我们最后还需要一个属性 minmax()
,现在我们将 100px
替换成 minmax(100px, 1fr)
,最后 CSS 是这样的:
1 | .container { |
会得到下面的结果:
可以看出 minmax()
函数的功能是定义了一个大小的范围。
所以上面的代码会将列的宽度限定在 100px
以上,并且随着宽度的增加列数会适应性地增加。
Adding the images
最后我们添加上图片来实现本文开头那张图片的效果。
1 | <div><img src="img/forest.jpg"/></div> |
现在我们使用一个新的属性: object-fit: cover
,它的功能是使图片覆盖包含它的整个容器,并且会将多余的部分自动剪裁。