4.7.6 响应式导航条
一个导航条默认情况下都是全屏100%显示的,所以通常都会有很多菜单,如图4-46所示。
图4-46 大于768像素的宽屏导航条
但在一些小屏幕下可能就不会显示全,通常我们需要根据屏幕尺寸自动调整,隐藏或去除一部分菜单内容,这就是我们所说的响应式设计的一部分内容,如图4-47所示。
图4-47 小于768像素的导航条
Bootstrap提供了这种功能,屏幕大小的分界点是768像素,在小于768像素的时候,所有的菜单默认会隐藏,单击右边的icon图标,所有默认的菜单就会展示出来,如图4-48所示。
图4-48 单击图标显示菜单
这种效果不是很好看,因为这里用了input输入框,并且最后两个按钮进行了右浮动。如果去除这些元素,而保持普通链接,效果就会很好看。上述效果的HTML代码如下:
- <div class="navbar navbar-default">
- <div class="navbar-header">
- <!-- .navbar-toggle样式用于toggle收缩的内容,即:nav-collapse collapse
- 样式所在的元素 -->
- <button type="button" class="navbar-toggle" data-toggle="collapse"
- data-target=".navbar-responsive-collapse ">
- <span class="sr-only">Toggle navigation</span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- <!-- 确保无论是宽屏还是窄屏,navbar-brand都会显示 -->
- <a class="navbar-brand" href="#">Brand</a>
- </div>
- <!-- 屏幕宽度小于768像素时,该div内的内容默认都会隐藏(通过单击icon-bar所在的图标,
- 可以再展开);大于768像素时默认显示 -->
- <div class="collapse navbar-collapse navbar-responsive-collapse ">
- <ul class="nav navbar-nav">
- <li class="active"><a href="#">主页</a></li>
- <li><a href="#">作品</a></li>
- <li><a href="#">图书</a></li>
- <li class="dropdown">
- <a data-toggle="dropdown" class="dropdown-toggle" href="#">
- 下拉菜单 <b class="caret"></b></a>
- <ul class="dropdown-menu">
- <li><a href="#">子菜单1</a></li>
- <li><a href="#">子菜单2</a></li>
- <!--省略菜单 -->
- </ul>
- </li>
- </ul>
- </div>
- </div>
上述示例有几个需要注意的重要知识点。
(1)Toggle图标
右上角的button图标(icon)必须包含在.navbar-toggle样式里,这是作者定下的规矩。相关源码如下:
- // 源码3763行
- .navbar-toggle { /*窄屏时,响应式按钮,用于单击展开其他菜单*/
- position: relative; /*相对定位*/
- float: right; /*右浮动*/
- padding: 9px 10px;
- margin-top: 8px;
- margin-right: 15px; /*通过3个方向的margin,保证该按钮居中显示*/
- margin-bottom: 8px;
- background-color: transparent; /*透明背景*/
- background-image: none;
- border: 1px solid transparent;
- border-radius: 4px; /*圆角设置*/
- }
- .navbar-toggle:focus {
- outline: none; /* 焦点状态时取消轮廓 */
- }
- .navbar-toggle .icon-bar { /*响应式按钮里的icon设置*/
- display: block; /*块级显示*/
- width: 22px;
- height: 2px; /*限制高度,因为一般都是显示3个*/
- border-radius: 1px; /*限制圆角*/
- }
- .navbar-toggle .icon-bar + .icon-bar {
- margin-top: 4px; /*多个icon之间的垂直间隔为4像素*/
- }
根据响应式导航的要求,浏览器在大于768像素时,该icon图标是不应该显示的。通过分析下面的代码可以看出,navbar-toggle在大于768像素的宽屏下是不显示的,这正好符合我们的期望。
- // 源码3787行
- @media (min-width: 768px) {
- .navbar-toggle { display: none; /*宽屏下,隐藏响应式按钮,因为所有菜单默认都显示*/ }
- }
(2)收缩容器
分析上述代码,可以看出在窄屏下,默认隐藏收缩的代码都在一个样式为.navbar-responsive-collapse的div里,并且该div应用了navbar-collapse和collapse两个样式。首先看一下collapse样式,默认情况下,应用collapse样式的容器会隐藏显示。源码如下:
- // 源码2354行
- .collapse {
- display: none; /*默认情况下,隐藏显示*/
- }
而对于大于768像素的宽屏,通过媒体查询语句,特殊设置其高度为auto,也就是不隐藏。源码如下:
- // 源码3677行
- @media (min-width: 768px) { /*宽屏时,折叠区域的显示设置*/
- .navbar-collapse {
- width: auto; /*不限制宽度*/
- border-top: 0;
- box-shadow: none; /*取消阴影*/
- }
- .navbar-collapse.collapse {
- display: block !important; /*块级显示*/
- height: auto !important;
- padding-bottom: 0;
- overflow: visible !important;
- }
- .navbar-collapse.in {
- overflow-y: visible; /*允许显示滚动条*/
- }
- .navbar-fixed-top .navbar-collapse,
- .navbar-static-top .navbar-collapse,
- .navbar-fixed-bottom .navbar-collapse {
- padding-right: 0; /*固定位置时,取消左右的padding值*/
- padding-left: 0;
- }
- }
再继续分析小于768像素的窄屏。由于默认情况下是隐藏的,通过单击Toggle图标,预期的结果是展开该收缩内容。那如何实现呢?通过上面的代码可以得出结果:很简单,单击以后,设置div的容器的高度height也为auto或者设置为块级显示方式就可以了。
通过单击事件检测HTML变换,JavaScript的collspase插件在单击的时候给div元素多附加了一个.in样式,也就是说默认的collapse样式和in样式组合在一起就可以展开内容了。去源码里找答案,正如我们所预期的,Bootstrap作者为这两个组合样式定义了块级显示方式。源码如下:
- // 源码2357行
- .collapse.in {
- display: block; /* 块级显示*/
- }
至此就真相大白了。
让我们来运行示例看看效果。随便单点,突然发现单击导航条里的dropdown下拉菜单菜单的时候,和宽屏的弹出行为不同,在窄屏下,直接在下面显示了同样宽度的横条。效果如图4-49所示。
图4-49 同一导航条在窄屏和宽屏下的运行效果
怎么回事?一般情况下dropdown下拉菜单是没问题的,现在为什么有问题?看看它的父元素容器有何限制?分析发现,作者在.navbar-nav样式下,又对.dropdown-menu样式进行了设置,主要目的就是让其和普通100%宽度的菜单有一样的效果,然后对内边距多设置了一点,分别是:padding: 5px 15px 5px 25px;。源码如下:
- // 源码3800行
- @media (max-width: 767px) { /*在窄屏情况下*/
- .navbar-nav .open .dropdown-menu { /*如果菜单项是个下拉菜单,对下拉菜单里的子菜单进行设置*/
- position: static;
- float: none; /*取消浮动*/
- width: auto; /*宽度自适应定*/
- margin-top: 0; /*取消上外边距*/
- background-color: transparent; /*背景透明*/
- border: 0; /*取消边框*/
- box-shadow: none; /*取消阴影*/
- }
- .navbar-nav .open .dropdown-menu > li > a,
- .navbar-nav .open .dropdown-menu .dropdown-header {
- padding: 5px 15px 5px 25px; /*设置子菜单项或者菜单项标题的内边距*/
- }
- .navbar-nav .open .dropdown-menu > li > a {
- line-height: 20px; /*设置行距*/
- }
- .navbar-nav .open .dropdown-menu > li > a:hover,
- .navbar-nav .open .dropdown-menu > li > a:focus {
- background-image: none;
- }
- }
而且在.navbar-default样式风格下,对下拉菜单的子菜单项的鼠标行为和颜色也都进行了相关的调整。具体源码如下:
- // 源码3999行
- @media (max-width: 767px) {
- .navbar-default .navbar-nav .open .dropdown-menu > li > a {
- color: #777; /*下拉菜单打开时,其里面的子菜单项链接的文本颜色*/
- }
- .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
- .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
- color: #333; /*下拉菜单打开时,其里面的子菜单项链接的文本颜色(移动或焦点时)*/
- background-color: transparent;
- }
- .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
- .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
- .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
- color: #555; ; /*下拉菜单打开时,其里面的当前活动的子菜单项链接的文本颜色*/
- background-color: #e7e7e7;
- }
- .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
- .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
- .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
- color: #ccc; /*下拉菜单打开时,其里面的当前已禁用的子菜单项链接的文本颜色*/
- background-color: transparent;
- }
- }
这也就是我们在上边看到,在两种尺寸下下拉菜单显示不同效果的原因了。
注意
示例HTML里的toggle按钮上的data-target的设置为.navbar-responsive-collapse,而不是先前我们用的#或者元素#+id选择器。它的意思是使用样式进行定位,即查找父容器下的子元素,如果有navbar-responsive-collapse样式就进行toggle,也就是我们所说的默认隐藏收缩的div容器。可以回头检查一下,该div上应用了navbar-responsive-collapse样式。