目的:

  • 用Bootstrap Navbar component 实现一个响应式导航
  • 理解Bootstrap Navbar component是如何工作的(不包括collepse.js)
  • 清楚自己添加一个规定的类名时是做了些什么
  • 根据自己的需求进行改装
  • 对比自己的实现方法,找出差距。

1.实现:

我想要模仿一个这样的响应式导航:

按照Bootstrap官网上介绍的方法,按照规则创建标签添加类名之后,可以得到一个这样的导航:

代码:

  1. <nav class="navbar navbar-default">
  2. <div class="container">
  3. <div class="navbar-header">
  4. <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
  5. <span class="sr-only">Toggle navigation</span>
  6. <span class="icon-bar"></span>
  7. <span class="icon-bar"></span>
  8. <span class="icon-bar"></span>
  9. </button>
  10. <a class="navbar-brand">Live With It</a>
  11. </div>
  12. <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
  13. <ul class="nav navbar-nav navbar-right">
  14. <li class="active"><a href="#">Home</a></li>
  15. <li><a href="#">Portfolio</a></li>
  16. <li><a href="#">Contact</a></li>
  17. </ul>
  18. </div>
  19. </div>
  20. </nav>

2.实现原理:

从他的源码中扒出和nav navbar相关的代码,挑出和位置相关的:

  1. @media (min-width: 768px) {
  2. .navbar-header {
  3. float: left;
  4. }
  5. }
  6. .navbar-brand {
  7. float: left;
  8. }
  9. @media (min-width: 768px) {
  10. .navbar-nav {
  11. float: left;
  12. }
  13. .navbar-nav > li {
  14. float: left;
  15. }
  16. }

两个关键的盒子,navbar-header和navbar-nav

默认是小屏幕,他们的状态是:

大屏幕时,navbar-header左浮动,navbar-nav和里面的li也都左浮动,像下面这样:

所以,他实现的原理就是,利用块级元素在文档流中占满一行,浮动之后挤到一起的特性,来控制堆叠和并排。

所以,为了可以在变成大屏幕时这两个盒子可以顺利地到一行上去,也就是说不要出现下面的情况,需要控制navbar-header和navbar-nav里面元素的总宽度不要超过768px。

再挑出和隐藏于出现相关的样式:

  1. @media (min-width: 768px) {
  2. .navbar-toggle {
  3. display: none;
  4. }
  5. }
  6. .collapse {
  7. display: none;
  8. }
  9. @media (min-width: 768px) {
  10. .navbar-collapse.collapse {
  11. display: block !important;
  12. height: auto !important;
  13. overflow: visible !important;
  14. }
  15. }
  1. navbar-collapse是控制导航列表隐藏和出现的盒子,按钮会在变成大屏后消失。
  2.  
  3. 3.弄清楚每个类名添加的样式
    .navbar 负责定义一个长条
  1. .navbar {
  2. position: relative;
  3. min-height: 50px;
  4. margin-bottom: 20px;
  5. border: 1px solid transparent;
  6. }
  7. @media (min-width: 768px) {
  8. .navbar {
  9. border-radius: 4px;
  10. }
  11. }

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

  1. @media (min-width: 768px) {
  2. .navbar-header {
  3. float: left;
  4. }
  5. }
  6. .container > .navbar-header,
  7. .container-fluid > .navbar-header {
  8. margin-right: -15px; //小屏幕的时候header内容左边缘和container左边缘对齐
  9. margin-left: -15px;
  10. }
  11. @media (min-width: 768px) {
  12. .container > .navbar-header,
  13. .container-fluid > .navbar-header {
  14. margin-right:;
  15. margin-left:;
  16. }
  17. }

.navbar-brand, 负责左边logo区的默认样式

  1. .navbar-brand {
  2. float: left;
  3. height: 50px;
  4. padding: 15px 15px;
  5. font-size: 18px;
  6. line-height: 20px;
  7. }
  8. .navbar-brand:hover,
  9. .navbar-brand:focus {
  10. text-decoration: none;
  11. }
  12. .navbar-brand > img {
  13. display: block;
  14. }
  15. @media (min-width: 768px) {
  16. .navbar > .container .navbar-brand,
  17. .navbar > .container-fluid .navbar-brand {
  18. margin-left: -15px; /*大屏幕的时候内容左边缘和header左边缘对齐*/
  19. }
  20. }

