PJCHENder 未整理筆記

[BS] Bootstrap 4 自訂容器和欄間距寬度(Custom Container and Gutters Width)

2017-10-19

[BS] Bootstrap 4 自訂容器和欄間距寬度(Custom Container and Gutters Width)

@(CSS)[bootstrap]

tags: bootstrap4, container, layout, gutter

這篇文章主要是說明 Bootstrap 4 中 .container 的作用,以及 .col 間的間距(gutters)是如何產生的。最後則說明如何自訂自己想要寬度的 container 容器和欄間距。因此不會介紹太多關於 Bootstrap layout 的內容,關於 Bootstrap Layout 的介紹可以參考中文官方文件

註1:閱讀前希望你先知道 FlexBootstrap Container 的基本用法。

註2:以下說明均是以 max-width: 1140px 的情況說明(.col-xl)。

註3:可搭配 程式範例 @ CodePen

註4:如果是要套用到全域的話,請參考文末。

基本的 Bootstrap Container 結構

簡單來說,Bootstrap Container 基本的結構長這樣:

1
2
3
4
5
6
7
8
9
10
<!-- HTML -->
<div class="container">
<div class="row">
<div class="col">
<div class="h4">
Lorem ipsum is placeholder text commonly used.
</div>
</div>
</div>
</div>

畫面則會長這樣子:

Imgur

接下來讓我們看一下這些樣式主要的作用是什麼。

.container

從 Bootstrap 4 原始當中可以看到,.container 的樣式大概是這樣子:

1
2
3
4
5
6
7
8
.container {
margin-right: auto;
margin-left: auto;
padding-right: 15px;
padding-left: 15px;
width: 100%;
max-width: 1140px; // 隨螢幕尺寸而變,當螢幕尺寸 ≥ 1200px 時是 1140px。
}

其中 .containermargin-rightmargin-left 是 auto,這是讓它可以水平置中的緣故。

