Bootstrap Navbar應用及源碼解析

https://www.cnblogs.com/LiveWithIt/p/5925194.html

目的:

  • 用Bootstrap Navbar component 實現一個響應式導航
  • 理解Bootstrap Navbar component是如何工作的(不包括collepse.js)
  • 清楚自己添加一個規定的類名時是做了些什麼
  • 根據自己的需求進行改裝
  • 對比自己的實現方法,找出差距。

1.實現:

我想要模仿一個這樣的響應式導航:

 

按照Bootstrap官網上介紹的方法,按照規則創建標籤添加類名之後,可以得到一個這樣的導航:

代碼:

複製代碼

<nav class="navbar navbar-default">
  <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand">Live With It</a>
    </div>
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav navbar-right">
        <li class="active"><a href="#">Home</a></li>
        <li><a href="#">Portfolio</a></li>
        <li><a href="#">Contact</a></li>
      </ul>
    </div>
  </div>
</nav>

複製代碼

 

2.實現原理:

從他的源碼中扒出和nav navbar相關的代碼,挑出和位置相關的:

複製代碼

@media (min-width: 768px) {
  .navbar-header {
    float: left;
  }
}
.navbar-brand {
  float: left;
}
@media (min-width: 768px) {
  .navbar-nav {
    float: left;
  }
  .navbar-nav > li {
    float: left;
  }
}

複製代碼

兩個關鍵的盒子,navbar-header和navbar-nav

默認是小屏幕,他們的狀態是:

大屏幕時,navbar-header左浮動,navbar-nav和裏面的li也都左浮動,像下面這樣:

所以,他實現的原理就是,利用塊級元素在文檔流中佔滿一行,浮動之後擠到一起的特性,來控制堆疊和並排。

所以,爲了可以在變成大屏幕時這兩個盒子可以順利地到一行上去,也就是說不要出現下面的情況,需要控制navbar-header和navbar-nav裏面元素的總寬度不要超過768px。

再挑出和隱藏於出現相關的樣式:

複製代碼

@media (min-width: 768px) {
  .navbar-toggle {
    display: none;
  }
}
.collapse {
  display: none;
}
@media (min-width: 768px) {
  .navbar-collapse.collapse {
    display: block !important;
    height: auto !important;
    overflow: visible !important;
  }
}

複製代碼

navbar-collapse是控制導航列表隱藏和出現的盒子,按鈕會在變成大屏後消失。

3.弄清楚每個類名添加的樣式
.navbar 負責定義一個長條

複製代碼

.navbar {
  position: relative;
  min-height: 50px;
  margin-bottom: 20px;
  border: 1px solid transparent;
}
@media (min-width: 768px) {
  .navbar {
    border-radius: 4px;
  }
}

複製代碼

 

.navbar-header ,負責包裹brand和摺疊按鈕,控制小屏幕時brand和按鈕的位置,控制導航列表的佈局。

複製代碼

@media (min-width: 768px) {
  .navbar-header {
    float: left;
  }
}
.container > .navbar-header,
.container-fluid > .navbar-header {
  margin-right: -15px;  //小屏幕的時候header內容左邊緣和container左邊緣對齊
  margin-left: -15px;
}
@media (min-width: 768px) {
  .container > .navbar-header,
  .container-fluid > .navbar-header {
    margin-right: 0;   
    margin-left: 0;
  }
}

複製代碼

 

.navbar-brand, 負責左邊logo區的默認樣式

複製代碼

.navbar-brand {
  float: left;
  height: 50px;
  padding: 15px 15px;
  font-size: 18px;
  line-height: 20px;
}
.navbar-brand:hover,
.navbar-brand:focus {
  text-decoration: none;
}
.navbar-brand > img {
  display: block;
}
@media (min-width: 768px) {
  .navbar > .container .navbar-brand,
  .navbar > .container-fluid .navbar-brand {
    margin-left: -15px;    /*大屏幕的時候內容左邊緣和header左邊緣對齊*/
  }
}

