Bootstrap 提供了一套響應(yīng)式、移動設(shè)備優(yōu)先的流式柵格系統(tǒng),隨著屏幕或視口(viewport)尺寸的增加,系統(tǒng)會自動分為最多 12 列。它包含了易于使用的預(yù)定義類,還有強(qiáng)大的 mixin 用于生成更具語義的布局。
柵格系統(tǒng)用于通過一系列的行(row)與列(column)的組合來創(chuàng)建頁面布局,你的內(nèi)容就可以放入這些創(chuàng)建好的布局中。下面就介紹一下 Bootstrap 柵格系統(tǒng)的工作原理:
.row 元素設(shè)置負(fù)值 margin 從而抵消掉為 .container 元素設(shè)置的 padding,也就間接為“行(row)”所包含的“列(column)”抵消掉了padding。.col-md-*柵格類適用于與屏幕寬度大于或等于分界點(diǎn)大小的設(shè)備 , 并且針對小屏幕設(shè)備覆蓋柵格類。 因此,在元素上應(yīng)用任何 .col-lg-* 不存在, 也影響大屏幕設(shè)備。通過研究后面的實(shí)例,可以將這些原理應(yīng)用到你的代碼中。
在柵格系統(tǒng)中,我們在 Less 文件中使用以下媒體查詢(media query)來創(chuàng)建關(guān)鍵的分界點(diǎn)閾值。
/* 超小屏幕(手機(jī),小于 768px) */
/* 沒有任何媒體查詢相關(guān)的代碼,因?yàn)檫@在 Bootstrap 中是默認(rèn)的(還記得 Bootstrap 是移動設(shè)備優(yōu)先的嗎?) */
/* 小屏幕(平板,大于等于 768px) */
@media (min-width: @screen-sm-min) { ... }
/* 中等屏幕(桌面顯示器,大于等于 992px) */
@media (min-width: @screen-md-min) { ... }
/* 大屏幕(大桌面顯示器,大于等于 1200px) */
@media (min-width: @screen-lg-min) { ... }
我們偶爾也會在媒體查詢代碼中包含 max-width 從而將 CSS 的影響限制在更小范圍的屏幕大小之內(nèi)。
@media (max-width: @screen-xs-max) { ... }
@media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) { ... }
@media (min-width: @screen-md-min) and (max-width: @screen-md-max) { ... }
@media (min-width: @screen-lg-min) { ... }
通過下表可以詳細(xì)查看 Bootstrap 的柵格系統(tǒng)是如何在多種屏幕設(shè)備上工作的。
| 超小屏幕 手機(jī) (<768px) | 小屏幕 平板 (≥768px) | 中等屏幕 桌面顯示器 (≥992px) | 大屏幕 大桌面顯示器 (≥1200px) | |
|---|---|---|---|---|
| 柵格系統(tǒng)行為 | 總是水平排列 | 開始是堆疊在一起的,當(dāng)大于這些閾值時將變?yōu)樗脚帕蠧 | ||
.container 最大寬度 |
None (自動) | 750px | 970px | 1170px |
| 類前綴 | .col-xs- |
.col-sm- |
.col-md- |
.col-lg- |
| 列(column)數(shù) | 12 | |||
| 最大列(column)寬 | 自動 | ~62px | ~81px | ~97px |
| 槽(gutter)寬 | 30px (每列左右均有 15px) | |||
| 可嵌套 | 是 | |||
| 偏移(Offsets) | 是 | |||
| 列排序 | 是 | |||
使用單一的一組 .col-md-* 柵格類,就可以創(chuàng)建一個基本的柵格系統(tǒng),在手機(jī)和平板設(shè)備上一開始是堆疊在一起的(超小屏幕到小屏幕這一范圍),在桌面(中等)屏幕設(shè)備上變?yōu)樗脚帕小K小傲校╟olumn)必須放在 ” .row 內(nèi)。
<div class="row">
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
</div>
<div class="row">
<div class="col-md-8">.col-md-8</div>
<div class="col-md-4">.col-md-4</div>
</div>
<div class="row">
<div class="col-md-4">.col-md-4</div>
<div class="col-md-4">.col-md-4</div>
<div class="col-md-4">.col-md-4</div>
</div>
<div class="row">
<div class="col-md-6">.col-md-6</div>
<div class="col-md-6">.col-md-6</div>
</div>
將最外面的布局元素 .container 修改為 .container-fluid,就可以將固定寬度的柵格布局轉(zhuǎn)換為 100% 寬度的布局。
<div class="container-fluid">
<div class="row">
...
</div>
</div>
是否不希望在小屏幕設(shè)備上所有列都堆疊在一起?那就使用針對超小屏幕和中等屏幕設(shè)備所定義的類吧,即 .col-xs-* 和 .col-md-*。請看下面的實(shí)例,研究一下這些是如何工作的。
<!-- Stack the columns on mobile by making one full-width and the other half-width -->
<div class="row">
<div class="col-xs-12 col-md-8">.col-xs-12 .col-md-8</div>
<div class="col-xs-6 col-md-4">.col-xs-6 .col-md-4</div>
</div>
<!-- Columns start at 50% wide on mobile and bump up to 33.3% wide on desktop -->
<div class="row">
<div class="col-xs-6 col-md-4">.col-xs-6 .col-md-4</div>
<div class="col-xs-6 col-md-4">.col-xs-6 .col-md-4</div>
<div class="col-xs-6 col-md-4">.col-xs-6 .col-md-4</div>
</div>
<!-- Columns are always 50% wide, on mobile and desktop -->
<div class="row">
<div class="col-xs-6">.col-xs-6</div>
<div class="col-xs-6">.col-xs-6</div>
</div>
在上面案例的基礎(chǔ)上,通過使用針對平板設(shè)備的 .col-sm-* 類,我們來創(chuàng)建更加動態(tài)和強(qiáng)大的布局吧。
.col-xs-12 .col-sm-6 .col-md-8.col-xs-6 .col-md-4 .col-xs-6 .col-sm-4.col-xs-6 .col-sm-4.col-xs-6 .col-sm-4
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-8">.col-xs-12 .col-sm-6 .col-md-8</div>
<div class="col-xs-6 col-md-4">.col-xs-6 .col-md-4</div>
</div>
<div class="row">
<div class="col-xs-6 col-sm-4">.col-xs-6 .col-sm-4</div>
<div class="col-xs-6 col-sm-4">.col-xs-6 .col-sm-4</div>
<!-- Optional: clear the XS cols if their content doesn't match in height -->
<div class="clearfix visible-xs-block"></div>
<div class="col-xs-6 col-sm-4">.col-xs-6 .col-sm-4</div>
</div>
如果在一個 .row 內(nèi)包含的列(column)大于 12 個,包含多余列(column)的元素將作為一個整體單元被另起一行排列。
.col-xs-9.col-xs-4 Since 9 + 4 = 13 > 12, this 4-column-wide div gets wrapped onto a new line as one contiguous unit..col-xs-6 Subsequent columns continue along the new line.
<div class="row">
<div class="col-xs-9">.col-xs-9</div>
<div class="col-xs-4">.col-xs-4<br>Since 9 + 4 = 13 > 12, this 4-column-wide div gets wrapped onto a new line as one contiguous unit.</div>
<div class="col-xs-6">.col-xs-6<br>Subsequent columns continue along the new line.</div>
</div>
With the four tiers of grids available you're bound to run into issues where, at certain breakpoints, your columns don't clear quite right as one is taller than the other. To fix that, use a combination of a .clearfix and our responsive utility classes.
.col-xs-6 .col-sm-3 Resize your viewport or check it out on your phone for an example. .col-xs-6 .col-sm-3.col-xs-6 .col-sm-3.col-xs-6 .col-sm-3
<div class="row">
<div class="col-xs-6 col-sm-3">.col-xs-6 .col-sm-3</div>
<div class="col-xs-6 col-sm-3">.col-xs-6 .col-sm-3</div>
<!-- Add the extra clearfix for only the required viewport -->
<div class="clearfix visible-xs-block"></div>
<div class="col-xs-6 col-sm-3">.col-xs-6 .col-sm-3</div>
<div class="col-xs-6 col-sm-3">.col-xs-6 .col-sm-3</div>
</div>
In addition to column clearing at responsive breakpoints, you may need to reset offsets, pushes, or pulls. See this in action in the grid example.
<div class="row">
<div class="col-sm-5 col-md-6">.col-sm-5 .col-md-6</div>
<div class="col-sm-5 col-sm-offset-2 col-md-6 col-md-offset-0">.col-sm-5 .col-sm-offset-2 .col-md-6 .col-md-offset-0</div>
</div>
<div class="row">
<div class="col-sm-6 col-md-5 col-lg-6">.col-sm-6 .col-md-5 .col-lg-6</div>
<div class="col-sm-6 col-md-5 col-md-offset-2 col-lg-6 col-lg-offset-0">.col-sm-6 .col-md-5 .col-md-offset-2 .col-lg-6 .col-lg-offset-0</div>
</div>
使用 .col-md-offset-*類可以將列向右側(cè)偏移。這些類實(shí)際是通過使用 *選擇器為當(dāng)前元素增加了左側(cè)的邊距(margin)。例如,.col-md-offset-4類將 .col-md-4 元素向右側(cè)偏移了4個列(column)的寬度。
.col-md-4.col-md-4 .col-md-offset-4 .col-md-3 .col-md-offset-3.col-md-3 .col-md-offset-3 .col-md-6 .col-md-offset-3
<div class="row">
<div class="col-md-4">.col-md-4</div>
<div class="col-md-4 col-md-offset-4">.col-md-4 .col-md-offset-4</div>
</div>
<div class="row">
<div class="col-md-3 col-md-offset-3">.col-md-3 .col-md-offset-3</div>
<div class="col-md-3 col-md-offset-3">.col-md-3 .col-md-offset-3</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">.col-md-6 .col-md-offset-3</div>
</div>
為了使用內(nèi)置的柵格系統(tǒng)將內(nèi)容再次嵌套,可以通過添加一個新的 .row 元素和一系列 .col-sm-* 元素到已經(jīng)存在的 .col-sm-* 元素內(nèi)。被嵌套的行(row)所包含的列(column)的個數(shù)不能超過12(其實(shí),沒有要求你必須占滿12列)。
Level 1: .col-sm-9 Level 2: .col-xs-8 .col-sm-6 Level 2: .col-xs-4 .col-sm-6
<div class="row">
<div class="col-sm-9">
Level 1: .col-sm-9
<div class="row">
<div class="col-xs-8 col-sm-6">
Level 2: .col-xs-8 .col-sm-6
</div>
<div class="col-xs-4 col-sm-6">
Level 2: .col-xs-4 .col-sm-6
</div>
</div>
</div>
</div>
通過使用 .col-md-push-*和 .col-md-pull-* 類就可以很容易的改變列(column)的順序。
.col-md-9 .col-md-push-3.col-md-3 .col-md-pull-9
<div class="row">
<div class="col-md-9 col-md-push-3">.col-md-9 .col-md-push-3</div>
<div class="col-md-3 col-md-pull-9">.col-md-3 .col-md-pull-9</div>
</div>
除了用于快速布局的預(yù)定義柵格類,Bootstrap 還包含了一組 Less 變量和 mixin 用于幫你生成簡單、語義化的布局。
通過變量來定義列數(shù)、槽(gutter)寬、媒體查詢閾值(用于確定合適讓列浮動)。我們使用這些變量生成預(yù)定義的柵格類,如上所示,還有如下所示的定制 mixin。
@grid-columns: 12;
@grid-gutter-width: 30px;
@grid-float-breakpoint: 768px;
mixin 用來和柵格變量一同使用,為每個列(column)生成語義化的 CSS 代碼。
// Creates a wrapper for a series of columns
.make-row(@gutter: @grid-gutter-width) {
// Then clear the floated columns
.clearfix();
@media (min-width: @screen-sm-min) {
margin-left: (@gutter / -2);
margin-right: (@gutter / -2);
}
// Negative margin nested rows out to align the content of columns
.row {
margin-left: (@gutter / -2);
margin-right: (@gutter / -2);
}
}
// Generate the extra small columns
.make-xs-column(@columns; @gutter: @grid-gutter-width) {
position: relative;
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
// Calculate width based on number of columns available
@media (min-width: @grid-float-breakpoint) {
float: left;
width: percentage((@columns / @grid-columns));
}
}
// Generate the small columns
.make-sm-column(@columns; @gutter: @grid-gutter-width) {
position: relative;
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
// Calculate width based on number of columns available
@media (min-width: @screen-sm-min) {
float: left;
width: percentage((@columns / @grid-columns));
}
}
// Generate the small column offsets
.make-sm-column-offset(@columns) {
@media (min-width: @screen-sm-min) {
margin-left: percentage((@columns / @grid-columns));
}
}
.make-sm-column-push(@columns) {
@media (min-width: @screen-sm-min) {
left: percentage((@columns / @grid-columns));
}
}
.make-sm-column-pull(@columns) {
@media (min-width: @screen-sm-min) {
right: percentage((@columns / @grid-columns));
}
}
// Generate the medium columns
.make-md-column(@columns; @gutter: @grid-gutter-width) {
position: relative;
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
// Calculate width based on number of columns available
@media (min-width: @screen-md-min) {
float: left;
width: percentage((@columns / @grid-columns));
}
}
// Generate the medium column offsets
.make-md-column-offset(@columns) {
@media (min-width: @screen-md-min) {
margin-left: percentage((@columns / @grid-columns));
}
}
.make-md-column-push(@columns) {
@media (min-width: @screen-md-min) {
left: percentage((@columns / @grid-columns));
}
}
.make-md-column-pull(@columns) {
@media (min-width: @screen-md-min) {
right: percentage((@columns / @grid-columns));
}
}
// Generate the large columns
.make-lg-column(@columns; @gutter: @grid-gutter-width) {
position: relative;
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
// Calculate width based on number of columns available
@media (min-width: @screen-lg-min) {
float: left;
width: percentage((@columns / @grid-columns));
}
}
// Generate the large column offsets
.make-lg-column-offset(@columns) {
@media (min-width: @screen-lg-min) {
margin-left: percentage((@columns / @grid-columns));
}
}
.make-lg-column-push(@columns) {
@media (min-width: @screen-lg-min) {
left: percentage((@columns / @grid-columns));
}
}
.make-lg-column-pull(@columns) {
@media (min-width: @screen-lg-min) {
right: percentage((@columns / @grid-columns));
}
}
你可以重新修改這些變量的值,或者用默認(rèn)值調(diào)用這些 mixin。下面就是一個利用默認(rèn)設(shè)置生成兩列布局(列之間有間隔)的案例。
.wrapper {
.make-row();
}
.content-main {
.make-lg-column(8);
}
.content-secondary {
.make-lg-column(3);
.make-lg-column-offset(1);
}
<div class="wrapper">
<div class="content-main">...</div>
<div class="content-secondary">...</div>
</div>