bootstrap_柵格系統_響應式工具_源碼分析

-----------------------------------------------------------------------------
margin 爲負css

  • ​使盒子重疊
  • ​等高 等高佈局 雙飛翼佈局
  • ​盒子往一邊 推 或者 拉

-----------------------------------------------------------------------------
bootstrap 應用層 UI 庫,出色的柵格系統,無可比擬css3

learn it 而後脫離 bootstrap 封裝本身單獨的 柵格系統git

注意: jQuery 版本問題,怪異盒子模型,以及樣式覆蓋問題!!!github

https://v3.bootcss.comweb

  • css3 媒體查詢

加了 only 之後,IE就會忽略 不支持的 媒體查詢面試

  • css2 媒體選擇器

讓 link 在 特定的 media 知足的狀況下生效npm

  • 2x 圖 , 3x 圖

使在不一樣設備完美顯示圖片的前提下,節約帶寬bootstrap

  • -webkit-min-device-pixel-ratio: 2
  • https://m.you.163.com 網易嚴選
  • 完美理想視口
  •  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

 

  • container 固定容器 : width>1200 讓 div 固定寬度 1170,居中
  • 響應式重疊: 元素另起一行的方式
  • 列偏移 margin 爲負
  • 列排序 push 或者 pull
  • 輔助類 :

情景顏色less

快速浮動工具

  • 字體圖標 :
  • <span class="glyphicon glyphicon-search" aria-hidden="true"></span>

不失真,矢量性

空間小

兼容性強

  • 導航條 消除圓角 加一個類 固定在頭部
  • 定製 變量值,設置主題顏色等等

-----------------------------------------------------------------------------
animation.css 動畫效果庫

https://daneden.github.io/animate.css

-----------------------------------------------------------------------------
bootstrap-3.3.7/

  • dist/
  • css/

bootstrap.css    必用

bootstrap.css.map    表現了 min 版本的變量對應等等

bootstrap.min.css    壓縮版

  • fonts/

幾種字體 必用

  • js/

bootstrap.js

bootstrap.min.js

npm.js

  • less/    開發進度源碼
  • mixin/

grid.less

grid-framework.less

grid.less

variables.less    變量定義

 

柵格系統 源碼分析

容器:兩邊擁有 槽寬 一半的 padding 15px

行:兩邊擁有 槽寬 一半的 margin 負15px

列:兩邊擁有 槽寬 一半的 padding 15px

 

  • 爲了維護槽寬的規則

列兩邊必須的擁有 槽寬 一半的 padding 15px

  • 爲了能距離列包裹行

行兩邊必須擁有 槽寬 一半的 margin 負15px

  • 爲了能使容器完整的包裹住行

容器兩邊必須擁有 槽寬 一半的 padding 15px

-----------------------------------------------------------------------------

variables.less

  •  @grid-columns: 12; // 列數 @grid-gutter-width: 30px; // 槽寬 @screen-sm: 768px; @screen-sm-min: @screen-sm; @screen-md: 992px; @screen-md-min: @screen-md; @screen-lg: 1200px; @screen-lg-min: @screen-lg; @screen-xs-max: (@screen-sm-min - 1); 767 @screen-sm-max: (@screen-md-min - 1); 991 @screen-md-max: (@screen-lg-min - 1); 1023

-----------------------------------------------------------------------------

grid.less    入口

  •  // 包含 container 固定容器這樣能夠直接用的類 .container { .container-fixed(); // 1. 調用一個混合 mixin // (超小屏時,寬度 auto 仍然有槽寬) @media (min-width: @screen-sm-min) { width: @container-sm; // 固定寬 750 } @media (min-width: @screen-md-min) { width: @container-md; // 固定寬 970 } @media (min-width: @screen-lg-min) { width: @container-lg; // 固定寬 1170 } } // 流體容器 .container-fluid { .container-fixed(); } .row { .make-row(); // 設置行 槽寬 的樣式 } .make-grid-columns(); // 設置列的公共樣式 // 3. 設置 特定列 的樣式 .make-grid(xs); @media (min-width: @screen-sm-min) { .make-grid(sm); } @media (min-width: @screen-md-min) { .make-grid(md); } @media (min-width: @screen-lg-min) { .make-grid(lg); }

 

