4.7.6 响应式导航条

一个导航条默认情况下都是全屏100%显示的,所以通常都会有很多菜单,如图4-46所示。

4.7.6 响应式导航条 - 图1 图4-46 大于768像素的宽屏导航条

但在一些小屏幕下可能就不会显示全,通常我们需要根据屏幕尺寸自动调整,隐藏或去除一部分菜单内容,这就是我们所说的响应式设计的一部分内容,如图4-47所示。

4.7.6 响应式导航条 - 图2 图4-47 小于768像素的导航条

Bootstrap提供了这种功能,屏幕大小的分界点是768像素,在小于768像素的时候,所有的菜单默认会隐藏,单击右边的icon图标,所有默认的菜单就会展示出来,如图4-48所示。

4.7.6 响应式导航条 - 图3 图4-48 单击图标显示菜单

这种效果不是很好看,因为这里用了input输入框,并且最后两个按钮进行了右浮动。如果去除这些元素,而保持普通链接,效果就会很好看。上述效果的HTML代码如下:

  1. <div class="navbar navbar-default">
  2. <div class="navbar-header">
  3. <!-- .navbar-toggle样式用于toggle收缩的内容,即:nav-collapse collapse
  4. 样式所在的元素 -->
  5. <button type="button" class="navbar-toggle" data-toggle="collapse"
  6. data-target=".navbar-responsive-collapse ">
  7. <span class="sr-only">Toggle navigation</span>
  8. <span class="icon-bar"></span>
  9. <span class="icon-bar"></span>
  10. <span class="icon-bar"></span>
  11. </button>
  12. <!-- 确保无论是宽屏还是窄屏,navbar-brand都会显示 -->
  13. <a class="navbar-brand" href="#">Brand</a>
  14. </div>
  15. <!-- 屏幕宽度小于768像素时,该div内的内容默认都会隐藏(通过单击icon-bar所在的图标,
  16. 可以再展开);大于768像素时默认显示 -->
  17. <div class="collapse navbar-collapse navbar-responsive-collapse ">
  18. <ul class="nav navbar-nav">
  19. <li class="active"><a href="#">主页</a></li>
  20. <li><a href="#">作品</a></li>
  21. <li><a href="#">图书</a></li>
  22. <li class="dropdown">
  23. <a data-toggle="dropdown" class="dropdown-toggle" href="#">
  24. 下拉菜单 <b class="caret"></b></a>
  25. <ul class="dropdown-menu">
  26. <li><a href="#">子菜单1</a></li>
  27. <li><a href="#">子菜单2</a></li>
  28. <!--省略菜单 -->
  29. </ul>
  30. </li>
  31. </ul>
  32. </div>
  33. </div>

上述示例有几个需要注意的重要知识点。

(1)Toggle图标

右上角的button图标(icon)必须包含在.navbar-toggle样式里,这是作者定下的规矩。相关源码如下:

  1. // 源码3763行
  2. .navbar-toggle { /*窄屏时,响应式按钮,用于单击展开其他菜单*/
  3. position: relative; /*相对定位*/
  4. float: right; /*右浮动*/
  5. padding: 9px 10px;
  6. margin-top: 8px;
  7. margin-right: 15px; /*通过3个方向的margin,保证该按钮居中显示*/
  8. margin-bottom: 8px;
  9. background-color: transparent; /*透明背景*/
  10. background-image: none;
  11. border: 1px solid transparent;
  12. border-radius: 4px; /*圆角设置*/
  13. }
  14. .navbar-toggle:focus {
  15. outline: none; /* 焦点状态时取消轮廓 */
  16. }
  17. .navbar-toggle .icon-bar { /*响应式按钮里的icon设置*/
  18. display: block; /*块级显示*/
  19. width: 22px;
  20. height: 2px; /*限制高度,因为一般都是显示3个*/
  21. border-radius: 1px; /*限制圆角*/
  22. }
  23. .navbar-toggle .icon-bar + .icon-bar {
  24. margin-top: 4px; /*多个icon之间的垂直间隔为4像素*/
  25. }

根据响应式导航的要求,浏览器在大于768像素时,该icon图标是不应该显示的。通过分析下面的代码可以看出,navbar-toggle在大于768像素的宽屏下是不显示的,这正好符合我们的期望。

  1. // 源码3787行
  2. @media (min-width: 768px) {
  3. .navbar-toggle { display: none; /*宽屏下,隐藏响应式按钮,因为所有菜单默认都显示*/ }
  4. }

(2)收缩容器

分析上述代码,可以看出在窄屏下,默认隐藏收缩的代码都在一个样式为.navbar-responsive-collapse的div里,并且该div应用了navbar-collapse和collapse两个样式。首先看一下collapse样式,默认情况下,应用collapse样式的容器会隐藏显示。源码如下:

  1. // 源码2354行
  2. .collapse {
  3. display: none; /*默认情况下,隐藏显示*/
  4. }

