zoukankan      html  css  js  c++  java
  • Bootstrap Navbar应用及源码解析

    目的:

    • 用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- 768px) {
      .navbar-header {
        float: left;
      }
    }
    .navbar-brand {
      float: left;
    }
    @media (min- 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- 768px) {
      .navbar-toggle {
        display: none;
      }
    }
    .collapse {
      display: none;
    }
    @media (min- 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- 768px) {
      .navbar {
        border-radius: 4px;
      }
    }

    .navbar-header ,负责包裹brand和折叠按钮,控制小屏幕时brand和按钮的位置,控制导航列表的布局。

    @media (min- 768px) {
      .navbar-header {
        float: left;
      }
    }
    .container > .navbar-header,
    .container-fluid > .navbar-header {
      margin-right: -15px;  //小屏幕的时候header内容左边缘和container左边缘对齐
      margin-left: -15px;
    }
    @media (min- 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- 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- 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- 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- 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- 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- 768px) {
      .navbar-collapse {
        width: auto;   
        border-top: 0;
        -webkit-box-shadow: none;
                box-shadow: none;
      }
    }
    @media (min- 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-768px){
    .navbar-collapse {
      padding-top:10px;
      padding-bottom:10px;
    }
    }
    .navbar-brand {
      font-size: 34px;
      font-family: Lobster, Monospace;
    }
    .nav {
      font-size: 20px;
    }
    @media(max-768px){
      .container .navbar-collapse {
      margin-left: 12px;
      margin-right: 12px;
    }
    }

    (如果以后也会用到这种版式,也可以为他定义一个类) 

    然后定义一个新的配色方案,替换掉.navbar-default

    @media(min-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-768px)和@media(max-768px)两种条件,对于一个设计我可能默认大屏幕的,小屏幕的用media,另一个设计我可能就会默认小屏幕的,大屏幕的用media。

    这样做可以减少一些重复的不必要的代码。但是缺点远远大于优点:

    ①对于写的人来说,如果逻辑清晰的话,写的会很顺畅。如果思维稍微有点混乱的话,就会把自己绕进去。

    ②对于看的人来说,理解起来会很别扭。

    ③如果过段时间想改一个小样式,都需要重新理解一下当时的逻辑。

     
  • 相关阅读:
    linux sysfs (2)
    微软——助您启动云的力量网络虚拟盛会
    Windows Azure入门教学系列 全面更新啦!
    与Advanced Telemetry创始人兼 CTO, Tom Naylor的访谈
    Windows Azure AppFabric概述
    Windows Azure Extra Small Instances Public Beta版本发布
    DataMarket 一月内容更新
    和Steve, Wade 一起学习如何使用Windows Azure Startup Tasks
    现实世界的Windows Azure:与eCraft的 Nicklas Andersson(CTO),Peter Löfgren(项目经理)以及Jörgen Westerling(CCO)的访谈
    正确使用Windows Azure 中的VM Role
  • 原文地址:https://www.cnblogs.com/LiveWithIt/p/5925194.html
Copyright © 2011-2022 走看看