2.2.3 响应式栅格

刚才说到了,Bootstrap为不同的屏幕尺寸(4种类型)提供了不同的栅格样式,前面例子我们使用的一直是中型屏幕(md),其他3种样式分别是超小(xs)、小型(sm)、大型(lg),所以组合起来样式就多了,可以是.col-xs-1,也可以是.col-sm-offset-2,还可以是.col-lg-push-1或者.col-lg-pull-1。下面总结了一个表格用于记录不同类型浏览器的各种参数,如表2-1所示。

2.2.3 响应式栅格 - 图1

这些分界点是如何定义的?答案就是:它们是媒体查询定义的。前面源码已经提到了,下面再列一下:

  1. // 超小型是默认实现
  2. // 小型
  3. @media (min-width: 768px) {
  4. .container { width: 750px; }
  5. }
  6. // 中型
  7. @media (min-width: 992px) {
  8. .container { width: 970px; }
  9. }
  10. // 大型
  11. @media (min-width: 1200px) {
  12. .container { width: 1170px; }
  13. }

1.跨设备组合定义

通过前面的示例和源码可以发现,一种样式(比如col-md-9)在其定义的尺寸范围以外是不起作用的,比如,在小型或者大型屏幕下,所有带有md的样式都不会生效,而且没有默认值。这就是说,我们可以在一个元素上应用不同类型的样式,以适配不同尺寸的屏幕。比如下面的示例:

  1. <div class="row">
  2. <div class="col-sm-12 col-md-8">.col-sm-12 .col-md-8</div>
  3. <div class="col-sm-6 col-md-4">.col-sm-6 .col-md-4</div>
  4. </div>
  5. <div class="row">
  6. <div class="col-sm-6 col-md-4">.col-sm-6 .col-md-4</div>
  7. <div class="col-sm-6 col-md-4">.col-sm-6 .col-md-4</div>
  8. <div class="col-sm-6 col-md-4">.col-sm-6 .col-md-4</div>
  9. </div>
  10. <div class="row">
  11. <div class="col-sm-6">.col-sm-6</div>
  12. <div class="col-sm-6">.col-sm-6</div>
  13. </div>

在上述示例中,每个div元素都应用了两种样式,分别是sm类型和md类型,用于适配小型屏幕和中型屏幕。在中型屏幕中的效果如图2-7所示。

2.2.3 响应式栅格 - 图2 图2-7 中型屏幕的运行效果

而换到小型屏幕的浏览器上时,效果就完全不一样了,如图2-8所示。

2.2.3 响应式栅格 - 图3 图2-8 小型屏幕的运行效果

为什么不一样?这就是因为第一行row里的第1个div使用了col-sm-12,一下子就占用了12个列,所以第2个div就自动换行了。第2行也是,两个div就占满了12个列,所以最后一个col-sm-6就换行了。

读者,可能会问,第2行用的col-sm-6,为什么在中型屏幕上也是各占50%啊?这是因为针对sm类型的媒体查询只用了@media(min-width: 768px),而不是@media(min-width: 768px)and(max-width: 992px)。所以,如果没有定义md样式的话,sm样式默认情况下依然有效。总结一句,如果只用min-width,则表示向大兼容。

既然向大兼容,那向小肯定就不兼容了?没错,在小于768px的超小屏幕上浏览上述示例时,由于所有的样式都无效了,所以所有的div默认都垂直换行堆叠在一起了,效果如图2-9所示。

2.2.3 响应式栅格 - 图4 图2-9 跨设备组合在超小型屏幕下的运行效果

既然两种类型的样式可以组合在一起,那4种也就没什么问题了。所以可以在一个div上分别应用xs、sm、md、lg类型的样式,以便在所有的设备上都能进行正常浏览。

2.清除浮动问题

理想是美好的,但现实是残酷的。我们来举一个美好的例子。在小型屏幕上,希望实现如图2-10所示的效果。

2.2.3 响应式栅格 - 图5 图2-10 在小型屏幕下的预想效果

但是在超小型屏幕下,则希望每行只显示两个div元素,即如图2-11所示的效果。

2.2.3 响应式栅格 - 图6 图2-11 在超小型屏幕下的预想效果

理想很美好的,按照上述响应式栅格的建议,可能觉得应该如下设计:

  1. <div class="row">
  2. <div class="col-xs-6 col-sm-3">.col-xs-6 .col-sm-3</div>
  3. <div class="col-xs-6 col-sm-3">.col-xs-6 .col-sm-3</div>
  4. <div class="col-xs-6 col-sm-3">.col-xs-6 .col-sm-3</div>
  5. <div class="col-xs-6 col-sm-3">.col-xs-6 .col-sm-3</div>
  6. </div>

把真实内容填到div里进入,看看实际效果,如图2-12所示。

2.2.3 响应式栅格 - 图7 图2-12 在小型屏幕下的实际效果

你肯定会说:“这是怎么回事啊!”怎么回事?所有的col-样式都是左浮动,很明显,这是因为没有清除浮动导致的。第3个div开始换行的时候,div1的内容高度过高,所以div3就在右边紧接着显示了。

要解决这个问题,需要用Bootstrap提供的clearfix样式。更新后的代码如下所示:

  1. <div class="row">
  2. <div class="col-xs-6 col-sm-3">div1: .col-xs-6 .col-sm-3</div>
  3. <div class="col-xs-6 col-sm-3">div2: .col-xs-6 .col-sm-3</div>
  4. <div class="clearfix visible-xs"></div>
  5. <div class="col-xs-6 col-sm-3">div3: .col-xs-6 .col-sm-3</div>
  6. <div class="col-xs-6 col-sm-3">div4: .col-xs-6 .col-sm-3</div>
  7. </div>

利用clearfix样式清除浮动,但是前提条件是在超小型屏幕上能显示才行(因为其是用visible-xs样式控制的)。

3.列偏移和列排序

由于响应式设计是利用了媒体查询的特性,而所有以col-*开头的样式都是在媒体查询里定义的,所以像列偏移(offset)、列排序(pull和push)相关的样式也都可以用,以组合出不同的精美样式。以下的例子大家自行调试一下。

  1. <div class="row">
  2. <div class="col-sm-5 col-md-6">.col-sm-5 .col-md-6</div>
  3. <div class="col-sm-5 col-sm-offset-2 col-md-6 col-md-offset-0"></div>
  4. </div>
  5. <div class="row">
  6. <div class="col-sm-6 col-md-5 col-lg-6">.col-sm-6 .col-md-5 .col-lg-6</div>
  7. <div class="col-sm-6 col-md-5 col-md-offset-2 col-lg-6 col-lg-offset-0"></div>
  8. </div>

怎么样?看到这么多特性,感觉到强大了吧?是的,我也觉得很强大,但是,请看下一节。