而对于大于768像素的宽屏,通过媒体查询语句,特殊设置其高度为auto,也就是不隐藏。源码如下:

  1. // 源码3677行
  2. @media (min-width: 768px) { /*宽屏时,折叠区域的显示设置*/
  3. .navbar-collapse {
  4. width: auto; /*不限制宽度*/
  5. border-top: 0;
  6. box-shadow: none; /*取消阴影*/
  7. }
  8. .navbar-collapse.collapse {
  9. display: block !important; /*块级显示*/
  10. height: auto !important;
  11. padding-bottom: 0;
  12. overflow: visible !important;
  13. }
  14. .navbar-collapse.in {
  15. overflow-y: visible; /*允许显示滚动条*/
  16. }
  17. .navbar-fixed-top .navbar-collapse,
  18. .navbar-static-top .navbar-collapse,
  19. .navbar-fixed-bottom .navbar-collapse {
  20. padding-right: 0; /*固定位置时,取消左右的padding值*/
  21. padding-left: 0;
  22. }
  23. }

再继续分析小于768像素的窄屏。由于默认情况下是隐藏的,通过单击Toggle图标,预期的结果是展开该收缩内容。那如何实现呢?通过上面的代码可以得出结果:很简单,单击以后,设置div的容器的高度height也为auto或者设置为块级显示方式就可以了。

通过单击事件检测HTML变换,JavaScript的collspase插件在单击的时候给div元素多附加了一个.in样式,也就是说默认的collapse样式和in样式组合在一起就可以展开内容了。去源码里找答案,正如我们所预期的,Bootstrap作者为这两个组合样式定义了块级显示方式。源码如下:

  1. // 源码2357行
  2. .collapse.in {
  3. display: block; /* 块级显示*/
  4. }

至此就真相大白了。

让我们来运行示例看看效果。随便单点,突然发现单击导航条里的dropdown下拉菜单菜单的时候,和宽屏的弹出行为不同,在窄屏下,直接在下面显示了同样宽度的横条。效果如图4-49所示。

4.7.6 响应式导航条 - 图4 图4-49 同一导航条在窄屏和宽屏下的运行效果

怎么回事?一般情况下dropdown下拉菜单是没问题的,现在为什么有问题?看看它的父元素容器有何限制?分析发现,作者在.navbar-nav样式下,又对.dropdown-menu样式进行了设置,主要目的就是让其和普通100%宽度的菜单有一样的效果,然后对内边距多设置了一点,分别是:padding: 5px 15px 5px 25px;。源码如下:

  1. // 源码3800行
  2. @media (max-width: 767px) { /*在窄屏情况下*/
  3. .navbar-nav .open .dropdown-menu { /*如果菜单项是个下拉菜单,对下拉菜单里的子菜单进行设置*/
  4. position: static;
  5. float: none; /*取消浮动*/
  6. width: auto; /*宽度自适应定*/
  7. margin-top: 0; /*取消上外边距*/
  8. background-color: transparent; /*背景透明*/
  9. border: 0; /*取消边框*/
  10. box-shadow: none; /*取消阴影*/
  11. }
  12. .navbar-nav .open .dropdown-menu > li > a,
  13. .navbar-nav .open .dropdown-menu .dropdown-header {
  14. padding: 5px 15px 5px 25px; /*设置子菜单项或者菜单项标题的内边距*/
  15. }
  16. .navbar-nav .open .dropdown-menu > li > a {
  17. line-height: 20px; /*设置行距*/
  18. }
  19. .navbar-nav .open .dropdown-menu > li > a:hover,
  20. .navbar-nav .open .dropdown-menu > li > a:focus {
  21. background-image: none;
  22. }
  23. }

而且在.navbar-default样式风格下,对下拉菜单的子菜单项的鼠标行为和颜色也都进行了相关的调整。具体源码如下:

  1. // 源码3999行
  2. @media (max-width: 767px) {
  3. .navbar-default .navbar-nav .open .dropdown-menu > li > a {
  4. color: #777; /*下拉菜单打开时,其里面的子菜单项链接的文本颜色*/
  5. }
  6. .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
  7. .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
  8. color: #333; /*下拉菜单打开时,其里面的子菜单项链接的文本颜色(移动或焦点时)*/
  9. background-color: transparent;
  10. }
  11. .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
  12. .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
  13. .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
  14. color: #555; ; /*下拉菜单打开时,其里面的当前活动的子菜单项链接的文本颜色*/
  15. background-color: #e7e7e7;
  16. }
  17. .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
  18. .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
  19. .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
  20. color: #ccc; /*下拉菜单打开时,其里面的当前已禁用的子菜单项链接的文本颜色*/
  21. background-color: transparent;
  22. }
  23. }

这也就是我们在上边看到,在两种尺寸下下拉菜单显示不同效果的原因了。

注意

示例HTML里的toggle按钮上的data-target的设置为.navbar-responsive-collapse,而不是先前我们用的#或者元素#+id选择器。它的意思是使用样式进行定位,即查找父容器下的子元素,如果有navbar-responsive-collapse样式就进行toggle,也就是我们所说的默认隐藏收缩的div容器。可以回头检查一下,该div上应用了navbar-responsive-collapse样式。