-----------------------------------------------------------------------------

mixins/

grid.less

  •  // 2. 固定容器、流體容器公共樣式 .container-fixed(@gutter: @grid-gutter-width) { // 盒子水平居中 margin-right: auto; margin-left: auto; // 設置全部容器左右 padding 15 padding-left: floor((@gutter / 2)); padding-right: ceil((@gutter / 2)); // 容器自動清除浮動 繼承了 .clearfix 這個類 &:extend(.clearfix all); } .make-row(@gutter: @grid-gutter-width) { // 面試題: margin 爲負的地方 加一個padding15 又推回去15 意義在於始終讓 容器內容 間距,邊距爲15px
    margin-left
    : ceil((@gutter / -2)); margin-right: floor((@gutter / -2)); &:extend(.clearfix all); }

     

-----------------------------------------------------------------------------

grid-framework.less

  •  .make-grid-columns() { // 一個參數 .col(@index) { // ~"不編譯內容" // ~".col-xs-1, .col-sm-1, .col-md-1, .col-lg-1"; @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}"; // 再調用, 傳參 .col(2, ~".col-xs-1, .col-sm-1, .col-md-1, .col-lg-1") .col((@index + 1), @item); } // 2 < 12 因此進行調用, 遞歸調用,直到 @index = 13 .col(@index, @list) when (@index =< @grid-columns) { @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}"; .col((@index + 1), ~"@{list}, @{item}"); } // 13 12列 選擇器 .col(@index, @list) when (@index > @grid-columns) { @{list} { position: relative; // 每列都相對定位, 做爲定位父元素 min-height: 1px; // 最小高度 1px // 左右 padding 15px padding-left: ceil((@grid-gutter-width / 2)); padding-right: floor((@grid-gutter-width / 2)); } } .col(1); // 入口 } // 讓 12 列 浮動 .float-grid-columns(@class) { .col(@index) { @item: ~".col-@{class}-@{index}"; .col((@index + 1), @item); // 從 12 到 1 設置 樣式 } .col(@index, @list) when (@index =< @grid-columns) { @item: ~".col-@{class}-@{index}"; .col((@index + 1), ~"@{list}, @{item}"); } .col(@index, @list) when (@index > @grid-columns) { @{list} { float: left; // 讓 特定的列 浮動 } } .col(1); // 入口 } // 循環 設置列的樣式 // 12 啥屏幕 樣式 .loop-grid-columns(@index, @class, @type) when (@index >= 0) { .calc-grid-column(@index, @class, @type); .loop-grid-columns((@index - 1), @class, @type); } // 設置 特定列 的樣式 .make-grid(@class) { .float-grid-columns(@class); // ① 讓 12列 浮動 // xs // 12 啥屏幕 樣式 .loop-grid-columns(@grid-columns, @class, width); // ② 設置 width 的百分比 .loop-grid-columns(@grid-columns, @class, pull); // ③ pull 列排序 設置 left .loop-grid-columns(@grid-columns, @class, push); // ④ push 列排序 設置 right .loop-grid-columns(@grid-columns, @class, offset); // ⑤ 列偏移 設置 margin-left } // 12 啥屏幕 width .calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) { // .col-xs-12 { width: percentage(12/12) } // .col-xs-11 { width: percentage(11/12) } // ... ... // .col-xs-1 { width: percentage(1/12) } .col-@{class}-@{index} { width: percentage((@index / @grid-columns)); } } // pull 列排序 設置 left .calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) { // .col-xs-push-12 { left: percentage(100%) } // .col-xs-push-11 { left: percentage(11/12) } // ... ... // .col-xs-push-1 { left: percentage(1/12) } .col-@{class}-push-@{index} { left: percentage((@index / @grid-columns)); } } // pull 列排序 設置 left .calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) { // .col-xs-push-0 { left: auto } .col-@{class}-push-0 { left: auto; } } // push 列排序 設置 right .calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) { // .col-xs-pull-12 { right: percentage(100%) } // .col-xs-pull-11 { right: percentage(11/12) } // ... ... // .col-xs-pull-1 { right: percentage(1/12) } .col-@{class}-pull-@{index} { right: percentage((@index / @grid-columns)); } } // push 列排序 設置 right .calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) { // .col-xs-pull-0 { right: auto } .col-@{class}-pull-0 { right: auto; } } // 列偏移 設置 margin-left .calc-grid-column(@index, @class, @type) when (@type = offset) { // .col-xs-offset-12 { margin-left: percentage(100%) } // .col-xs-offset-11 { margin-left: percentage(11/12) } // .col-xs-offset-1 { margin-left: percentage(1/12) } // .col-xs-offset-0 { margin-left: 0 } .col-@{class}-offset-@{index} { margin-left: percentage((@index / @grid-columns)); } }

-----------------------------------------------------------------------------

響應式工具 源碼分析

responsive-utilities.less

  •  @-ms-viewport { width: device-width; } .visible-xs, .visible-sm, .visible-md, .visible-lg { .responsive-invisibility(); // 1. visible 首先所有 display: none !important; } .visible-xs-block, .visible-xs-inline, .visible-xs-inline-block, .visible-sm-block, .visible-sm-inline, .visible-sm-inline-block, .visible-md-block, .visible-md-inline, .visible-md-inline-block, .visible-lg-block, .visible-lg-inline, .visible-lg-inline-block { display: none !important; } .visible-xs { @media (max-width: @screen-xs-max) { .responsive-visibility(); // 2. visible 再顯示 } } .hidden-xs { @media (max-width: @screen-xs-max) { .responsive-invisibility(); // hidden 直接 display: none !important; } }

-----------------------------------------------------------------------------

mixins/

responsive-visibility.less

  •  .responsive-visibility() { display: block !important; // 默認 block 顯示 // 兼容性 老的表格佈局 table& { display: table !important; } tr& { display: table-row !important; } th&, td& { display: table-cell !important; } } .responsive-invisibility() { display: none !important; }

 


 

抽出 bootstrap 的柵格系統,引入項目

  • 代碼結構
  • diyGridSystem.less
  • @import "./diyGridSystem/mixins/grid";
    @import "./diyGridSystem/mixins/grid-framework";
    
    @import "./diyGridSystem/variables";
    @import "./diyGridSystem/grid";
  • grid.less
  • .container {/**** 固定容器 ****/
        .container-fixed();
    
        @media (min-width: @screen-sm-min) {
            width: @container-sm;
        }
        @media (min-width: @screen-md-min) {
            width: @container-md;
        }
        @media (min-width: @screen-lg-min) {
            width: @container-lg;
        }
    box-sizing: border-box; } .container-fluid {/**** 流體容器 ****/ .container-fixed();
    box-sizing
    : border-box; } .row {
    /**** 給 行 設置樣式 ****/ .make-row();
    box-sizing
    : border-box; } .make-grid-columns(); /**** 給 列 設置公共樣式 ****/

    /**** 給 特定列 設置樣式 ****/ .make-grid(xs); @media (min-width: @screen-sm-min) { .make-grid(sm); } @media (min-width: @screen-md-min) { .make-grid(md); } @media (min-width: @screen-lg-min) { .make-grid(lg); }
  • variables.less
  • 直接拷貝官網源碼便可
  • mixins/
  • grid.less
  • /**** 給 固定容器 設置樣式 ****/
    .container-fixed(@gutter: @grid-gutter-width) {
    /**** 居中 ****/ margin-right: auto; margin-left: auto;

    /**** 固定容器 左右 padding 15px ****/ padding-left: floor((@gutter / 2)); padding-right: ceil((@gutter / 2));

    /**** 清除浮動 ****/ .clearfix() }/**** 給 行 設置樣式 ****/ .make-row(@gutter: @grid-gutter-width) {/**** 左右拉 -15px 使 內容 始終保持邊界、間隔 爲 15px ****/ margin-left: ceil((@gutter / -2)); margin-right: floor((@gutter / -2));/**** 清除浮動 ****/ .clearfix() }/**** 定義mixin: 清除浮動 ****/ .clearfix() { &:before, &:after { content: " "; // 1 display: table; // 2 } &:after { clear: both; } }
  • grid-framework.less
  • /**** 給 12-1 列設置公共樣式 ****/
    .make-grid-columns() {
        .col(@index) {
            @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
            .col((@index + 1), @item);
        }
        
        .col(@index, @list) when (@index =< @grid-columns) {
            @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
            .col((@index + 1), ~"@{list}, @{item}");
        }
        
        .col(@index, @list) when (@index > @grid-columns) {
            @{list} {
                position: relative;    /**** 每列都開啓 相對定位 ****/
                
                /**** 最小高度爲 1 ****/
                min-height: 1px;
                
                /**** 列 左右 padding 15px ****/
                padding-left:  ceil((@grid-gutter-width / 2));
                padding-right: floor((@grid-gutter-width / 2));
                box-sizing: border-box;
            }
        }
        
        .col(1);
    }
    
    /**** 給特定列設置樣式 ****/
    .make-grid(@class) {
        .float-grid-columns(@class);    /**** 每列 開啓 左浮動 ****/
        .loop-grid-columns(@grid-columns, @class, width);    /**** 設置每列的 width ****/
        .loop-grid-columns(@grid-columns, @class, pull);    /**** 列排序: 設置每列的 left ****/
        .loop-grid-columns(@grid-columns, @class, push);    /**** 列排序: 設置每列的 right ****/
        .loop-grid-columns(@grid-columns, @class, offset);    /**** 列偏移: 設置每列的 margin-left ****/
    }
    
    /**** 循環給 每一個列 設置樣式 ****/
    .loop-grid-columns(@index, @class, @type) when (@index >= 0) {
        .calc-grid-column(@index, @class, @type);
        
        .loop-grid-columns((@index - 1), @class, @type);
    }
    
    /**** 每列 開啓 左浮動 ****/
    .float-grid-columns(@class) {
        .col(@index) {
            @item: ~".col-@{class}-@{index}";
            .col((@index + 1), @item);
        }
        
        .col(@index, @list) when (@index =< @grid-columns) {
            @item: ~".col-@{class}-@{index}";
            .col((@index + 1), ~"@{list}, @{item}");
        }
        
        .col(@index, @list) when (@index > @grid-columns) {
            @{list} {
                float: left;
            }
        }
        
        .col(1);
    }
    
    /**** 設置每列的 width ****/
    .calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {
        .col-@{class}-@{index} {
            width: percentage((@index / @grid-columns));
        }
    }
    
    /**** 列排序: 設置每列的 left ****/
    .calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {
        .col-@{class}-push-@{index} {
            left: percentage((@index / @grid-columns));
        }
    }
    
    .calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {
        .col-@{class}-push-0 {
            left: auto;
        }
    }
    
    /**** 列排序: 設置每列的 right ****/
    .calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {
        .col-@{class}-pull-@{index} {
            right: percentage((@index / @grid-columns));
        }
    }
    
    .calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {
        .col-@{class}-pull-0 {
            right: auto;
        }
    }
    
    /**** 列偏移: 設置每列的 margin-left ****/
    .calc-grid-column(@index, @class, @type) when (@type = offset) {
        .col-@{class}-offset-@{index} {
            margin-left: percentage((@index / @grid-columns));
        }
    }
相關文章
相關標籤/搜索