接著當螢幕尺寸為 xl(≥1200px )時, 因為 max-width 是 1140px,而且有 padding-rightpadding-left 各 15px ,所以:

  • 容器寬為 1140px(如果是使用 .container-fluid 則沒有設定 max-width
  • 內容寬為 1110px
  • 左右多於的空間自動分配給 margin

我們用 Chrome Dev Tool 看一下大概會長這樣子,有幾點可以注意的是:

  • 左右 margin 100 會隨著螢幕的寬度自動伸縮
  • 容器寬雖然是 1140px,但是由於有 padding 15px 的緣故,所以實際上內容的寬度是 1110px

Imgur

容器寬雖然是 1140px,但是由於有 padding 15px 的緣故,所以實際上內容的寬度是 1110px

.row

透過 .row 會讓裡面的內容以 flex 方式排版,原本在 .container 的作用下,內容寬會是 1110px ,但是因為有 margin-rightmargin-left-15px 的緣故,所以:

  • 容器寬為 1140px
  • 內容寬為 1140px
1
2
3
4
5
6
.row {
display: flex;
flex-wrap: wrap;
margin-right: -15px;
margin-left: -15px;
}

Imgur

原本在 .container 的作用下內容寬會是 1110px ,但是因為有 margin-rightmargin-left -15px 的緣故,所以容器和內容寬度均變回 1140px。

.col

.col.row 的 flex-item。在剛剛 .row 的作用下,.col 的容器寬再次變成了 1140px ,但由於 .row 裡面有 padding-rightpadding-left 15px,所以:

  • 容器寬為 1140px
  • 內容寬為 1110px
1
2
3
4
5
6
7
8
9
10
.col {
position: relative;
flex-basis: 0;
flex-grow: 1;
max-width: 100%;
width: 100%;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}

Imgur

.col 裡面的 div

.col 中我們建立一個 <h4> 標籤,由於 .col 帶有 padding-leftpadding-right 15px 的緣故,所以 <h4>

  • 容器寬:1140px
  • 內容寬:1110px

Imgur

綜合上述,所以呢?

綜觀上面對於 .container, .row.col 的瞭解,我們可以知道,當.containermax-width: 1140px 時,整個容器的寬會是 1140px,但實際上內容的寬只會是 1110px,這兩者間差的 30px 就是來自於 padding-left: 15pxpadding-right: 15px

客制化 .container 容器寬度(Custom Container)

從上面的說明可以瞭解到,一般切版的時候,設計師給的稿上通常標示的會是內容寬度,而非容器寬度,因此假設設計師標示的內容寬度希望是 980px 時,我們就可以回推這時候我們 .containermax-width 應該要是 980px + 30px = 1010px。

速記:容器寬度 = 內容寬度 + 30px

註:這種算法只適用在 padding-left 和 padding-right 是 15px 的情況,也就是沒有修改 gutter 間距的情況。gutter 的修改會在後面的篇幅提到。

因此,我們可以在 HTML 中的 .container 這個 class 後面新增一個客制化的 class-.container-custom-width

1
2
3
4
5
6
7
8
<!-- HTML -->
<div class="container custom-container-width">
<div class="row">
<div class="col">
<h4>Lorem ipsum is placeholder text commonly used.</h4>
</div>
</div>
</div>

CSS 的部分就去修改原本 .containermax-width

1
2
3
4
5
6
7
/**
* 期望的內容寬 + 30px ,才會是最後的容器寬(不改變間距寬度的情況下)
**/

.container.custom-container-width {
max-width: 1010px; // 最後內容寬會是 980px
}

顯示的結果如下,上面原本的 container,容器寬是 1140px,內容寬是 1100px;下面是修改後的 .custom-container-width,可以看到新的樣式,容器寬是 1010px,內容寬就會是設計給的 980px,而左右兩邊的 margin 則會自動根據螢幕裝置寬度調整:

Imgur

那麼欄間距(gutters)呢?

在看完基本的 container 結構後,來看一下欄之間的間距吧。

前面有看到不論在 .container, .row, .col 中常常出現 15px 這個數字,基本上 Bootstrap 就是利用 padding 和 margin 中的 15px 做到間距的效果。

我們只要在 .row 中使用多個 .col 時,各個欄位間會自動出現間距,HTML 結構像是這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- HTML -->
<div class="container">
<div class="row">
<div class="col">
<h4>Lorem ipsum is placeholder text commonly used.</h4>
</div>
<div class="col">
<h4>Lorem ipsum is placeholder text commonly used.</h4>
</div>
<div class="col">
<h4>Lorem ipsum is placeholder text commonly used.</h4>
</div>
</div>
</div>

畫面會像這樣:

Imgur

可以看到每個 .col 都有 padding-left 和 padding-right 15px,這也就是 gutter 的來源,由於左右都有 padding 的緣故,所以欄位之間的間距會是 30px。

註:這種透過左右添加 padding 和 margin 達到 gutter 的效果,稱作 “gutter on outside”,可以在 sketch 中找到這個選項,若想瞭解更多可以參考這篇 What is the purpose of having outside gutters on a responsive grid? @ StackExchange(謝謝卡斯伯大大 提供)。

.no-gutters

在 Bootstrap4 中提供了 .no-gutters 這個 class,可以讓我們把間距拿掉。從 Bootstrap 4 原始檔中可以看到 .no-gutters 的 CSS 如下:

1
2
3
4
5
6
7
8
9
10
.no-gutters {
margin-right: 0;
margin-left: 0;
}

.no-gutters > .col,
.no-gutters > [class*="col-"] {
padding-right: 0;
padding-left: 0;
}

因此如果在 .row 上搭配 .no-gutters 則會把原本 .rowmargin-leftmargin-right-15px 拿掉,並且把 padding-leftpadding-right 都修為 0 ,因此原本欄和欄之間的間距會變為 0,畫面會像這樣:

Imgur

  • 容器寬(.container)為 1140px
  • 內容全寬為 1110px
  • .col 間不在有間距存在

客制化欄間距(Custom Gutters)

知道欄間距的作法是透過 padding 和 margin 之後就可以客制化我們自己想要的間距大小,舉例來說,現在設計師希望欄和欄之間的間距不要是 30px 而是 20px 這時候我們就可以客制化調整我們的 gutter。

因為要同時修改 .container, .row, .col 所使用到的 margin 或 padding 的 px 值,所以我們把客制化 gutter 用的 class .custom-gutters 加在和 .container 同一層,HTML 結構長這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- HTML -->
<div class="container custom-gutters">
<div class="row">
<div class="col">
<h4>Lorem ipsum is placeholder text commonly used.</h4>
</div>
<div class="col">
<h4>Lorem ipsum is placeholder text commonly used.</h4>
</div>
<div class="col">
<h4>Lorem ipsum is placeholder text commonly used.</h4>
</div>
</div>
</div>

CSS 的部分,則是去修改和間距寬度相關的像素值,並且利用 SCSS 建立一個變數名為 $custom-gutter-width

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* SCSS */
$custom-gutter-width: 20px; // 將欄距改成 20px
.custom-gutters {
&.container {
padding-left: $custom-gutter-width / 2;
padding-right: $custom-gutter-width / 2;
}
.row {
margin-left: -($custom-gutter-width / 2);
margin-right: -($custom-gutter-width / 2);
}
.col {
padding-left: $custom-gutter-width / 2;
padding-right: $custom-gutter-width / 2;
}
}

從畫面中可以看到,.col 的 padding 變成 10px,因此欄和欄之間的間距變成 10 + 10 = 20px,而且因為沒有去改變 .container 的 max-width,所以整個容器寬還是一樣是預設的 1140px:

Imgur

要留意的是,當我們把間距改成 20px 時,表示 .col 左右兩邊各會有 10px 的 padding,因此我們的內容寬實際上會是 .col 寬度在少 20px:

Imgur

客制化 Bootstrap 變數

上面的作法主要是用在:

  1. 直接使用 Bootstrap 4 下載的 bootstrap.css 檔案,沒有辦法透過編譯器重新編譯 SCSS 檔案時。
  2. 只要套用在某些頁面,不是整個網頁都要改變容器寬度或欄間距時。

也就是說,如果你可以重新透過 SCSS 編譯出新的 CSS 檔,而且要套用在整個網頁的情況下時,就可以不用使用上述的方法,而是可以透過客制化 Bootstrap 變數的方法來達成。

Bootstrap 的變數存放在 Bootstrap 資料夾中 ./scss/_variables.scss 這支檔案,裡面列了許多變數,像這裡提到的容器寬度和欄間距都可以在這裡找到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* ./scss/_variables.scss  */
// Grid containers
// Define the maximum width of `.container` for different screen sizes.

$container-max-widths: (
sm: 540px,
md: 720px,
lg: 960px,
xl: 1140px
) !default;

// Grid columns
// Set the number of columns and specify the width of the gutters.

$grid-columns: 12 !default;
$grid-gutter-width: 30px !default;

另外每個變數後面都有寫 !default,代表你只要在這支 SCSS 檔之前先宣告 $container-max-widths$grid-gutter-width 的值時,它就會覆蓋掉 Bootstrap 預設的變數值。

關於客制化 Bootstrap 變數的方法,可以參考官方網站-Customization Options 的說明。

參考

Grid @ Bootstrap4

掃描二維條碼,分享此文章