深入新版BS4源碼 探索flex和工程化sass奧秘

你可能已經(jīng)聽(tīng)說(shuō)了一個(gè)“大新聞”:Bootstrap4 合并了代號(hào)為#21389的PR某抓,宣布放棄支持IE9迄损,并默認(rèn)使用flexbox彈性盒模型布局坑质。
這標(biāo)志著:
1)前端開(kāi)發(fā)全面步入“現(xiàn)代瀏覽器”的時(shí)代進(jìn)一步來(lái)臨患雇;
2)樣式處理也再一次面向未來(lái)妈经,擁抱更加靈活的彈性盒模型-Flex布局淮野。

這篇文章會(huì)帶你深入Bootstrap最新版源碼,窺探其架構(gòu)組織奧秘吹泡,并解析最具亮點(diǎn)的柵格化系統(tǒng)骤星。
同時(shí),你也會(huì)了解到sass的高階用法和flex最新語(yǔ)法的奧秘爆哑。

BS4的新特性

在開(kāi)啟我們的探索之前洞难,有必要先梳理一下BS4添加的新特性:
1)從Less遷移到Sass:
現(xiàn)在,Bootstrap已加入Sass的大家庭中揭朝。得益于Libsass(Sass 解析器)队贱,Bootstrap的編譯速度比以前更快;

2)改進(jìn)網(wǎng)格系統(tǒng):
新增一個(gè)網(wǎng)格層適配移動(dòng)設(shè)備潭袱,并整頓語(yǔ)義混合柱嫌。

3)默認(rèn)彈性盒模型(flexbox):
這是項(xiàng)劃時(shí)代的變動(dòng),利用flexbox的優(yōu)勢(shì)快速布局屯换。

4)廢棄了wells编丘、thumbnails和panels,使用cards代替彤悔。

5)新的自定義選項(xiàng):
不再像上個(gè)版本一樣嘉抓,將漸變、淡入淡出晕窑、陰影等效果分放在單獨(dú)的樣式表中抑片。而是將所有選項(xiàng)都移到一個(gè)Sass變量中。

6)使用rem和em單位杨赤。

7)重構(gòu)所有JavaScript插件:
Bootstrap 4用ES6重寫(xiě)了所有插件〕ㄕ現(xiàn)在提供UMD支持、泛型拆解方法望拖、選項(xiàng)類型檢查等特性渺尘。

8)改進(jìn)工具提示和popovers自動(dòng)定位:
這部分要感謝Tether(A positioning engine to make overlays, tooltips and dropdowns better)工具的幫助,
如果你還不知道Tether是什么说敏,可以去他家Github地址了解一下鸥跟,源碼也短小精悍,值得一讀。

BS4柵格系統(tǒng)揭秘

了解了以上新特性医咨,我們主要研究BS從誕生以來(lái)最大的“賣點(diǎn)” — 柵格系統(tǒng)枫匾。

一個(gè)柵格實(shí)例

我們選取代表性的BS4官網(wǎng)范例,可以在線參考, 或者參看以下截圖拟淮,
在寬屏幕下干茉,我們看到:

寬屏幕狀態(tài)下

當(dāng)屏幕寬度小于576px時(shí)候,我們有:

iphone5屏幕下

對(duì)應(yīng)代碼:

<div class="col-6 col-sm-3">
    ...
</div>
<div class="col-6 col-sm-3">
    ...
</div>
<div class="col-6 col-sm-3">
    ...
</div>
<div class="col-6 col-sm-3">
    ...
</div>

.col-6 class樣式在源碼里面可以簡(jiǎn)單歸納(不完全)為:

.col-6 {
    -webkit-box-flex: 0;
    -webkit-flex: 0 0 50%;
    -ms-flex: 0 0 50%;
    flex: 0 0 50%;
    max-width: 50%;
}

.col-sm-3 class在源碼里面可以歸納為:

.col-sm-3{
    -webkit-box-flex: 0;
    -webkit-flex: 0 0 25%;
        -ms-flex: 0 0 25%;
            flex: 0 0 25%;
    max-width: 25%;
}

兩種類的共存和交替作用

我們看到很泊,代碼里設(shè)置了這兩個(gè)class進(jìn)行樣式聲明角虫,很明顯他們的樣式屬性是有沖突的,那么他們是如何做到“和平共處”交替發(fā)揮作用的呢委造?

1)在屏幕寬度大于576px時(shí)候戳鹅,我們發(fā)現(xiàn).col-sm-3并沒(méi)有起作用,這時(shí)候起作用的是.col-6昏兆。
我們?cè)谠创a里發(fā)現(xiàn).col-sm-的樣式聲明全部在@media (min-width: 576px) {...}的媒體查詢中枫虏,
這就保證了在576px寬度以上的屏幕,只有在媒體查詢之外的.col-
樣式聲明發(fā)揮了作用爬虱。

