之前在项目中用bootstrap的时候没有深入理解,直接就上手用了,这几天重新看了官方文档中最基本的布局容器和栅格系统部分,并且阅读了相关部分的css源码,理解了bootstrap是如何通过CSS3的媒体查询语法来实现响应式的栅格布局。
如果你刚好还不理解bootstrap的栅格系统如何实现响应式布局,这篇手记或许会有帮助。
那么首先什么是响应式呢?
响应式网页设计的定义
它是针对任意设备对网页内容进行完美布局的一种显示机制。
以往我们先是针对桌面电脑进行固定宽度设计,然后将其缩小并针对小屏幕进行内容重排;现在我们应该首先针对小屏幕进行设计,然后逐步增强针对大屏幕的设计和内容。
也就是说页面布局会针对设备屏幕尺寸发生变化以更好的显示。那么bootstrap是怎么实现响应式布局的呢?
就是通过栅格系统。
布局容器
bootstrap的栅格系统要放在布局容器中,bootstrap提供了两种布局容器:
.container 类用于固定宽度并支持响应式布局的容器
...
.container类的宽度由媒体查询设定为在不同浏览器宽度范围内有几个固定值,且浏览器宽度768px以上的时候会有随浏览器宽度变化的左右margin。
.container-fluid类用于 100% 宽度,占据全部视口(viewport)的容器
...
.container-fluid类的宽度为100%浏览器窗口大小,且没有margin。
两类容器都有左右各15px的内边距,浏览器宽度小于768px的时候两者效果是相同的。
进一步查看源码bootstrap.css可以看到container和container-fluid类本身没有设置width属性值,也就是默认100%,但是container类还设置了媒体查询:
@media (min-width: 768px) {
.container {
width: 750px;
}
}
@media (min-width: 992px) {
.container {
width: 970px;
}
}
@media (min-width: 1200px) {
.container {
width: 1170px;
}
}
也就是说container类在浏览器viewport宽度768992px区间宽度固定为750px,在9921200px区间宽度宽度固定为970px,大于1200px的时候宽度固定为1170px,所以container类在viewport大于768px的时候会有变化的左右margin,而container-fluid类没有媒体查询设置,所以始终是100%宽度,没有左右margin。
栅格系统
有了布局容器后,你的内容就可以放在布局容器中,bootstrap通过栅格系统进行排版布局。
栅格系统的核心是类似.col-xs-1这样的div,也就是列,列放在行中,也就是.row这样的div,而行就放在布局容器中,一行最多会分为12列。预定义的列类名中,xs、sm、md和lg表明列的宽度设置分别在超小屏幕、小屏幕、中等屏幕和大屏幕上生效;1到12表示列宽度占行宽度的1/12到12/12。官方文档上写了这些列的参数和在不同尺寸viewport上如何排版布局,但是还是没有讲为什么,这里还是直接看源码bootstrap.css吧。
栅格预定义列类的代码就在布局容器预定义类部分代码的后面,首先可以看到:
.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
position: relative;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}
这里所有预定义列类都没有设置width属性,也就是默认行宽度的100%,接着可以看到:
.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
float: left;
}
.col-xs-12 {
width: 100%;
}
.col-xs-11 {
width: 91.66666667%;
}
.col-xs-10 {
width: 83.33333333%;
}
.col-xs-9 {
width: 75%;
}
.col-xs-8 {
width: 66.66666667%;
}
.col-xs-7 {
width: 58.33333333%;
}
.col-xs-6 {
width: 50%;
}
.col-xs-5 {
width: 41.66666667%;
}
.col-xs-4 {
width: 33.33333333%;
}
.col-xs-3 {
width: 25%;
}
.col-xs-2 {
width: 16.66666667%;
}
.col-xs-1 {
width: 8.33333333%;
}
上面的代码让所有xs类的列都左浮动,而且从1到12的width属性分别是1/12到12/12,注意这里没有用到媒体查询,所以无论viewport多大,xs类都会在一行内水平排列,且根据1~12占据固定比例。
在xs类的代码后可以找到sm类的和上面类似的代码,但是有一点不同,就是sm类用了媒体查询:@media (min-width: 768px),也就是说,只有当viewport宽度大于768px时sm类的列才会和xs类一样在一行内水平排列,且根据1~12占据固定比例。而当viewport小于768px的时候就会按默认的100%宽度在竖直方向从上到下排列了。后面的代码也是类似对md类和lg类的列也通过媒体查询设置了float: left和宽度比例,只要小于媒体查询所设置的宽度就会100%宽度竖直排列,大于媒体查询所设宽度才会水平按比例排列。
有的时候为了在不同尺寸的设备上都有合适的布局,可以同时应用不同规格的列类,比如对一个div同时添加.col-xs-6 .col-md-4两个类,会如何显示呢?如果是在超小屏幕上(小于768px),就会按.col-xs-6的设置显示为行宽的一半,这时.col-md-4类的媒体查询设置是失效的,如果是在中等屏幕上(大于等于992px),由于满足了.col-md-4类的媒体查询条件,而且这个媒体查询设置的代码是写在.col-xs-6类代码的后面,这时.col-xs-6类的设置就会失效,就会显示为行宽的1/3。
总结
从上面栅格系统的部分css源代码可以看出bootstrap利用栅格系统实现响应式布局的核心:
使用float实现流动布局,一行分为十二列,如果一行中超过了十二列,放不下的元素会滚到前面元素的下方,不会在水平方向overflow(溢出),避免了水平滚动条的出现。
使用百分比宽度,让内容宽度平滑渐变。
使用媒体查询,在不同尺寸的设备上应用不同类的预定义列,从而让排版更灵活地适配屏幕尺寸
说了这么多,也许一开始就对着css源码看并不是那么好理解,最好的学习方法还是借助官方文档中相关部分的实例代码写几个页面,在浏览器中打开,然后用浏览器开发者工具查看不同浏览器宽度下页面的布局,宽度等属性,然后再回来看相关部分的源码。
我是这样学会的~也许,你也可以试试。
参考资料
本作品采用知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。要查看该许可协议,可访问 http://creativecommons.org/licenses/by-nc-sa/4.0/ 或者写信到 Creative Commons, PO Box 1866, Mountain View, CA 94042, USA。