container和navbar-brand都在左右两边设置了15px的内填充,所以container、header、brand三个盒子左边线本该是这样的:

小屏幕的时候,header左右两边各有一个负边距,所以是这样的状态:

大屏幕的时候,brand左边有一个负边距:

.nav 负责定义成垂直导航的样式

  1. .nav {
  2. padding-left:;
  3. margin-bottom:;
  4. list-style: none;
  5. }
  6. .nav > li {
  7. position: relative;
  8. display: block;
  9. }
  10. .nav > li > a {
  11. position: relative;
  12. display: block;
  13. padding: 10px 15px;
  14. }
  15. .nav > li > a:hover,
  16. .nav > li > a:focus {
  17. text-decoration: none;
  18. background-color: #eee;
  19. }
navbar-nav:负责竖版导航的填充、实现横版导航。
  1. .navbar-nav {
  2. margin: 7.5px -15px; /*折叠之后添加一个上下边距,每一行都和屏幕等宽*/
  3. }
  4. .navbar-nav > li > a {
  5. padding-top: 10px;
  6. padding-bottom: 10px;
  7. line-height: 20px;
  8. }
  9. @media (min-width: 768px) {
  10. .navbar-nav {
  11. float: left;
  12. margin:;
  13. }
  14. .navbar-nav > li {
  15. float: left;
  16. }
  17. .navbar-nav > li > a {
  18. padding-top: 15px;
  19. padding-bottom: 15px;
  20. }
  21. }

navbar-right,navbar-left :负责定位

  1. @media (min-width: 768px) {
  2. .navbar-left {
  3. float: left !important;
  4. }
  5. .navbar-right {
  6. float: right !important;
  7. margin-right: -15px; //第一个添加navbar-right的元素右边会有一个负边距
  8. }
  9. .navbar-right ~ .navbar-right { //之后的都不会有
  10. margin-right:;
  11. }
  12. }

navbar-toggle:负责定义按钮的样式,里面用三个盒子绘制三条线。在大屏幕时消失。

  1. .navbar-toggle {
  2. position: relative;
  3. float: right;
  4. padding: 9px 10px;
  5. margin-top: 8px;
  6. margin-right: 15px;
  7. margin-bottom: 8px;
  8. background-color: transparent;
  9. background-image: none;
  10. border: 1px solid transparent;
  11. border-radius: 4px;
  12. }
  13. .navbar-toggle:focus {
  14. outline:;
  15. }
  16. @media (min-width: 768px) {
  17. .navbar-toggle {
  18. display: none;
  19. }
  20. }
  21. .navbar-toggle .icon-bar {
  22. display: block;
  23. width: 22px;
  24. height: 2px;
  25. border-radius: 1px;
  26. }
  27. .navbar-toggle .icon-bar + .icon-bar {
  28. margin-top: 4px;
  29. }

collapse,负责控制显示和隐藏

  1. .collapse {
  2. display: none;
  3. }
  4. @media (min-width: 768px) {
  5. .navbar-collapse.collapse {
  6. display: block !important;
  7. height: auto !important;
  8. padding-bottom:;
  9. overflow: visible !important;
  10. }
  11. }

.navbar-collapse: 负责被折叠盒子的样式

  1. .navbar-collapse {
  2. padding-right: 15px;
  3. padding-left: 15px;
  4. overflow-x: visible;
  5. -webkit-overflow-scrolling: touch;
  6. border-top: 1px solid transparent;
  7. -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
  8. box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
  9. }
  10. .container > .navbar-collapse,
  11. .container-fluid > .navbar-collapse {
  12. margin-right: -15px;
  13. margin-left: -15px;
  14. }
  15. @media (min-width: 768px) {
  16. .navbar-collapse {
  17. width: auto;
  18. border-top:;
  19. -webkit-box-shadow: none;
  20. box-shadow: none;
  21. }
  22. }
  23. @media (min-width: 768px) {
  24. .container > .navbar-collapse,
  25. .container-fluid > .navbar-collapse {
  26. margin-right:;
  27. margin-left:;
  28. }
  29. }

以上这些类负责的样式是除了颜色之外的样式,与颜色相关的一切都由.navbar-default负责。

4.改装

现在的导航条是这个样子的:

和我想要的还有一些差异,不过知道了它的实现方式,就可以进行想要的改动。