複製代碼

 

container和navbar-brand都在左右兩邊設置了15px的內填充,所以container、header、brand三個盒子左邊線本該是這樣的:

小屏幕的時候,header左右兩邊各有一個負邊距,所以是這樣的狀態:

大屏幕的時候,brand左邊有一個負邊距:

 

.nav 負責定義成垂直導航的樣式

複製代碼

.nav {
  padding-left: 0;
  margin-bottom: 0;
  list-style: none;
}
.nav > li {
  position: relative;
  display: block;
}
.nav > li > a {
  position: relative;
  display: block;
  padding: 10px 15px;
}
.nav > li > a:hover,
.nav > li > a:focus {
  text-decoration: none;
  background-color: #eee;
}

複製代碼

 

navbar-nav:負責豎版導航的填充、實現橫版導航。

複製代碼

.navbar-nav {
  margin: 7.5px -15px;  /*摺疊之後添加一個上下邊距,每一行都和屏幕等寬*/
}
.navbar-nav > li > a {
  padding-top: 10px;
  padding-bottom: 10px;
  line-height: 20px;
}
@media (min-width: 768px) {
  .navbar-nav {
    float: left;
    margin: 0;
  }
  .navbar-nav > li {
    float: left;
  }
  .navbar-nav > li > a {
    padding-top: 15px;
    padding-bottom: 15px;
  }
}

複製代碼

 

navbar-right,navbar-left :負責定位

複製代碼

@media (min-width: 768px) {
  .navbar-left {
    float: left !important;
  }
  .navbar-right {
    float: right !important;
    margin-right: -15px;         //第一個添加navbar-right的元素右邊會有一個負邊距
  }
  .navbar-right ~ .navbar-right {   //之後的都不會有
    margin-right: 0;
  }
}

複製代碼

 

navbar-toggle:負責定義按鈕的樣式,裏面用三個盒子繪製三條線。在大屏幕時消失。

複製代碼

.navbar-toggle {
  position: relative;
  float: right;
  padding: 9px 10px;
  margin-top: 8px;
  margin-right: 15px;
  margin-bottom: 8px;
  background-color: transparent;
  background-image: none;
  border: 1px solid transparent;
  border-radius: 4px;
}
.navbar-toggle:focus {
  outline: 0;
}
@media (min-width: 768px) {
  .navbar-toggle {
    display: none;
  }
}
.navbar-toggle .icon-bar {
  display: block;
  width: 22px;
  height: 2px;
  border-radius: 1px;
}
.navbar-toggle .icon-bar + .icon-bar {
  margin-top: 4px;
}

複製代碼

 

collapse,負責控制顯示和隱藏

複製代碼

.collapse {
  display: none;
}
@media (min-width: 768px) {
  .navbar-collapse.collapse {
    display: block !important;
    height: auto !important;
    padding-bottom: 0;
    overflow: visible !important;
  }
}

複製代碼

 

.navbar-collapse: 負責被摺疊盒子的樣式

複製代碼

.navbar-collapse {
  padding-right: 15px;
  padding-left: 15px;
  overflow-x: visible;
  -webkit-overflow-scrolling: touch;
  border-top: 1px solid transparent;
  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
}
.container > .navbar-collapse,
.container-fluid > .navbar-collapse {
  margin-right: -15px;
  margin-left: -15px;
}
@media (min-width: 768px) {
  .navbar-collapse {
    width: auto;   
    border-top: 0;
    -webkit-box-shadow: none;
            box-shadow: none;
  }
}
@media (min-width: 768px) {
  .container > .navbar-collapse,
  .container-fluid > .navbar-collapse {
    margin-right: 0;
    margin-left: 0;
  }
}

複製代碼

 

以上這些類負責的樣式是除了顏色之外的樣式,與顏色相關的一切都由.navbar-default負責。

 