2)在屏幕寬度小于576px時(shí)候隶债,命中媒體查詢,命中.col-sm-3的樣式聲明跑筝。他的優(yōu)先級(jí)一定大于.col-6(媒體查詢優(yōu)先級(jí)高)死讹,這時(shí)候就保證了移動(dòng)端的樣式“占上風(fēng)”。

flex講解

從上面樣式代碼里看到類似flex: 0 0 25%的聲明继蜡,為了理解它回俐,我們從flex屬性入手:
flex屬性是flex-grow, flex-shrink 和 flex-basis的簡(jiǎn)寫(xiě)(類似backgroud是很多背景屬性的簡(jiǎn)寫(xiě)一樣),
它的默認(rèn)值為0 1 auto稀并。后兩個(gè)屬性可選仅颇。語(yǔ)法格式如下:

.item {
    flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

1)flex-grow:屬性定義項(xiàng)目的放大比例,默認(rèn)為0碘举。我們看到BS代碼里這個(gè)值一直為0忘瓦,即如果存在剩余空間,也不放大引颈。

2)flex-shrink:屬性定義了項(xiàng)目的縮小比例耕皮,默認(rèn)為1,即如果空間不足蝙场,該項(xiàng)目將縮小凌停。

3)flex-basis:屬性定義了在分配多余空間之前,項(xiàng)目占據(jù)的主軸空間(main size)售滤。
瀏覽器根據(jù)這個(gè)屬性罚拟,計(jì)算主軸是否有多余空間台诗。它可以設(shè)為跟width或height屬性一樣的值(比如350px),則項(xiàng)目將占據(jù)固定空間赐俗。
當(dāng)然BS4這里設(shè)置為比例值拉队,這也是響應(yīng)式自然而然實(shí)現(xiàn)的基礎(chǔ)。

SASS在BS4工程化中的偉大作用

看到此阻逮,不難明白BS4柵格是如何實(shí)現(xiàn)的粱快,但是這并不是此文的最終目的。我們可以深入更多:比如叔扼,BS4的柵格系統(tǒng)里事哭,一行一共是12欄。他的媒體查詢斷點(diǎn)又包括:xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px币励。
我們會(huì)想組織生成如此大量的CSS樣式慷蠕,不用預(yù)處理器簡(jiǎn)直是反人類的珊拼。而B(niǎo)S4卻是把sass用到了極致食呻。

參考其源碼dist/css目錄下樣式代碼,我們進(jìn)行分析:

.col-sm-*是如何生成的

我們深入其scss目錄下澎现,scss/mixins/_grid.scss文件:

@if $enable-grid-classes {
    @include make-grid-columns();
}

在enable-grid-classes變量為true的情況下(默認(rèn)為true)仅胞,調(diào)用make-grid-columns,make-grid-columns()這個(gè)mixin定義在scss/mixins/_grid-reamework.scss文件中(找的我好心累剑辫。干旧。。):

@mixin make-grid-columns($columns: $grid-columns, $gutters: $grid-gutter-widths, $breakpoints: $grid-breakpoints) {
    ...
}

這個(gè)mixin接受三個(gè)參數(shù):
1)$columns表示柵格數(shù)目妹蔽,默認(rèn)為12椎眯;
2)$gutters默認(rèn)為30
3)$breakpoints表示斷點(diǎn)設(shè)置,這是一個(gè)全局變量胳岂,為map類型编整。
這些你可以在scss/mixins/_breakpoints.scss文件中和scss/_variables.scss文件中找到。

認(rèn)識(shí)了這些參數(shù)乳丰,我們看.col-sm-具體實(shí)現(xiàn)掌测,下面代碼我已經(jīng)進(jìn)行過(guò)大范圍精簡(jiǎn),只保留col-sm-相關(guān)部分产园,并且加了注釋:

@each $breakpoint in map-keys($breakpoints) {
    // Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront.
    $infix: breakpoint-infix($breakpoint, $breakpoints);
    // Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
    // Makes the @content apply to the given breakpoint and wider.
    @include media-breakpoint-up($breakpoint, $breakpoints) {
        @for $i from 1 through $columns {
            .col#{$infix}-#{$i} {
                @include make-col($i, $columns);
            }
        }
    }
}

我們一步一步來(lái)分析:
1)@each $breakpoint in map-keys($breakpoints)汞斧,對(duì)每一個(gè)斷點(diǎn)進(jìn)行遍歷;
2)breakpoint-infix是一個(gè)函數(shù)什燕,它定義在css/mixins/_breakpoints.scss文件當(dāng)中粘勒, 返回一個(gè)帶破折號(hào)的斷點(diǎn)標(biāo)識(shí)字符串,比如這里我們關(guān)系的就是“-sm”屎即;
3)media-breakpoint-up是一個(gè)mixin:

@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
    $min: breakpoint-min($name, $breakpoints);
    @if $min {
        @media (min-width: $min) {
        @content;
    }
    } @else {
        @content;
    }
}

