当前位置:首页 >> 网页制作

网站导航菜单的分割线和水平居中

写这篇啰嗦的文章,缘由来自于Jorux Notebook的《什么是Semantics?》文章。

实际上,从《网站重构》一书开始在国内流行之后,Zeldman提出的语义化标记就已经在一定程度上流传开来。在抛弃table布局页面之后大家突然发现,原来这还不够,随意地使用<p>或者<div>来进行布局实际上和table布局一样的糟糕。

Jorux的例子(如下):

我是老大 | 我是不好意思说 | 老三 | 老四在这里 | 老幺

Jorux指出,在这种极为普遍的导航样式中(通常是用于网站底部的信息导航,100个网站里有90个采用这样的模式),我们应该使用无序列表,而不是下面这种:

   1:  <p>
   2:  <a href=”home.html”>首页</a> | 
   3:  <a href=”about.html”>关于</a> | 
   4:  <a href=”blog.html”>博客</a> | 
   5:  <a href=”message.html”>留言</a> | 
   6:  <a href=”album.html”>相册</a>
   7:  </p>

甚至是使用了<ul>,但是依然将修饰线条作为内容元素的写法也是五十步笑百步:

   1:  <ul>
   2:  <li><a href=”home.html”>首页</a></li>
   3:  <li>|</li>
   4:  <li><a href=”about.html”>关于</a></li>
   5:  <li>|</li>
   6:  <li><a href=”blog.html”>博客</a></li>
   7:  <li>|</li>
   8:  <li><a href=”message.html”>留言</a></li>
   9:  <li>|</li>
  10:  <li><a href=”album.html”>相册</a></li>
  11:  </ul>

遗憾的是,内容与样式分离web标准化建设的推进道路总是充满了各种各样的阻碍。即使是新浪和淘宝在它们的页面底部也存在着上述的情况。

先来看新浪的截图:

网站导航菜单的分割线和水平居中

代码(简略了内容):

   1:  <div style="padding-bottom:6px;">
   2:      <a href="">新浪简介</a> ┊ 
   3:      <a href="">About Sina</a> ┊ 
   4:      <a href="">广告服务</a> ┊ 
   5:      <a href="">联系我们</a> ┊
   6:      <a href="">诚聘英才</a>
   7:  </div>

为什么要这么做,有过网页制作经验的朋友大概会了解。网站底部的导航通常都是以比较简单的文本形式出现,居中,再附加一些修饰——大部分都是“|”和“·”或者“—”。html部分采用新浪的做法,节省了编写css的时间,最重要的是让一切水平居中显示将是非常简单的事情。只需要将<div>的text-align设置为center就万事大吉。

这里需要讨论的是,到底使用什么标记才算是语义化?

我们没有教科书,任何一本某某权威指南不会写着:你应该使用<ul>和<li>,而不是<div>和<p>来制作导航菜单。也就是说,我认为如果考虑到实际项目的操作,使用前者或后者都不是一个严重到会出现违背XHTML准则的问题。

我们来看淘宝的底部:

网站导航菜单的分割线和水平居中

在我看到,如果按照zeldman的思路,应该这样去写:

   1:  <dl>
   2:      <dt>全球阿里巴巴 - 阿里巴巴网络</dt>
   3:      <dd>
   4:          <ul>
   5:              <li>中国站</li>
   6:              <li>国际站</li>
   7:              ......
   8:          </ul>
   9:      </dd>
  10:  </dl>

但实际上,淘宝的代码是这样:

   1:  <div class="ali-group" style="width:680px;margin:5px auto;">
   2:  全球阿里巴巴 - 阿里巴巴网络:
   3:      <a href="">中国站</a>
   4:      <a href="">国际站</a>
   5:      <a href="">日文站</a> | 
   6:      <a href="">淘宝站</a> | 
   7:      <a href="">支付宝</a> | 
   8:      ......
   9:  </div>

为什么一个如此提倡标准化的UED小组所编写的淘宝代码中也有和Jorux说法相违背,不严格按照语义化标记来操作呢?

因为,这样的水平居中和添加“|”不会那么烦人。

烦人的分割线

不要小看这个“|”,加入这么一个小小的修饰线条,看似简单,实际上还是比较头痛的。

首先我们知道,这个竖线是分割线,是把一个个链接从视觉上分开的一种手段,有多种方式去实现这一个效果:

1、直接插入“|”实体,但这和用空的table来撑开空白一样,是不符合内容和样式分离准则。