首先让小屏幕的时候导航列表也是水平显示,并且与屏幕两边有一定距离:

  1. .navbar-nav {
  2. text-align:center;
  3. }
  4. .nav li {
  5. display:inline-block;
  6. }
  7. .navbar {
  8. border:;
  9. }
  10. .navbar .navbar-header {
  11. padding-top:10px;
  12. padding-bottom:10px;
  13. }
  14. @media(min-width:768px){
  15. .navbar-collapse {
  16. padding-top:10px;
  17. padding-bottom:10px;
  18. }
  19. }
  20. .navbar-brand {
  21. font-size: 34px;
  22. font-family: Lobster, Monospace;
  23. }
  24. .nav {
  25. font-size: 20px;
  26. }
  27. @media(max-width:768px){
  28. .container .navbar-collapse {
  29. margin-left: 12px;
  30. margin-right: 12px;
  31. }
  32. }

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

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

  1. @media(min-width:768px){
  2. .navbar {
  3. background-color: #F79C9C;
  4. }
  5. }
  6. .navbar-girl .navbar-header,
  7. .navbar-girl .navbar-collapse {
  8. background-color: #F79C9C;
  9. }
  10. .navbar-girl .navbar-brand {
  11. color: #FFF;
  12. }
  13. .navbar-girl .navbar-text {
  14. color: #F7846B;
  15. }
  16. .navbar-girl .navbar-nav > li > a {
  17. color: #F7846B;
  18. }
  19. .navbar-girl .navbar-nav > li > a:hover,
  20. .navbar-girl .navbar-nav > li > a:focus {
  21. color: #CEE6E6;
  22. background-color: transparent;
  23. }
  24. .navbar-girl .navbar-nav > .active > a,
  25. .navbar-girl .navbar-nav > .active > a:hover,
  26. .navbar-girl .navbar-nav > .active > a:focus {
  27. color: #F7846B;
  28. background-color: #FFF;
  29. }
  30. .navbar-girl .navbar-toggle {
  31. border-color: #FFF;
  32. }
  33. .navbar-girl .navbar-toggle:hover,
  34. .navbar-girl .navbar-toggle:focus {
  35. background-color: #CEE6E6;
  36. }
  37. .navbar-girl .navbar-toggle .icon-bar {
  38. background-color: #FFF;
  39. }
  40. .navbar-girl .navbar-collapse {
  41. border-color: #FFF;
  42. }

大功告成啦。

5.反思

之前用自己的思路实现了一个响应式导航:CSS3media queries+jQuery实现响应式导航

和Bootstrap的思想对比之后,发现自己的一些问题

①定位:

我的思路是通过position:absolute来控制导航列表的位置。这样有一个明显的缺点,导航列表已经完全脱离普通流。

我这样思考的根源是,我没有抓住这个变化的本质,当我看到两个相同的东西在不同情况下出现在不同地方的时候,(也就是从一个地方换到另一个地方),我首先想到的就是直接挪过去,即利用absolute定位。

而Bootstrap看到了这个变化的本质,让一些块级元素由堆叠排列变成水平排列(或者相反),这样的变化通过利用块级元素的特点和浮动就可以实现。

②出发点:

Bootstrap的中心思想是:mobile first,先把在小屏幕上的布局实现,然后再做一些改变来实现在大屏幕上的布局。

而我的思想是:每一个布局和样式都考虑到这两种情况,对比一下看哪种情况方便就用哪个。所以我的代码中会出现@media(min-width:768px)和@media(max-width:768px)两种条件,对于一个设计我可能默认大屏幕的,小屏幕的用media,另一个设计我可能就会默认小屏幕的,大屏幕的用media。

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

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

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

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

  1.  