4.改裝

 現在的導航條是這個樣子的:

和我想要的還有一些差異,不過知道了它的實現方式,就可以進行想要的改動。

首先讓小屏幕的時候導航列表也是水平顯示,並且與屏幕兩邊有一定距離:

複製代碼

.navbar-nav {
  text-align:center;
}
.nav li {
  display:inline-block;
}
.navbar {
  border: 0;
}
.navbar .navbar-header {
  padding-top:10px;
  padding-bottom:10px;
}
@media(min-width:768px){
.navbar-collapse {
  padding-top:10px;
  padding-bottom:10px;
}
}
.navbar-brand {
  font-size: 34px;
  font-family: Lobster, Monospace;
}
.nav {
  font-size: 20px;
}
@media(max-width:768px){
  .container .navbar-collapse {
  margin-left: 12px;
  margin-right: 12px;
}
}

複製代碼

(如果以後也會用到這種版式,也可以爲他定義一個類) 

 

然後定義一個新的配色方案,替換掉.navbar-default

複製代碼

@media(min-width:768px){
.navbar {
  background-color: #F79C9C;
}
}
.navbar-girl .navbar-header,
.navbar-girl .navbar-collapse {
   background-color: #F79C9C;
}
.navbar-girl .navbar-brand {
  color: #FFF;
}
.navbar-girl .navbar-text {
  color: #F7846B;
}
.navbar-girl .navbar-nav > li > a {
  color: #F7846B;
}
.navbar-girl .navbar-nav > li > a:hover,
.navbar-girl .navbar-nav > li > a:focus {
  color: #CEE6E6;
  background-color: transparent;
}
.navbar-girl .navbar-nav > .active > a,
.navbar-girl .navbar-nav > .active > a:hover,
.navbar-girl .navbar-nav > .active > a:focus {
  color: #F7846B;
  background-color: #FFF;
}
.navbar-girl .navbar-toggle {
  border-color: #FFF;
}
.navbar-girl .navbar-toggle:hover,
.navbar-girl .navbar-toggle:focus {
  background-color: #CEE6E6;
}
.navbar-girl .navbar-toggle .icon-bar {
  background-color: #FFF;
}
.navbar-girl .navbar-collapse {
  border-color: #FFF;
}

複製代碼

大功告成啦。

 

5.反思

之前用自己的思路實現了一個響應式導航:CSS3media queries+jQuery實現響應式導航

和Bootstrap的思想對比之後,發現自己的一些問題

①定位:

我的思路是通過position:absolute來控制導航列表的位置。這樣有一個明顯的缺點,導航列表已經完全脫離普通流。

我這樣思考的根源是,我沒有抓住這個變化的本質,當我看到兩個相同的東西在不同情況下出現在不同地方的時候,(也就是從一個地方換到另一個地方),我首先想到的就是直接挪過去,即利用absolute定位。

而Bootstrap看到了這個變化的本質,讓一些塊級元素由堆疊排列變成水平排列(或者相反),這樣的變化通過利用塊級元素的特點和浮動就可以實現。

②出發點:

Bootstrap的中心思想是:mobile first,先把在小屏幕上的佈局實現,然後再做一些改變來實現在大屏幕上的佈局。

而我的思想是:每一個佈局和樣式都考慮到這兩種情況,對比一下看哪種情況方便就用哪個。所以我的代碼中會出現@media(min-width:768px)和@media(max-width:768px)兩種條件,對於一個設計我可能默認大屏幕的,小屏幕的用media,另一個設計我可能就會默認小屏幕的,大屏幕的用media。

這樣做可以減少一些重複的不必要的代碼。但是缺點遠遠大於優點:

①對於寫的人來說,如果邏輯清晰的話,寫的會很順暢。如果思維稍微有點混亂的話,就會把自己繞進去。

②對於看的人來說,理解起來會很彆扭。

③如果過段時間想改一個小樣式,都需要重新理解一下當時的邏輯。

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章