4)breakpoint-min又是一個(gè)函數(shù)庙睡,它返回了斷點(diǎn)的具體數(shù)值。這里是用來(lái)拼媒體查詢條件的。
5)最后最關(guān)鍵樣式的生成又使用了另外一個(gè)定義在css/mixins/_grid.scss文件當(dāng)中的mixin:

@mixin make-col($size, $columns: $grid-columns) {
    flex: 0 0 percentage($size / $columns);
    max-width: percentage($size / $columns);
}

到此為止埃撵,我們深入了Bootstrap V4的scss/目錄下的源碼赵颅,研究涉及了:
css/mixins/_grid-framework.scss文件;
css/mixins/_breakpoints.scss文件;
css/mixins/_grid.scss文件;
css/_variables.scss文件;
css/bootstrap-gris.scss文件;
......

如果你理解了這些,那么再去讀bootstrap新版源碼就不會(huì)存在任何難度暂刘。相信你也能夠在全局上饺谬,以“上帝視角”了解sass所起的作用,大型樣式框架的架構(gòu)組織谣拣。

總結(jié)

通過(guò)閱讀源碼的柵格系統(tǒng)部分募寨,我們應(yīng)該認(rèn)識(shí)到sass對(duì)于這樣大型樣式框架系統(tǒng)的重要意義:
1)css模塊化在管理組織上的靈活性;
2)復(fù)用的意義:使用了大量的mixin,function,全局變量森缠;
3)像JS一樣神奇的語(yǔ)法拔鹰,包括條件、遍歷等等等等贵涵。
同時(shí)列肢,你也應(yīng)該對(duì)flex這一神器有了更加深刻的認(rèn)識(shí)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宾茂,一起剝皮案震驚了整個(gè)濱河市瓷马,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌跨晴,老刑警劉巖欧聘,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異端盆,居然都是意外死亡怀骤,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)焕妙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蒋伦,“玉大人,你說(shuō)我怎么就攤上這事访敌×骨茫” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵寺旺,是天一觀的道長(zhǎng)爷抓。 經(jīng)常有香客問(wèn)我,道長(zhǎng)阻塑,這世上最難降的妖魔是什么蓝撇? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮陈莽,結(jié)果婚禮上渤昌,老公的妹妹穿的比我還像新娘虽抄。我一直安慰自己,他們只是感情好独柑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布迈窟。 她就那樣靜靜地躺著,像睡著了一般忌栅。 火紅的嫁衣襯著肌膚如雪车酣。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,165評(píng)論 1 299
  • 那天索绪,我揣著相機(jī)與錄音湖员,去河邊找鬼。 笑死瑞驱,一個(gè)胖子當(dāng)著我的面吹牛娘摔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播唤反,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼凳寺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了拴袭?” 一聲冷哼從身側(cè)響起读第,我...
    開(kāi)封第一講書(shū)人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拥刻,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體父泳,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡般哼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惠窄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒸眠。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖杆融,靈堂內(nèi)的尸體忽然破棺而出楞卡,到底是詐尸還是另有隱情,我是刑警寧澤脾歇,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布蒋腮,位于F島的核電站,受9級(jí)特大地震影響藕各,放射性物質(zhì)發(fā)生泄漏池摧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一激况、第九天 我趴在偏房一處隱蔽的房頂上張望作彤。 院中可真熱鬧膘魄,春花似錦、人聲如沸竭讳。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)绢慢。三九已至蹈丸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間呐芥,已是汗流浹背逻杖。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留思瘟,地道東北人荸百。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像滨攻,于是被迫代替她去往敵國(guó)和親够话。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 聲明變量 定義變量的語(yǔ)法: 在有些編程語(yǔ)言中(如光绕,JavaScript)聲明變量都是使用關(guān)鍵詞“var”開(kāi)頭女嘲,但是...
    Junting閱讀 1,470評(píng)論 0 6
  • 想想學(xué)習(xí)Sass時(shí)間也有差不多一年的光景了。在這一年來(lái)的時(shí)間中诞帐,在GitHub不斷閱讀Sass相關(guān)的源碼欣尼。也在國(guó)外...
    小豌豆書(shū)吧閱讀 7,249評(píng)論 1 24
  • Sass 是對(duì) CSS 的擴(kuò)展,讓 CSS 語(yǔ)言更強(qiáng)大停蕉、優(yōu)雅愕鼓。 它允許你使用變量、嵌套規(guī)則慧起、mixins菇晃、導(dǎo)入等眾...
    八寶君閱讀 2,012評(píng)論 0 1
  • 學(xué)習(xí)Sass(官網(wǎng):Sass)之前需要了解什么是Sass,Sass全稱:Syntactically Awesome...
    haoxilu閱讀 498評(píng)論 0 3
  • 《禮記·中庸》有言:“凡是預(yù)則立,不預(yù)則廢蚓挤。言前定則不跲磺送,事前定則不困,行前定則不疚灿意,道前定則不窮估灿。”意即凡事如果...
    上海Jimmy劉閱讀 323評(píng)論 0 1