Bootstrap3 栅格布局实现原理

老牛浏览 490评论 0发表于

1. 介绍

本文主要讲解 Bootstrap3 的栅格布局实现原理,以及实际使用中应该注意的问题。

栅格系统这些本来是隐藏在后面的东西,直接使用就可以,没必要去了解其真正的工作原理。除非你的布局出问题了,比如写一些复杂的页面,spacing,margin,padding 等这些全都乱了,特别在写某些需要动态调整的页面时。

很多人都对 Bootstrap 的栅格系统不太理解,得解释很多遍。所以我更倾向于用可视化的方式,来解释 Bootstrap 栅格系统是怎么工作的,这样更容易理解。让我们一起看看 Bootstrap 是如何巧妙的实现栅格系统的。

2. 原理

Bootstrap 的基本使用是这样的:

html
<div class="container">
    <div class="row">
        <div class="col-xs-12"></div>
    </div>
</div>

2.1 Container 容器

container 类有两个目的:

  1. 为响应式提供宽度约束。响应式尺寸的改变其实改变的是 container,行(rows)和列(columns)都是基于百分比的,不用改变;

  2. 提供内补(padding)使内容不至于紧贴在浏览器边缘,左右两边都是 15px 的 padding 值,下图中用粉色标出,稍后详细解释。

切记,不要在一个 container 中嵌套另一个 container。

5c5dc537-2e05-455e-a778-78de852b8b71

2.2 Row 行

行(row)为容纳列(column)提供了空间,默认一行分为 12 列,因为所有列都是左浮动的,行自然也就扮演了容器的角色。

行(row)的两侧拥有独特的 -15px 的 margin 值,如下图蓝色部分所示。行(row)被约束在容器(container)内,边缘与粉色区域的边缘重叠,但是没有超出。这里 -15px 的 margin 值把行(row)向两边延伸,最终抵消了容器(container)15px 的 padding。为什么这么做呢?后面介绍列时我们会知道。

不要在 container 外使用 row,不起作用。

aa6dad52-8198-48e8-9d84-8760a42fac85

2.3 Column 列

列拥有 15px 的 padding 值,在下图中用黄色部分表示。列的 padding 值使得列的边缘与行的边缘重叠了。同时由于行有负的 margin 值,容器有正的 padding 值,行和容器(container)的边缘也正好重叠。列的 padding 值为列与列的内容之间提供了 30px 的间隔。

不要在 row 外使用 col,不起作用。

d0ed7a7c-6919-4792-980e-23c2466f510b

2.4 Content Within a Column 列内内容

列的 padding 给内容提供了空白,让内容不至于紧贴在浏览器边界上,列和列的内容之间也有了 padding。这就是 container、row、column 最终要达到的设计效果。

e22b02a1-79d4-4ef5-ad70-fd879c2c3968

2.5 Nesting 嵌套

使用了 container,row,column 后,可以在列内再增加新的栅格。例如,在右侧的列内添加新的行时就不需要再在 container 中了。

30fd3987-2e9c-49d1-8d89-4277b539a872

这个技巧在于列扮演了 container 一样的角色,列也有 15px 的 padding,一样可以和 row 的负 margin 值相抵消,同时在内容的两侧留白。

138fe4a2-dc87-437c-aae0-4f228ae9d558

2.6 Offsets 偏移

偏移的实现相当简单,仅仅是在列(col)的左侧加上了 margin 值。

唯一比较怪的地方可能是最左侧的 col 是从 -15px 的 row 的 margin 值开始偏移的,中间的列的偏移则是直接从前一个列开始偏移,分割列并在列内容的两侧留出补白。除此之外,偏移和列(col)是一样的。

b23449e0-47b1-4404-b497-c121baa39e22

2.7 Push and Pull 列的排序

首先我们为什么需要对列进行排序:为了响应式的调整布局。比如说,在移动设备上使用移动端布局,在桌面上使用桌面布局,push 和 pull 允许你打破 HTML 中从上到下自左向右的布局方式。