Bootstrap Navbar应用及源码解析的更多相关文章

  1. 转载:Bootstrap 源码解析

    Bootstrap 源码解析 前言 Bootstrap 是个CSS库,简单,高效.很多都可以忘记了再去网站查.但是有一些核心的东西需要弄懂.个人认为弄懂了这些应该就算是会了.源码看一波. 栅格系统 所 ...

  2. 实战录 | Kafka-0.10 Consumer源码解析

    <实战录>导语 前方高能!请注意本期攻城狮幽默细胞爆表,坐地铁的拉好把手,喝水的就建议暂时先别喝了:)本期分享人为云端卫士大数据工程师韩宝君,将带来Kafka-0.10 Consumer源 ...

  3. Netty5客户端源码解析

    Netty5客户端源码解析 今天来分析下netty5的客户端源码,示例代码如下: import io.netty.bootstrap.Bootstrap; import io.netty.channe ...

  4. Netty5服务端源码解析

    Netty5源码解析 今天让我来总结下netty5的服务端代码. 服务端(ServerBootstrap) 示例代码如下: import io.netty.bootstrap.ServerBootst ...

  5. 【原创】angularjs1.3.0源码解析之执行流程

    Angular执行流程 前言 发现最近angularjs在我厂的应用变得很广泛,下周刚好也有个angular项目要着手开始做,所以先做了下功课,从源代码开始入手会更深刻点,可能讲的没那么细,侧重点在于 ...

  6. dubbo源码解析-spi(一)

    前言 虽然标题是dubbo源码解析,但是本篇并不会出现dubbo的源码,本篇和之前的dubbo源码解析-简单原理.与spring融合一样,为dubbo源码解析专题的知识预热篇. 插播面试题 你是否了解 ...

  7. normalize.css源码解析

    什么是normalize.css?  它是为了帮助我们统一各个浏览器的样式和消除bug的css库. 为什么需要normalize.css,有什么好处? 不像一些reset.css,normalize. ...

  8. Laravel源码解析--看看Lumen到底比Laravel轻在哪里

    在前面一篇<Laravel源码解析--Laravel生命周期详解>中我们利用xdebug详细了解了下Laravel一次请求中到底做了哪些处理.今天我们跟 Lumen 对比下,看看 Lume ...

  9. 渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(下)

    关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/12/es-code03/ 前提 上篇文章写完了 ES 流程启动的一部分,main 方法都入 ...

随机推荐

  1. jGestures: jQuery的手势事件插件

    官网地址:http://jgestures.codeplex.com/文档版本号: v0.7,由neuedigitale编辑,2012年5月8日最新稳定版: jGestures v0.90 - sha ...

  2. 字节流与数据类型的相互转换---使用struct模块

    字节流与数据类型的相互转换---使用struct模块 http://blog.csdn.net/Sunboy_2050/article/details/5974029 Python是一门非常简洁的语言 ...

  3. SDOI 2016 游戏

    树链剖分 线段树维护区间最小值,区间最大值 更新,对于每一个区间,找到当前区间的最小值的最大值,和要更新的值比较,如果比最大值还大,则此数对于以后的询问无任何贡献,直接返回即可,若有贡献,则一直递归到 ...

  4. 简单的ATM取款过程

    一个简单的ATM的取款过程是这样的:首先提示用户输入密码(pwd),最多只能输3次,超过三次则提示用户“密码已输入三次错误,请取卡.“结束交易.如果用户密码正确,在提示用户输入金额(money),AT ...

  5. 参加MVP OpenDay 和2015 MVP Community Camp社区大课堂

    微软MVP Openday 1月30日在北京召开,到时全国上百位 MVP 专家将齐聚北京.当然还有亚太的其他国家地区的MVP 也会来北京,1月31日微软 MVP 项目组主办的年度微软技术社区分享大会- ...

  6. C#获取本机可用端口

    当我们要创建一个Tcp/UDP Server connection ,我们需要一个范围在1000到65535之间的端口 .但是本机一个端口只能一个程序监听,所以我们进行本地监听的时候需要检测端口是否被 ...

  7. c#处理空白字符

    空白字符是指在屏幕不会显示出来的字符(如空格,制表符tab,回车换行等).空格.制表符.换行符.回车.换页垂直制表符和换行符称为 “空白字符”,因为它们为与间距单词和行在打印的页 )的用途可以读取更加 ...

  8. PHP是怎么运行的

    这篇文章,研究一下PHP代码是如何解释和执行以及PHP脚本运行的生命周期. 概述 PHP服务的启动.严格来说,PHP的相关进程是不需要手动启动的,它是随着Apache的启动而运行的.当然,如果有需要重 ...

  9. [.net 面向对象程序设计进阶] (27) 团队开发利器(六)分布式版本控制系统Git——在Visual Studio 2015中使用Git

    [.net 面向对象程序设计进阶] (26) 团队开发利器(六)分布式版本控制系统Git——在Visual Studio 2015中使用Git 本篇导读: 接上两篇,继续Git之旅 分布式版本控制系统 ...

  10. [.net 面向对象程序设计进阶] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化

    [.net 面向对象程序设计进阶] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化 本节导读: 介绍JSON的结构,在JS中的使用.重点说明JSON如何在.N ...