首页 > 代码库 > 7.1 双竖线菜单

7.1 双竖线菜单

导航是网页中不可缺少的功能,本章将制作5个风格各异的导航幕单。这些菜单单充分利用了CSS的各种特性,并且将前面介绍的各种关于盒子模型的技术要点都融入到各个案例当中。

本章将集中介绍竖直排列的菜单,第8章中将介绍水平排列的菜单,第9章中将介绍一个更为复杂的下拉菜单。需要注意的是。这些案例中都大量使用了前面章节中的CSS盒子模型以及浮动和定位的技术,因此读者务必先把前面的基础掌握好,再来学习这些实际的案例。这3章中的案例参考了英国设计师StuNicholls的设计和文章,如果读者有兴趣,可以访问他的网站
http://www.cssplay.co.uk,了解更多内容。

该实例文件位于网页学习网CSS教程资源中的“第7章\O1\vertical-border-1.htm”。

图1 双竖线菜单效果
图1 双竖线菜单效果
 

一、HTML框架

首先,从编写基本的HTML文件开始,搭建出这个菜单的基本框架.HTML代码如下。

折叠XML/HTML 代码复制内容到剪贴板
  1. <body>  
  2.     <div id="menu">  
  3.        <a href="#"> Home </a>    
  4.        <a href="#"> Contact Us</a>  
  5.        <a href="#"> Web Dev</a>    
  6.        <a href="#"> Web Design</a>    
  7.        <a href="#"> Map </a>    
  8.     </div>  
  9. </body>

可以看到,body部分非常简单,5个文字链接被放置到一个id设置为menu的div容器中。此时在浏览器中观察效果,只是最普通的文字超链接样式。

注意:由于这个div包括了所有的链接,也就是各个菜单项,因此这里将这个div称为“容器”。

二、设置容器的CSS样式

现在设置菜单div容器的整体区域样式,设置菜单的宽度、背景色,以及义字的字体和大小。在HTML文件的head部分增加CSS样式表代码如下。lodidance.com

折叠CSS 代码复制内容到剪贴板
  1. <style>   
  2.     /*对menu层设置*/  
  3.     #menu {   
  4.       font-family:Arial;   
  5.       font-size:14px;   
  6.       width:120px;       
  7.       background:#ccc;     
  8.       border:1px solid #ccc;   
  9.       }     
  10. </style>

这时效果可以看到,文字链接都被限制在了#menu容器中。

然后对菜单进行定位,在#menu部分增加如下两行代码。

折叠CSS 代码复制内容到剪贴板
  1. margin:0 auto/*设置水平居中*/  
  2. padding:8px;  /*设置内边距*/  

这时这个菜单在浏览器窗口中就水平居中显示了,并且文字和边界之间空8个像素的距离。

三、设置菜单项的CSS样式

现在就需要设置文字链接了。为了使5个文字链接依次竖直排列,需要将它们从“行内元素”变为“块级元索”。此外还应该为它们设置背景色和内边距,以使菜单文字之间不要过于局促。具体代码如下:

折叠CSS 代码复制内容到剪贴板
  1. #menu a, #menu a:visited {  /*设置菜单项样式*/  
  2.   display:block;  /*设置为块级元素*/  
  3.   background-color:#fff;  /*背景色为白色*/  
  4.   padding:4px 8px;  /*设置内边距*/  

此时效果,菜单项就有padding属性设置的内边距。

接下来设置文字的样式,取消下划线,并将文字设置为黑色.代码如下:

折叠CSS 代码复制内容到剪贴板
  1. color:#000;    
  2. text-decoration:none;  

现在参考一下前面的效果图,可以发现每个菜单项之间应该有一定的空隙,而不是现在这样连在一起。这个效果可以通过设置margin来实现,代码为:

折叠CSS 代码复制内容到剪贴板
  1. margin:8px 0;  

此外,左右两侧还各需要一条竖线,这可以通过设置左右边框来实现,代码为:

折叠CSS 代码复制内容到剪贴板
  1. border-left:8px solid #9ab;    
  2. border-right:8px solid #9ab;   

显示的效果和最前面的目标效果图1比较,虽然总体上和目标效果已经非常接近了,但是灰色背景的上下空白的宽度比左右空白的宽度要宽,而目标效果中,这个灰色的边上下左右都是一样宽的。

下面来具体分析一下目前的情况。细斜线区域是padding,粗斜线区域是margin。从这里可以看到一个现象,竖直相邻的两个菜单项之间的margin台并了,即本来每一个菜单都有自己的8个像素高的margin.由于竖直方向的两个margin相遇了,因此它们之间的margin就以高的那个margin为准,这里都是8个像素,因此最终的结果就是8个像素。

然而,由于最上面的菜单项的margin和menu容器的padding各有8个像素,加在一起就是16个像素高,从而使得上下灰边比左右的灰边要宽一些。下面我们就来解决这个问题。

四、解决出现的问题

既然问题产生的原因在于上下两端空白的高度等于容器顶部的padding加上第一个菜单项上侧的margin,就会自然想到要如何将这个多余的margin去掉。如果修改链接文本的样式,那么所有的菜单项都会受到影响,因此必须把第一个和最后一个菜单项的样式与其他菜单项的样式区别对待,才能解决问题。具体的方法如下。

① 首先将HTML文件中相关的两个链接的代码修改如下:

折叠XML/HTML 代码复制内容到剪贴板
  1. <body>  
  2.     <div id="menu">  
  3.        <a href="#" id="first"> Home </a>    
  4.        <a href="#"> Contact Us</a>  
  5.        <a href="#"> Web Dev</a>    
  6.        <a href="#"> Web Design</a>    
  7.        <a href="#" id="last"> Map </a>    
  8.     </div>  
  9. </body>

② 在第一个和最后一个链接中,分别增加一个样式类别,设为#first和#last.这里表示第一个和最后一个的意思。然后设置这两个id的样式,将它们的margin设置为0。

折叠CSS 代码复制内容到剪贴板
  1. #menu a#first#menu a#last {   
  2.   margin:0;   
  3. }

注意:由于中间的3个菜单项都设有margin,因此即使上下两个菜单项的margin为0,也不会和其他菜单项合并列一起。

③ 最后,设置鼠标指针经过效果,代码如下:

折叠CSS 代码复制内容到剪贴板
  1. #menu a:hover {   
  2.     color:#f00;    
  3.     border-left:8px solid #000;    
  4.     border-right:8px solid #000;    
  5. }

此时在Firefox中的显示效果完全正确,只要鼠标指针进入菜单项的矩形就会触发。而在IE浏览器中,只有当鼠标指针移动到文字上的时候才会触发鼠标经过效果中鼠标指针进入矩形范围时,并没有触发效果,这是IE本身的问题导致的。

解决这个问题的办法是,在“#menu a, #menu a:visited”的样式中增加下面这条CSS规则:

折叠CSS 代码复制内容到剪贴板
  1. height:1em;  

这样不会改变菜单的外观,但可以解决上面所说的问题。至此,这个案例就全部完成了。为了方便读者分析,代码整理后抄录如下:

折叠XML/HTML 代码复制内容到剪贴板
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"   
  2.        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  3. <html xmlns="http://www.w3.org/1999/xhtml">  
  4. <head>  
  5.     <title>双竖线菜单</title>  
  6.     <style>  
  7.         /*对menu层设置*/   
  8.         #menu {   
  9.           font-family:Arial;   
  10.           font-size:14px;   
  11.           width:120px;    
  12.           padding:8px;    
  13.           background:#ccc;   
  14.           margin:0 auto;   
  15.           border:1px solid #ccc;   
  16.           }   
  17.            
  18.         /*设置菜单选项*/   
  19.         #menu a, #menu a:visited {   
  20.           display:block;    
  21.           background-color:#fff;    
  22.           padding:4px 8px;   
  23.           color:#000;    
  24.           text-decoration:none;   
  25.           margin:8px 0;    
  26.           border-left:8px solid #9ab;    
  27.           border-right:8px solid #9ab;    
  28.              
  29.           }   
  30.         #menu a:hover {   
  31.           color:#f00;    
  32.           border-left:8px solid #000;    
  33.           border-right:8px solid #000;    
  34.           }   
  35.   
  36.         #menu a#first, #menu a#last {   
  37.           margin:0;   
  38.         }     
  39.   
  40.     </style>  
  41. </head>  
  42.   
  43. <body>  
  44.     <div id="menu">  
  45.        <a href="#" id="first"> Home </a>    
  46.        <a href="#"> Contact Us</a>  
  47.        <a href="#"> Web Dev</a>    
  48.        <a href="#"> Web Design</a>    
  49.        <a href="#" id="last"> Map </a>    
  50.     </div>  
  51. </body>  
  52. </html>

在这个案例中.一个重要的问题是如何在一系列相同的菜单项中,对两端的元素作特殊处理。上面使用的方法是为它们单独设置CSS类别。实际上,可以进一步考虑,其实只需要对一端的元素作特殊处理就可以了,而不必对上下两端的元素都作特殊处理。例如.可以使第一个菜单项的4个margin都为0,然后将其他4个菜单项的margin设置为“margin: 8px 0 0 0”,即只有上侧的margin为8像素,其他3个margin为0,这样只需要对第一个菜单项设置class="first"就可以了,效果是完全相同的。

事实上,W3C组织在设计CSS规范的时候,就已经替用户考虑到这个问题了,他们专门为此设汁一个伪类first-child。例如,找到下面这段代码:lodidance.com

折叠CSS 代码复制内容到剪贴板
  1. #menu a#first#menu a#last {   
  2.   margin:0;   
  3. }

修改为:

折叠CSS 代码复制内容到剪贴板
  1. #menu a:first-child{   
  2.    margin:0;   
  3. }

这里的选择器的含义就是,对在#menu这个div中的“第一个”a标记进行样式设置,这样就不用在HTML代码中单独为第一个菜单项设置特殊的类了。

注意:first-child伪类虽然是标准的CSS伪类.但是IE浏览器并不支持它。由于IE对margin和padding的处理与Firefox不同,因此在本例中使用first-child伪类的方法,同样可以满足IE和Firefox中都正确显示的要求。但是在其他情况下,如果为了保证在IE浏览器中正确显示,目前还应该使用自定义的class代替first-child伪类的方法。

请读者参考网页学习网CSS教程资源中的文件,“vertical-border-1.htm”中使用的是对首尾两个菜单项特殊处理的方法,“vertical-border-2.htm”中使用的是仅对首菜单项特殊处理的方法,“vertical-border-3.htm”中使用的是first-child伪类的方法。如果读者还有不明白的地方,请分别参考这些文件。

点击下载第1~7章CSS教程资源 返回《CSS教程布局之道》教程列表

编辑:网页学习网
本文地址:http://www.lodidance.com/css/jc/700.html