当前位置:编程学习 > html/css >>

基于Web标准的UI组件 — 菜单(2)

答案:基于Web标准的UI组件 — 菜单(2)
UI Components Based on Web Standards - Menu (2)

  在本文的第一篇中,我们了解了一个“完美”的菜单应该具备的可用性和易用性特征,并且创建了基本的XHTML和CSS代码。接下来我们将深入到与菜单相关的一些高级特性的实现技术上,首先是——

指示当前活动菜单项

  当用户点击某菜单项进入网站相应的栏目,我们通常会希望这个菜单项表现出与其它菜单项不同的视觉特征,使用户明确地了解自己所处的“地点”而不至于在站点中迷路。我一直想不好应该是给这个菜单项一个什么样的名字,暂且称为“当前活动菜单项(Currently Active Menu Item)”吧,如果你有什么好想法请一定在右边留言告诉我,谢谢^_^。

  当前活动菜单项对创建良好的用户体验具有非常重要的作用,一个负责任的UI设计师是绝对不会忽视它的。实现的方法至少有两种:“直接指示”与“自上而下的指示”。

  “直接指示”的方法即直接给当前活动菜单项相对应的li元素一个适当的class属性,再在CSS中为这个class重载一般菜单项的视觉属性,使它表现出“独特”的视觉特征。说得挺悬忽,做起来很简单,我们还是用apache.org的菜单为例,并假设已经点击“DB”项进入了相应的栏目:

<li class="active"> <a href=>

  XHTML只要做这么一点小小的改进就可以了,CSS的改动也不大,只要增加这么一段:

menu li.active a{ background-color:#E8F3FF; border:1px solid #05F; }

  查看效果(例9)

  “自上而下的指示”并不直接在某个菜单项上指明它特殊的身份,而是先给每个菜单项命名,再在菜单项的“上级(比如body元素)”处指明哪个菜单项被选中了(颇有些类似皇帝翻牌选择当晚“临幸”的妃子^_^)。

  我们拿上篇文章中使用”绝对定位”的那个菜单为例,假设“软件”项被选中:

<body class="chlSoftware">
<menu>
<li id="miMovie"><a href=><li id="miMusic"><a href=><li id="miSoftware"><a href=></menu>
</body>

  body元素的class设置了当前页面所处的频道(栏目),也就是此处chl前缀的意思——Channel。根据这个class就可以设置“临幸”的规矩了……-_-|||

body.chlMovie li#miMovie a, body.chlMusic li#Music a, body.chlSoftware li#miSoftware a{ background-color:#E8F3FF; border:1px solid #05F; }

  查看效果(例10)

  可能的情况下我建议使用第二种方式,理由如下:

  1. 写后台程序的时候比较方便,只需判断当前所处的栏目给body设置class即可(怎么判断?那可不是我的事儿....);
  2. 扩展性好,不仅可用于指示当前活动菜单项,也可以给页面上的其他元素提供当前状态的信息。比如你想让每个栏目有不一样的主色调,知道怎么办了吧^_^;
  3. 当皇帝比较爽……
带图标的菜单项

  做到现在我们的菜单还都是光秃秃的,某些朋友可能已经对Web标准技术在视觉效果上能走多远产生怀疑。下面我们就把图片引入到菜单的制作中,先从最简单的讲起——给菜单项加个图标“”。我们以例9的菜单为基础,对a元素的样式做些小修改:

menu a{
/*定义a为块级元素,方便用盒模型属性定义外观*/ display:block;
/*定义尺寸*/ width:100%; height:20px;
/*盒模型风格*/ background-color:#F6F6F6; border:1px solid #DDD;
/*文字样式*/ font:11px arial; text-decoration:none;
/*垂直居中*/ line-height:20px;
/*水平居中*/ text-align:center;
/*文字缩进*/ text-indent:20px;
/*图标*/ background:#F6F6F6 url(i/arrow.gif) 5% 50% no-repeat; }

  查看效果(例11)

  这里有三点需要说明一下:

  1. 去除文字水平居中后菜单项的文字都紧贴左侧排列,我们需要给图标留出一定的空间。常用的方法(也是最容易想到的方法),就是使用padding-left。但这样会面临IE的盒模型Bug,虽然解决起来也很方便,但总不如用text-indent来得自然,更何况这样没有任何的Bug需要处理。
  2. 为什么不把图标直接用img标签插入到XHTML文档中?因为这些图标仅仅是装饰作用,它们并不是这个网页真正的“内容”,所以它们出现在XHTML代码中是不合适的。另外用背景图的方式处理也更方便更节约网络流量。反过来说,如果这个图标是一个logo,比如Apache HTTP Server那支著名的羽毛,建议你把它加入到XHTML代码中(别忘了alt属性),因为它是这个网页真正想要表达的“内容”。
  3. 关于如何正确设置背景图,我这里就不多说了,请参考小雨的《CSS2.0中文手册》中background部分。需要注意的是Opera对背景图定位有一些怪脾气,请参考我的另一篇文章
背景图翻转技术

  这又是一个很实用的技术。当我们对简单的盒模型风格不满意的时候,自然会想到使用背景图来创建更有个性的菜单项,实现的方法也很简单,我们还是在例9的基础上做修改。

  先看看两张背景图的效果:

  普通状态(bk01.gif):
   鼠标覆盖(bk02.gif):

  CSS的改动也不大,我就拣重要的讲(开始偷懒了……^_^):

menu a:link,menu a:visited{ background:transparent url(i/bk01.gif) 0 0 no-repeat; }
menu a:hover,menu a:active{ background:transparent url(i/bk02.gif) 0 0 no-repeat; }

  查看效果(例12)

  Yes,就这么简单,只要给a元素的四种状态设置相应的背景图就可以了。这种办法足以应付各种古里古怪的菜单,而且不光可以用在菜单上,任何需要模样古怪的链接的地方都可以用上它。不过这还不是最完美的方法,还有更棒的。

  我们先把两张背景图合成一张(bk03.gif):

  

  再修改CSS(这里只列出修改了的部分):

menu a{ ... background:transparent url(i/bk03.gif) 0 0 no-repeat; }
menu a:link,menu a:visited{ background:transparent url(i/bk01.gif) 0 0 no-repeat; }
menu a:hover,menu a:active{ background:transparent url(i/bk02.gif) 0 0 no-repeat; background-position:0 -21px; }

  查看效果(例13)

  看明白了吗?事实上只用了一张图,当鼠标覆盖事件产生后把图的位置向上移动了一段距离,刚好露出下半张图的红色背景部分。这样做有什么好处吗?

  1. 方便管理背景图。一个大型网站很可能需要使用几十上百张背景图,把相关的背景图合在一起可以极大地方便管理和维护。
  2. 与桌面软件皮肤的制作方式更接近。制定中的CSS3已经引入桌面软件皮肤制作中最基本的“九宫格”技术,由此网页UI设计已经明显地呈现出向桌面软件UI设计靠拢的趋势。
  3. 节约网络流量。以上面这个例子为例,小的背景图0.47K,合并后的背景图0.94K。两张小图的体积之和也是0.94K,这有什么节约的?我们知道数据是以“IP包”的形式在网络上传输。大部分的IP包都在1K左右,比如我的网站服务器收发的每个IP包大小为1024字节。每张图至少需要一个IP包传输,这么一来两张小图就占用了2K的流量,而使用一张大图只需要1K的流量。对于中小型网站这点流量的出入并不算什么,但对于日访问量上千万的网站来说,“能省则省”并不仅仅是网络流量的问题,而是实实在在的经济

上一个:基于Web标准的UI组件 — 菜单(1)
下一个:CSS的优化&技巧

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,