让人更困惑的是 push pull 的实现是通过添加 position 而不是通过添加 margin 值来实现。push 添加的是 left 值,pull 添加的是 right 值。因为它们是浮动的,并且被包含在一个相对定位的容器中,行会根据你设置的距离进行对应的移动,比如,col-sm-push-4。

96466810-b1fc-44ea-841e-4a2a4a924948

这就出问题了,它会导致列重叠,而不像正常的列或者列的偏移。

所以大体是这样,当你 push 或 pull 之后,相应的还需要一个「互补」的操作。如果你 push 一个列到右侧,那么还要以对应的距离 pull 右侧的列到左侧。

6da06f36-6dd5-43b8-84d6-f8548e26a5b1

3. 背后的原理

3.1 Container

container 使得内容两侧能够有 15px 的空白,而不需要为 body 元素设置 15px 的 padding。否则可能会让非 Bootstrap 的 div 元素不能到达浏览器边缘,这对使用全屏背景色的 div 元素来说,很成问题。

3.2 Row

row 拥有负的 margin 值,并且值等于 container 的 padding 值,所以边界与 container 得以重叠,负的 margin 值抵消了 padding,这让 row 没有被 container 的 padding 所影响。

3.3 Columns

col 也拥有 15px 的 padding 值,使得内容和容器边缘有 15px 的空白,并且在相邻列的内容之间也有 15px + 15px 的留白。这就不需要单独为第一列或最后一列设置 padding。现在,不管怎样,在列内容和列边缘之间总是留有 15px 的空白。

3.4 Nested Rows

嵌套行的原理和上面一样,行的负 margin 值抵消了列的 padding,本质上列扮演了 container 的角色,所以嵌套行时不再需要 container。

3.5 Nested Columns

嵌套列和上面一样的。

3.6 Offsets

偏移的本质就是通过增加空白间隔达到你想要的距离,非常的简单。

3.7 Push/Pull

push 和 pull 用于在移动端到桌面端布局切换来调整左右列的位置,或者,当有一个特别的布局而 offset 偏移无效时。

4. 常见问题

下面会列举一些经常遇到的问题,绝大多数在 HTML 代码中很容易就能看出来。

4.1 缺少 container

第一个就是少了 container。没有 container 意味着没有 padding 与行(row)的负 margin 值相抵消,意味着行会超出父元素。当元素处于浏览器边缘时,造成奇怪的横向滚动。

845d6c0a-78c2-4c96-a997-f2c459e61900

4.2 缺少 row

第二个类似的问题就是少了 row,这与缺少 container 产生的问题相反,content 与浏览器(可视区)的边缘有了 30px 的距离,比正常值多了一倍。而且你的浮动也会产生问题。由于缺少了外面 row 的包裹,浮动没有得到正常的清除,导致浮动可能产生问题。

同样,当试图嵌套栅格系统时,新嵌进去的 content 离左侧的边距达到了 45px。

c1f71fa6-fc02-450d-8ec1-e72998bad93b

4.3 其它元素里面嵌套 container

在其它任意元素内嵌套 container 和列相比增加了新的 padding,同时也增加了 container 独有的响应式特性。

42eca870-c3ef-47b5-b07e-7bf019a28fda

4.4 偏移/push/pull

当使用偏移或者 push/pull 时,偏移很简单不会出现什么问题,只是让列更宽了。push/pull 不同,如果你 push 太多,列会超出它的 container,注意使用合适的值就不会有问题。

6eb3614c-018a-4c07-88e8-e345fb9d14b4

上面就是使用 Bootstrap3 的栅格系统时经常会碰到的一些问题,如果你在页面有很多的嵌套布局碰到问题,或者你的响应式布局没按照你所预想的方式工作,先看看上面这几点。

5. 最后

这就是 Bootstrap3 的栅格系统工作原理。它真的很聪明并且提供了极好的解决方案。在这么多年使用栅格系统的经验中,我个人觉得它是实现的最优雅的。

英文原文链接

点赞
收藏
暂无评论,快来发表评论吧~