本文所引用的版本爲Bootstrap 4 Beta版,閱讀者請先下載好相關源文件。css
時光荏苒,若後續版本代碼發生變化,將看心情進行更新補充。若是你以爲本文不錯,歡迎評論支持,如需轉載請標明做者及出處,謝謝。前端
在平常使用Bootstrap的時候,咱們最多見的作法是給HTML內的元素添加上預設的類名,這種方法直觀且易於調試。可是對於一個前端潔癖患者來講,在HTML標籤內添加一大堆類名簡直和內聯style同樣讓人深惡痛絕。那麼在這種時候,學會使用Bootstrap的Scss,利用其內置的函數和
@mixin
來對你本身命名的類進行樣式添加就成了一件很棒很酷的事。bootstrap
@mixin:架構
@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) { // Common properties for all breakpoints %grid-column { position: relative; width: 100%; min-height: 1px; // Prevent columns from collapsing when empty padding-right: ($gutter / 2); padding-left: ($gutter / 2); } @each $breakpoint in map-keys($breakpoints) { $infix: breakpoint-infix($breakpoint, $breakpoints); @for $i from 1 through $columns { .col#{$infix}-#{$i} { @extend %grid-column; } } .col#{$infix}, .col#{$infix}-auto { @extend %grid-column; } @include media-breakpoint-up($breakpoint, $breakpoints) { .col#{$infix} { flex-basis: 0; flex-grow: 1; max-width: 100%; } .col#{$infix}-auto { flex: 0 0 auto; width: auto; max-width: none; // Reset earlier grid tiers } @for $i from 1 through $columns { .col#{$infix}-#{$i} { @include make-col($i, $columns); } } @for $i from 1 through $columns { .order#{$infix}-#{$i} { order: $i; } } } } }
整個文件只有一個@mixin make-grid-columns()
,這個@mixin
纔是真正的搭建12列Grid網格系統的核心,讓咱們細細來拆解。框架
首先是參數,引入了列數($columns
)、列間距($gutter
)、斷點列表($breakpoints
)。這三者都已經預設好了,不須要操心。ide
%grid-column { position: relative; width: 100%; min-height: 1px; padding-right: ($gutter / 2); padding-left: ($gutter / 2); }
下面是佔位符%grid-column
,這個在以前講make-col-ready()
時已經講過了,出於減少css體積的考慮,佔位符在這裏顯然優於@mixin
。那麼這裏定義的就是一個列的基本屬性,而min-height
的設置也是考慮到當列爲空時不至於坍縮。函數
@each $breakpoint in map-keys($breakpoints) {}
接下來是一個大循環,這個循環的根本目的在於爲不一樣的斷點加上相匹配的類,它的循環依據就是斷點名。佈局
$infix: breakpoint-infix($breakpoint, $breakpoints);
讓咱們以「md
」爲例進入這個循環,首先是$infix
變量,結合先前的知識,咱們瞭解到,這個$infix
的值將是」-md
」,讓咱們記住它,接下來,又是一個小循環。學習
@for $i from 1 through $columns { .col#{$infix}-#{$i} { @extend %grid-column; } }
這個@for
循環的目的,就是爲了建立12列的基本屬性,由於全部的列都具有%grid-column
定義的基本屬性,因此咱們將這份共性總結出來,單獨設置一個循環進行類名構建,當這個循環結束,你就能夠看到css裏出現了用逗號相連的col-md-1
一直到col-md-12
flex
.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, { position: relative; width: 100%; min-height: 1px; padding-right: 15px; padding-left: 15px; }
它們都有着一樣的屬性,這也是@extend
的好處。可是請注意,咱們並無設置這些列的寬度,因此它們如今仍是不可用的狀態。
.col#{$infix}, .col#{$infix}-auto { @extend %grid-column; }
接下來有一個單獨的小傢伙,經過它,你能夠發現.col-md
這個類也出現了,也是一樣的屬性,這個咱們就先不去管它了。
@include media-breakpoint-up($breakpoint, $breakpoints) {}
接下拉就是大頭了,咱們引入了media-brakpoint-up()
函數,拿到了media查詢的外包裝
@media (min-width:768px){}
花括號裏就是咱們要往這個外包裝裏塞的內容了。
.col#{$infix} { flex-basis: 0; flex-grow: 1; max-width: 100%; }
首先是一個小傢伙,又是這貨,它單獨給col-md
定義了一些flex
屬性,它的意思代表,當「.col-md
」出現的時候,它將撐滿整行剩餘的空間。
.col#{$infix}-auto { flex: 0 0 auto; width: auto; max-width: none; }
接下來定義了「.col-md-auto
」類,這個類挺奇葩,寬度隨着內容走,跟列寬毛關係都沒有。
@for $i from 1 through $columns { .col#{$infix}-#{$i} { @include make-col($i, $columns); } }
接下來的@for
循環就開始定義咱們的列寬了,利用make-col()
,咱們獲得了從col-md-1
到col-md-12
各類不一樣的列寬。
@for $i from 1 through $columns { .order#{$infix}-#{$i} { order: $i; } }
最後的這個@for
循環也是從1到12遍歷一次,熟悉flex
的同窗會知道,添加的這個order
屬性就至關於名次,數值越小越靠前,而在flex
佈局下的12列Grid也正是依靠這一點來對不一樣的列進行排序的。
至此,「
md
」下的12列Grid框架構建完成。依次類推,其它的斷點列也都是如今生成的。比較特殊的仍是斷點」xs
」,因爲先前提到的緣由,最小的那一部分是沒有前綴的,因此你在css裏看到的.col-[1-12]
就能夠視做.col-xs-[1-12]
,這須要適應一下。
自動化構建其它諸如」.container
」之類的元素,那個$enable-grid-classes
布爾值,在變量裏的第126行,默認爲ture
。
$enable-grid-classes: true !default;
換句話說,若是你哪天心情很差,不想用bootstrap的網格系統了,直接把這裏改爲false
就行。
@if $enable-grid-classes { .row { @include make-row(); } .no-gutters { margin-right: 0; margin-left: 0; > .col, > [class*="col-"] { padding-right: 0; padding-left: 0; } } }
在這裏面有一個新定義的類「.no-gutter
」,它這個嵌入式展開後是「.no-gutter>col
,.no-gutter>[class*=」col-」]
」,從結構能夠看出來,它就是加在row
元素上的,能夠取消列的默認間距。
說回咱們的Grid,咱們知道,若是不加以控制,那麼Bootstrap在編譯Scss的時候會自動生成全部斷點下的列,若是你不打算給每一個等級都用上一種佈局,那麼自動編譯的Scss將會產生大量冗餘的css代碼。
.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col, .col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm, .col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md, .col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg, .col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl, .col-xl-auto
好比我只想作桌面端和手機端兩種適配,那麼我可能只須要lg
和sm
的列,css中其它的列代碼對我是沒用的。因此面對這種狀況,咱們就須要對Bootstrap進行修改。這裏提供兩種化用方式,若是你有其它的主意,也歡迎在評論區留言。
$grid-breakpoints: ( xs: 0, sm: 576px, md: 768px, //lg: 992px, //xl: 1200px ) !default; $container-max-widths: ( sm: 540px, md: 720px, //lg: 960px, //xl: 1140px ) !default;
這是一種很簡單的方式,也很直觀,我須要什麼列就用什麼列,不須要的我就給扔掉,可是注意,別扔掉默認值爲0的xs
。若是你不是前端潔癖患者,只是想縮減css體積,那麼推薦用這種方式。
@mixin
,替換掉默認的循環建立行爲第一種方式有一個問題,即雖然你註釋掉了不須要的列,但仍須要在HTML中寫入預設的類名。若是你不但願在HTML中寫入一堆以」col-
」開頭的類名,那麼就嘗試本身定義一個@mixin
,來建立本身的列吧。
建立以前注意,在bootstrap-grid.scss
中將@import 「grid」
註釋掉,我們不須要自動建立。
其次,新建一個scss文件,引入bootstrap-grid
。
@import "bootstrap-grid" %grid-column{ position: relative; width: 100%; min-height: 1px; padding-left: ($grid-gutter-width/2); padding-right: ($grid-gutter-width/2); } @mixin make-my-col($breakpoint:null,$size:null,$breakpoints: $grid-breakpoints){ @extend %grid-column; @include media-breakpoint-up($breakpoint,$breakpoints){ @include make-col($size,$grid-columns); } }
在這裏我提供一個自定義的@mixin
,名字也很簡單make-my-col
。包含兩個參數,一個是$breakpoint
(斷點名),一個是$size
(列寬)。這個@mixin
實際上是make-grid-columns()
的簡化版。
具體原理不用多說了,由於是自用,因此我就沒去考慮參數驗證的問題。若是你有這方面的需求,要應用到項目中,能夠考慮加上參數驗證。
調用也很簡單,在你須要的類中直接調用便可,傳入斷點名和列寬,就能建立在對應視寬下的列了。
@import "bootstrap-grid"; .side{ @include make-my-col(sm,2); @include make-my-col(md,6); } .content{ @include make-my-col(sm,10); @include make-my-col(md,6); }
P.S.寫的時候注意順序,要按照升序排列,小的放在上面,即sm在md上面,寫反了md將失效。
這種方式一樣有一個問題,在小型項目中,這樣編譯出的css能顯著縮減css的體積。但在大型項目中,各類類名交錯混雜,利用這種建立單個列的方式,最後生成的css代碼不見得比bootstrap預約義的類名更好,因此請規範命名,一些容器元素最好保持固定寬度和固定變化。
Scss顯然是利用Bootstrap更高效的方式,根據需求,以上兩種方式可任選其一。固然,若是你有其它的利用方式,也能夠爲所欲爲地蹂♂躪Bootstrap~
「好的代碼像一首詩」
之前對這句話只以爲莫名高大上,卻沒有多少感觸。而在閱讀了Bootstrap用Scss寫的源碼以後,倒是真切地感覺到了這一點。打開變量(_variables.scss
)文件的時候,帶給個人震驚是不可言表的。嚴謹而有序,體量龐大而層次井然。這些模塊若是一個個看下來,相信會獲益良多。因此若是你和我同樣,是Scss的初學者,那麼瀏覽一下Bootstrap的源碼,絕對會爽翻。
Grid應該是Bootstrap的核心區塊了,從這裏入手雖然比較難,可是方便從根本上了解Bootstrap的運行方式。
總的來講,Beta版本的Bootstrap4相比於Alpha版本已經往前邁了一大步,告別了傳統盒模型的佈局方式,轉身擁抱flexbox
,同時刪去了不少之前的殘餘代碼,在初期,習慣使用b3的同窗可能會以爲不大適應,具體表現是
「哎?我寫了這個類咋沒反應啊?」
眼下這個時候,官方說明文檔都不見得會同步更新,看源代碼纔是最直接的閱讀學習方式。
Grid篇到此結束,謝謝閱讀,歡迎指出本文的錯漏之處,前端新手上路,請多指教。