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-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:;
margin-left:;
}
}
.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:;
margin-bottom:;
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 {
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:;
}
.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:;
}
}
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:;
}
@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:;
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:;
-webkit-box-shadow: none;
box-shadow: none;
}
}
@media (min-width: 768px) {
.container > .navbar-collapse,
.container-fluid > .navbar-collapse {
margin-right:;
margin-left:;
}
}
以上这些类负责的样式是除了颜色之外的样式,与颜色相关的一切都由.navbar-default负责。
4.改装
现在的导航条是这个样子的:

和我想要的还有一些差异,不过知道了它的实现方式,就可以进行想要的改动。
首先让小屏幕的时候导航列表也是水平显示,并且与屏幕两边有一定距离:
.navbar-nav {
text-align:center;
}
.nav li {
display:inline-block;
}
.navbar {
border:;
}
.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。
这样做可以减少一些重复的不必要的代码。但是缺点远远大于优点:
①对于写的人来说,如果逻辑清晰的话,写的会很顺畅。如果思维稍微有点混乱的话,就会把自己绕进去。
②对于看的人来说,理解起来会很别扭。
③如果过段时间想改一个小样式,都需要重新理解一下当时的逻辑。
Bootstrap Navbar应用及源码解析的更多相关文章
- 转载:Bootstrap 源码解析
Bootstrap 源码解析 前言 Bootstrap 是个CSS库,简单,高效.很多都可以忘记了再去网站查.但是有一些核心的东西需要弄懂.个人认为弄懂了这些应该就算是会了.源码看一波. 栅格系统 所 ...
- 实战录 | Kafka-0.10 Consumer源码解析
<实战录>导语 前方高能!请注意本期攻城狮幽默细胞爆表,坐地铁的拉好把手,喝水的就建议暂时先别喝了:)本期分享人为云端卫士大数据工程师韩宝君,将带来Kafka-0.10 Consumer源 ...
- Netty5客户端源码解析
Netty5客户端源码解析 今天来分析下netty5的客户端源码,示例代码如下: import io.netty.bootstrap.Bootstrap; import io.netty.channe ...
- Netty5服务端源码解析
Netty5源码解析 今天让我来总结下netty5的服务端代码. 服务端(ServerBootstrap) 示例代码如下: import io.netty.bootstrap.ServerBootst ...
- 【原创】angularjs1.3.0源码解析之执行流程
Angular执行流程 前言 发现最近angularjs在我厂的应用变得很广泛,下周刚好也有个angular项目要着手开始做,所以先做了下功课,从源代码开始入手会更深刻点,可能讲的没那么细,侧重点在于 ...
- dubbo源码解析-spi(一)
前言 虽然标题是dubbo源码解析,但是本篇并不会出现dubbo的源码,本篇和之前的dubbo源码解析-简单原理.与spring融合一样,为dubbo源码解析专题的知识预热篇. 插播面试题 你是否了解 ...
- normalize.css源码解析
什么是normalize.css? 它是为了帮助我们统一各个浏览器的样式和消除bug的css库. 为什么需要normalize.css,有什么好处? 不像一些reset.css,normalize. ...
- Laravel源码解析--看看Lumen到底比Laravel轻在哪里
在前面一篇<Laravel源码解析--Laravel生命周期详解>中我们利用xdebug详细了解了下Laravel一次请求中到底做了哪些处理.今天我们跟 Lumen 对比下,看看 Lume ...
- 渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(下)
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/12/es-code03/ 前提 上篇文章写完了 ES 流程启动的一部分,main 方法都入 ...
随机推荐
- DES原理
1.DES的描述 为了建立适用于计算机系统的商用密码,美国商业部的国家标准局NBS于1973年5月和1974年8月两次发布通告,向社会征求密码算法.在征得的算法中,由IBM公司提出的算法lucifer ...
- 什么情况下才要重写Objective-C中的description方法
特别注意: 千万不要在description方法中同时使用%@和self,同时使用了%@和self,代表要调用self的description方法,因此最终会导致程序陷入死循环,循环调用descrip ...
- Mac读取Andriod屏幕截图
int main(int argc, const char * argv[]) { // insert code here... string str3 = "/Users/Ethan/Do ...
- 分布式数据库中的Paxos 算法
分布式数据库中的Paxos 算法 http://baike.baidu.com/link?url=ChmfvtXRZQl7X1VmRU6ypsmZ4b4MbQX1pelw_VenRLnFpq7rMvY ...
- C#与Java对比学习:类型判断、类与接口继承、代码规范与编码习惯、常量定义
类型判断符号: C#:object a; if(a is int) { } 用 is 符号判断 Java:object a; if(a instanceof Integer) { } 用 inst ...
- Java static 的一两点使用
这篇文章是关于Java static关键字的使用,主要会介绍以下的内容: static 的概念 static的各种应用 总结 static 是什么 static 顾名思义是静态的意思.与this相对, ...
- 使用Emit把Datatable转换为对象集合(List<T>)
Emit生成动态方法部分摘自网上,但是经过修改,加入了对委托的缓存以及类结构的调整,使之调用更简洁方便.大致的思路是:要实现转换datatable到某个指定对象的集合,本质是实现转换一个datarow ...
- Uiautomator 2.0之UiDevice新增API学习小记
1. InstrumentationRegistry类 1.1. 类说明: 一个暴露的注册实例,持有instrumentation运行的进程和参数,还提供了一种简便的方法调用instrumentati ...
- 轻量级前端MVVM框架avalon - ViewModel
废话说了大几篇,我们开始来点干货了~ ViewModel的内部机制 在MVVM中,数据是核心.而jQuery则以DOM为核心. 而DOM只是HTML在JS的世界的抽象,是一个很易变的东西.因此如果业务 ...
- Effective Modern C++ 42 Specific Ways to Improve Your Use of C++11 and C++14
Item 1: Understand template type deduction. Item 2: Understand auto type deduction. Item 3: Understa ...