您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關使用BootStrap怎么實現柵格布局,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
box-sizing: border-box
這是最基本的一點,將盒子模型設置成邊框盒子.這樣 width
屬性指定的盒子寬度就包括 border + padding + content
。只要 width
固定,指定 padding
和 border
將不會改變盒子的大小。
*, *::before, *::after { box-size: border-box; }
知識前置
sass 基礎
bootstrap 柵格布局基本會使用
flex 布局基礎
本文柵格實現參考 bootstrap 源碼實現
一般來說作為應用最頂層的容器分為兩種:
響應式容器
.container
.container-sm
.container-md
.container-lg
.container-xl
固定寬度容器( bootstrap 中叫做流體容器)
.container-fluid
響應式容器會根據屏幕寬度的不同,根據媒體查詢使用 max-width
約束容器的寬度。因為 bootstrap 移動優先的原則,所以是先滿足小屏幕的容器樣式,然后再根據媒體查詢擴展大屏幕的樣式。
container 基本數據
xs < 576px | sm >= 576px | md >=768px | lg >=992px | xl >=1200px | |
---|---|---|---|---|---|
.container | 100% | 540px | 720px | 960px | 1140px |
.container-sm | 100% | 540px | 720px | 960px | 1140px |
.container-md | 100% | 100% | 720px | 960px | 1140px |
.container-lg | 100% | 100% | 100% | 960px | 1140px |
.container-xl | 100% | 100% | 100% | 100% | 1140px |
.container-fluid | 100% | 100% | 100% | 100% | 100% |
斷點:
$grid-breakpoints: ( xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px );
不同斷點對應的容器寬度:
$container-max-widths: ( sm: 540px, // min-width: 576px md: 720px, // min-width: 768px lg: 960px, // min-width: 992px xl: 1140px // min-width: 1200px );
實際上斷點到底取在哪里,可以隨意自定義。這里只是引用的 bootstrap 的規范而已。
固定容器實現很簡單。無非就是將容器的寬度設置為 100%
, 水平居中而已。
/** * 基本容器的樣式 * 寬度 100% * 有半個槽寬的內邊距 * 水平居中 * @param $gutter 槽寬, 如果只是想要一個普通的容器。可以將參數槽寬設置為 0 * 默認值是 $gird-gutter-width */ @mixin make-container($gutter: $grid-gutter-width) { width: 100%; padding-right: $gutter / 2; padding-left: $gutter / 2; margin-right: auto; margin-left: auto; }
槽寬這個概念如果用過 bootstrap 應該能夠理解。如果不理解可以跳到本文底部,有詳細介紹。
當屏幕寬度小于 576px
的時候,所有的容器寬度都是 100%
。即 xs
的情況下:
.container, .container-sm, .container-md, .container-lg, .container-xl, .container-fluid { @include make-container(); }
要實現響應式容器,就是要根據不同的斷點分別給不同的容器設置媒體查詢,以 max-width
約束容器的寬度。
根據規范所示:
當斷點為 sm
時, .container
, .container-sm
的 max-width
為 540px
,其余容器為初始的 100%
當斷點為 md
時, .container
, .container-sm, .container-md
的 max-width
為 720px
,其余容器為初始的 100%
當斷點為 lg
時, .container
, .container-sm, .container-md, .container-lg
的 max-width
為 960px
,其余容器為初始的 100%
當斷點為 xl
時, .container
, .container-sm, .container-md, .container-lg, .container-xl
的 max-width
為 1140px
,其余容器為初始的 100%
分析一下,就可以發現。每個斷點處需要設置媒體查詢的容器數剛好在 .container-#{$breakpoint}
處停止。
使用 sass 描述如下:
@each $breakpoint, $container-max-width in $container-max-widths { /** * .container * .container-sm * .container-md * .container-lg * .container-xl * 按照斷點設置媒體查詢 * 其實就是通過 max-width 控制容器到底有多寬 */ @include media-breakpoint-up($breakpoint, $grid-breakpoints) { // 每個斷點的屏幕最大 width %responsitive-#{$breakpoint} { max-width: $container-max-width; } // 用于確定哪些容器需要設置媒體查詢的 flag $extend-breakpoint: true; @each $name, $width in $grid-breakpoints { @if $extend-breakpoint { .container#{breakpoint-infix($name)} { @extend %responsitive-#{$breakpoint}; } } @if $name == $breakpoint { $extend-breakpoint: false; } } } }
其中兩個輔助函數 breakpoint-min
, breakpoint-infix
:
/** * 根據斷點名稱取得對應的斷點 width. * 注意:如果是 xs 斷點,返回的是 null * @param $name: 傳入的 map key * @param $breakpoints-map: 斷點 map * @return: 斷點對應的 mind-width */ @function breakpoint-min($name, $breakpoints-map: $grid-breakpoints) { $min: map-get($map: $breakpoints-map, $key: $name); @return if($min != 0, $min, null); } /** * 根據斷點名稱作為 key 查詢map * 若是 map 中 key對應的 value 不為 0 則生成后綴名 * 否則返回空串 * * @param $name: 傳入的 map key * @param $breakpoints-map: 斷點 map * @return: 斷點對應的后綴名 格式 '-sm' */ @function breakpoint-infix($name, $breakpoints-map: $grid-breakpoints) { @return if(breakpoint-min($name) != null, '-#{$name}', ''); }
輔助 mixin media-breakpoint-up
:
/** * 根據 $name 作為 key 查詢 $breakpoints-map 中對應的斷點值 * 如果斷點值存在,則對相應內容設置媒體查詢 * 如果斷點值不存在,則將混合的內容原樣輸出 * * @param $name 斷點名稱 * @param $breakpoints-map 保存斷點的 map */ @mixin media-breakpoint-up($name, $breakpoints-map: $grid-breakpoints) { $min: breakpoint-min($name, $breakpoints-map); @if $min { @media (min-width: $min) { @content; } }@else { @content; } }
柵格布局主要就是圍繞 row
和 column
展開。行中放置列,列中放置應用內容,列中又可以嵌套行(子子孫孫無窮盡也(x))。
行其實就是一個固定的容器,所以樣式也很簡單。
/** * 行基礎樣式 * 開啟 flex 布局 * 允許多行容器 * 左右有半個槽寬的負外邊距 * * @param $gutter 槽寬 */ @mixin make-row($gutter: $grid-gutter-width) { display: flex; flex-wrap: wrap; margin-right: -$gutter / 2; margin-left: -$gutter / 2; }
// 行 .row { @include make-row(); }
column 是柵格布局中最重要的部分,同時也是最復雜的一部分。
有多種列可供使用:
等寬列 .col
特點是 .row
中放置 n 個 .col
, 那么一個 .col
的寬度就是 .row
的 n 分之一
比例列 .col-${i}
$i 取值為 1- 12
. bootstrap 默認情況下一行可以分作12列。 .col-{$i}
所占的寬度就是 row
總寬度的 $i / 12
。
這里默認分成的列數對應變量是 $grid-columns: 12 !default;
可變寬度的彈性列 .col-auto
其所占據的寬度由其內容寬度決定
如果是在小屏幕下,我們通常不會讓一行有很多列,通常一行都只有一列。所以根據不同的屏幕斷點,bootstrap 還提供了響應式列。
等寬列 .col-#{$breakpoint}
比例列 .col-#{$breakpoint}-${i}
可變寬度的彈性列 .col-#{$breakpoint}-auto
語義是,當屏幕大于等于斷點對應寬度時,呈現列的語義形式。當小于斷點寬度時,所有的列都退化成 width: 100%;
的形式。同樣的,這也通過媒體查詢實現.
所有列的最基礎的樣式:
/** * 列基礎樣式 * 開啟相對定位,作為列中內容絕對定位的參考點 * width 為 100% * 左右有半個槽寬的外邊距 */ %grid-column { position: relative; width: 100%; padding-left: $gutter / 2; padding-right: $gutter / 2; }
這個樣式用于當屏幕小于對應斷點的時候,列的樣式進行退化
$infix: breakpoint-infix($breakpoint, $breakpoints); // .col-*-i 系列設置基礎樣式 @if $columns > 0 { @for $i from 1 through $columns { .col#{$infix}-#{$i} { @extend %grid-column; } } } // .col-*, -col-*-auto 系列設置列基礎樣式 .col#{$infix}, .col#{$infix}-auto { @extend %grid-column; }
我們這里以 $breakpoint: sm
為例,則 $infix: '-sm'
。變量 $colums: 12
是默認的一行可以分為多少列.
執行完之后, .col-sm, .col-sm-#{$i}(i 取值 1-12), .col-sm-auto
它們的默認樣式都設置成了 %grid-column
。退化的基本樣式就設置好了。
之后就開始設置媒體查詢,以確定不同的列的樣式。
因為此時的例子 $breakpoint: sm
, 所以接下來的內容都會被編譯進 @media(min-width: 576px)
中:
等寬列樣式設置
即 flex:1 1 0; max-width: 100%
。列可以等比例放大等比例縮小。初始行可用空間計算值是整個 main size
。(如果不理解,可以去搜索 flex-basis: 0 代表什么含義)。這樣的話,無論 .row
下放置多少個 .col-sm
,每個 .col-sm
的寬度都是相等的。(前提是列能容納得了內容)
.col-sm { flex-basis: 0; flex-grow: 1; max-width: 100%; }
.row-cols#{$infix}-#{$i}
這個是 bootstrap 的特色類,這個類應用在 row
上。約束其下最多可以擁有多少個等寬列.這個類對于其他的列是不影響的,僅僅影響等寬列。(是通過選擇器優先級實現的)
// 設置 .row-cols-*-i 系列 的樣式 @if $grid-row-columns > 0 { @for $i from 1 through $grid-row-columns { .row-cols-sm-#{$i} { @include row-cols($i); } } }
輔助 mixin row-cols
/** * 設置 .row-col-*-i 系列下的列樣式 * flex: 0 0 100% / $count,即是一個不會放大不會縮小,永遠按 i 的值等比例平分行的列 * * @param $count 要平分的列數 */ @mixin row-cols($count) { & > * { flex: 0 0 100% / $count; max-width: 100% / $count; } }
即 .row-cols-sm-1 > *
的選擇器特殊性和 .col-sm
相同。但是前者聲明在后者后面,所以造成了樣式覆蓋。即 .row-cols#{$infix}-#{$i}
只對等寬列起效。
嚴格的說,當使用對應斷點的 .row-cols-#{$breakpoint}-#{$i}
之后,會對其下列中 .col-#{$breakpoint}
及斷點之前的等寬列生效。即 .row-cols-md-4
會對 .col, .col-sm, .col-md
都生效。原因是因為整個循環順序是從 xs -> xl
。如果不明白,看一下編譯輸出的 CSS 就知道為什么了。
可變寬度彈性列樣式設置 .col-sm-auto
// 設置 .col-*-auto 的樣式 .col-sm-auto { @include make-col-auto(); }
輔助 mixin make-col-auto
/** * 設置 .col-*-auto 的樣式 * 默認情況下是一個不會放大不會縮小,寬度由 flex item 寬度決定的盒子 */ @mixin make-col-auto() { flex: 0 0 auto; width: auto; max-width: 100%; }
設置比例列樣式 .col-sm-#{$i}
// 設置 .col-*-i 系列的樣式 @if $columns > 0 { @for $i from 1 through $columns { .col-sm-#{$i} { @include make-col($i, $columns); } } }
輔助 mixin make-col
/** * .col-*-i 的樣式 * * @param $size 占據的列數 * @param $columns: 總可用列數 */ @mixin make-col($size, $columns: $grid-columns) { flex: 0 0 percentage($size / $columns); max-width: percentage($size / $columns); }
這里就是按比例分配,如果 $i: 5
, 則 .col-sm-5
就占據整行寬度的 5/12
。
flex 布局中使用 order
屬性來視覺排序 flex item.所以 bootstrap 也提供了列排序的類
// 列排序相關 .order-sm-first { order: -1; } .order-sm-last { order: $columns + 1; } // 一行最多12列,也就是說從 -1 開始編號就可以安排完整行所有的列排列順序 @for $i from 0 through $columns { .order-sm-#{$i} { order: $i; } }
只要明白瀏覽器視覺排序是按照 order
數值從小到大排序就能了解這個是干嘛的了。
列偏移
實際需求中,總是會有列偏移的需求,這里是通過 margin-left
實現。
// 設置列偏移 @if $columns > 0 { @for $i from 0 through ($columns - 1) { @if not ($infix == '' and $i == 0) { .offset#{$infix}-#{$i} { @include make-col-offset($i, $columns); } } } }
輔助 mixin make-col-offset
:
@mixin make-col-offset($size, $columns: $grid-columns) { $num: $size / $columns; margin-left: if($num == 0, 0, percentage($num)); }
整個創建響應式列的流程就是這樣,這里只是舉了斷點為 sm
的情況,其他斷點也是這個流程。就不一一贅述了,實際上實現也是通過循環。如果不需要響應式,只是需要等寬列,可變寬度彈性列,比例列的話就更簡單了,我相信如果能理解上面的內容的話以讀者的聰明才智可以很容易自己寫出來。
槽(gutter) 是兩列之間的間距。槽的數量是列數量 - 1.
槽公式: 設柵格行寬度為 w, 列寬度為 c(這里的列寬指內容區域), 槽寬度為 g, 列數為 n 則 w = n * c + (n - 1) * g
bootstarp 的設計是這樣的:
container
container 上左右分別有 1/2 gutter
的 padding
row
row 上設置了 -1/2 gutter
的左右外邊距將容器的 padding
影響抹平
column
colum 上設置了 1/2 gutter
的左右外邊距使得內容距離容器的邊界有了 1/2 gutter
的距離。使得內容不貼邊。
同時允許列嵌套行,因為行的負外邊距會將列的左右 padding 影響清除,可以達到無限套娃的目的。
總之這個 gutter 的 大小因不同的設計而異, bootstrap 的默認 gutter 寬度為 30px
,讀者可以根據自己的設計目的調整。
關于使用BootStrap怎么實現柵格布局就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。