2、使用border-right来给每一个链接加上一个1px宽的边框。缺点是这个边框线条的高度定义起来比较讨厌,作为行内元素的a,无法应用到上下内边距来控制高度,勉强使用行高line-height只会让你在实际应用中漏洞百出。

3、使用background来给每一个链接加上一个竖线的图片背景,这种方式在视觉效果上应用灵活,但缺点是会多制作一张图片(尽管你可以CSS Sprites或者你认为一条竖线的图片大小可以忽略不计),同样高度无法定义。

4、使用:after这样的伪类元素,如a:after { content: "|"; }。可以再添加font-size来稍稍控制高度。尽管这样的一种做法被一些css玩家所推崇,毕竟了解的人少,使它看上去比较的高深和复杂。实际上它的缺点也最多。首先,:after在版本8以下的IE中通通免谈,这就意味着大部分浏览者无法看到这样的效果。其次,看上去这一条“|”是由css来控制的样式,实际上它在html中实际生成了内容,本质上和直接在<a>之后插入一个“|”没有区别。

综上所述,我们理应抛弃第一种做法,采用2、3、4中的一种来显示这个分割线效果。然而接踵而至的问题是,不管你用了哪种方法,你都要考虑如何去除最后一个“|”分割线。让导航看上是这样:

我是老大 | 我是不好意思说 | 老三 | 老四在这里 | 老幺

而不是这样:

我是老大 | 我是不好意思说 | 老三 | 老四在这里 | 老幺 |

常用的做法是给div中的最后一个a,或者ul中的最后一个li(或者都是第一个a和li,这取决与你css中的左右位置)添加一个id或者class,例如:

   1:  <ul id="menu">
   2:      ......    
   3:      <li><a href="#">王老五</a></li>
   4:      <li class="last"><a href="#">老幺</a></li>
   5:  </ul>

然后在css添加对这个.last的单独定义,去除它的边框或者背景或者:after生成的content内容。

如此的繁琐,是不是已经开始头大了?

水平居中

从分割线的问题,我们往下讨论导航的水平居中问题。

淘宝的另一个底部导航采用了不让人头大的选择:

网站导航菜单的分割线和水平居中

在这个例子中,HTMl如下:

   1:  <ul class="foot-nav" style="width:690px;_width:695px;">
   2:      <li><a href="">关于淘宝</a></li>
   3:      <li><a href="">广告服务</a></li>
   4:      <li><a href="">合作伙伴</a></li>
   5:      <li><a href="">帮助中心</a></li>
   6:      <li><a href="">诚征英才</a></li>
   7:      <li><a href="">联系我们</a></li>
   8:      <li><a href="">网站地图</a></li>
   9:      <li><a href="">热门品牌</a></li>
  10:  </ul>

这里的采用了标准的写法,没有分割线,没有额外的id或class,没有上面讨论的烦人的各种问题。

然而这种写法意味着,如果将li的display设置block,text-align:center无法轻松的将这个导航水平放置在页面的正中,除非你给ul定义了一个宽度,在上面的代码中淘宝也的确是这样去做的。

如果,导航菜单中的项目数量不能够确定,整体的宽度势必也要成为变量——一个未知宽度。不断地去修改这个width,以确保margin: 0 auto;可以让这个导航水平居中无疑将让你的工作变得琐碎和困难。

未知宽度的水平居中

最简单的方法,就是让每一个li元素不要以block的形式float:left,以inline的方式让它们一字排开,给ul一个text-align:center就可以搞定这一切。

我做了这样一个例子,demo1。为了图省事,我没有做图,采用背景图片的方式显示分割线,而是使用了:after生成content的方法。

在css中的最后,我添加这样两行:

   1:  #menu li:before { content: "|"; padding-right: 10px; }
   2:  #menu li:first-child:before { content: ""; }

这样,在不支持:after的浏览器中,导航以最质朴的方式展现,在IE8和FF这样的浏览器中,分割线将显示出来,最后一个li的分割线将被删除。

上面的方法,在大部分时间还是比较好用的,但如果需要给导航菜单添加更多的效果控制,例如给每一个li添加一个按钮似的背景,我们就必须让li成为块级元素。这个时候,text-align:center就无效了。

好在Stu Nicholls给出了一个解决方案——Centering Float Left Menus。

我做了另一个例子,demo2。

在这样的基础之上,无论你或删或增导航菜单的项目数量,无论你是想给它添加简单背景色,还是添加复杂的圆角框,你都可以从容应对了。

上一篇: CSS first-letter伪类元素的特点
下一篇: CSS Border属性制作小三角