页面可用性之outline轮廓外框的一些研究

这篇文章发布于 2010年01月4日,星期一,15:57,归类于 CSS相关。 阅读 96498 次, 今日 5 次 10 条评论

 

一、重要的前言

在IE以及Firefox浏览器下,默认情况下,点击链接文字或图片(特指<a>标签下的)。会留下一个轮廓框。曾经有一段时间,我称之为链接虚框。后来,改口了,因为我发现称之为链接虚框似乎有些不准确,狭隘了点。

由于点击链接会产生轮廓框就在IE和Firefox浏览器下会出现,而这两者的变现恰好有都是虚框(dotted),所以会直接用链接虚框的表述代替链接轮廓框。事实上,链接外框不等于链接虚框,例如,chrome浏览器下,链接获取焦点是的轮廓框是羽化的实线,呈暗淡的橙色,如下:

chrome浏览器下的焦点外框

所以除非是特指点击事件,我会使用虚框一词,其余均用轮廓框或外框取而代之。

就我个人而言,对于链接点击后留下的轮廓框,我都是采取无视的态度,因为权衡来讲,对链接轮廓框大动干戈麻烦大于好处。麻烦在于代码成本,兼容性以及可用性,好处在于一定程度上去除了讨厌的点击外框,对于追求完美的设计师或页面工程师而言,心理上舒服了。但是对于用户而言呢,考虑到从众与习惯性,用户对链接外框的讨厌远不及设计师或工程师,瞧,百度,腾讯,或是新浪它们对链接外框做了处理吗?没有。大部分的用户就是在这样的环境下过来的。

然而,在互联网上,页面总是千差万别,遇到的情况也是千秋各异,所以有时候也会遇到好处大于麻烦的情况,看下面这张图:
链接外框太丑的情况

还有就是一些设计类网站,丑陋的点击虚框是完美主义的设计师们完全无法容忍的,所以他们就会对这个链接虚框下手,铲除他们。他们可能会使用a{outline:none;}a{outline:0;}(后者更消耗渲染多一点),想必浏览至此的您也知道这一点。然而,这个,或许大家习以为常,认为“没什么啊”的一个样式其实是页面可用性上一个大大的问题,a big problem!

绝大多数的用户都是通过鼠标点击打开一个链接的,所以设置a{outline:none;}去除点击时的虚框是没有问题的。然而,有一部分用户是键盘使用爱好者或是不得已键盘使用者,设置a{outline:none;}就会给他们带来麻烦。举个例子吧,我大学同寝室的涛哥,他不是什么键盘爱好者,但是他的鼠标总是时灵是不灵,换鼠标也不起作用,所以很多时间,都是使用键盘打开文件,浏览网页什么的。假设他在用Firefox3浏览器浏览我的新的首页系统,其平时浏览页面都是按TAB键在切换链接,回车打开的。谁知我这个“赖水宝”(方言,有傻逼之意)设置了a{outline:none;},结果其狂按TAB键,页面上一点反应都没有,其迷茫了,脑中冒出诸如“这个页面怎么了”“我浏览器是不是出什么岔子了”之类的问题,然后不得已关掉了此页面。……

总结此例子,一句话,设置a{outline:none;}虽然可以去除点击时留下的外框,但同时也扼杀了键盘操作focus时留下的虚框,回事键盘使用者迷茫与网页中。这也是为什么会写这篇文章的原因所在,本文讨论的就是如何点击时可以有效地去除链接外框,键盘focus时又保留链接外框。由于本文主要讨论outline,所以IE6,IE7浏览器可以继续过元旦,放假休息。

您可以狠狠地点击这里:本文CSS与outline表现测试demo页面

二、demo使用的一些说明

demo效果的查看分两类,一类是点击;二类是键盘。

点击没有什么好说的,移上去,左键一点(由于基本上都是当前页面链接,故不松开),观察有无虚框;对于键盘查看效果,值得一提:首先IE浏览器,Firefox,chrome下,直接点击TAB键就可以查看focus焦点后的效果,Opera浏览器是个怪胎,按Tab键不顶用,要使用Shift+↓和Shift+↑进行切换查看(更多Opera下快捷键点这里)。对于Safari浏览器,如果是在OS X下,需通过System Preferences(系统偏好) > Keyboard and Mouse(键盘与鼠标) > Keyboard Shortcuts(快捷键)设置打开键盘的可用性(我没有苹果机子-穷啊(5555~~),所以这里正确与否我未验证)。如果是在windows系统下,则通过编辑 > 偏好设置 > 高级,然后勾选“按住TAB键以高亮显示网页上的每一项”,步骤如下图所示:
windows开启键盘高亮显示步骤1
windows下开启Safari浏览器键盘步骤2

demo中,文字链接为普通的文字链接,第一个图片链接背景为图片,文字text-indent负值定位到浏览器之外,第二个图片链接添加一个span标签,绝对定位到浏览器可见区域之外。

三、默认的链接外框

这里没有任何outline相关的属性,结果在有些浏览器下链接外框的表现就比较挫了,例如Firefox下的虚框:
Firefox默认下的虚框

Opera浏览器下的外框:
Opera浏览器下的外框

这里外框的延伸正是由于使用了文字偏移技术产生的。为了显示的好看,有时会用图片代替按钮等,我们所见的文字有时就是图片的一部分。从搜索引擎的角度上讲,有必要在HTML中显示图片上的文字,但又不能在页面上看到,故使用文字偏移技术。常用的是text-indent定位,还有就是是绝对定位。

.indent{text-indent:-1000px;}
.absolute{position:relative;} 
.absolute span{position:absolute; left:-1000px;}

四、overflow:hidden有效解决外框延长问题

overflow:hidden可以有效解决外框延长的问题。不过,在Opera浏览器下,overflow:hidden貌似对绝对定位的文字偏移没有作用,这似乎是个bug。见下图:
Opera下overflow:hidden对外框延长无作用

五、使用outline:none去除链接外框的

outline:none可以去除链接外框,不管鼠标点的,或是键盘切换的,都没有外框,这显然是有问题的。问题不在于outline,其实outline:none本身并没有什么,只是直接挂在<a>标签下面未免太狠了点,就像是宁错杀三千不放走一人的恐怖行动,直接把键盘用户排除掉了。因为a{outline:none;}造成了IE6/7(不认识outline)以外浏览器下,不管是点击或是TAB键切换都看不到任何外框,用户根本不知道哪个链接当前在激活状态,在键盘用户眼中,这些页面就是个死页面。

a{outline:none;}

太多的设计师没有考虑到这一点了,不少CSS重置(css reset)中也对outline进行了处理,例如下面:

CSS reset之outline

上图中的设置方式其实是有问题的(此reset还比较出名),看过本文您就会知道为什么有问题,怎样设置才更合理。

六、通过:focus添加键盘切换外框

通过:focus添加键盘切换外框的想法其实是好的,既然a{outline:none;}不够仁义,株连所有的外框,那么我在后面再设置个:focus的样式,岂不就解决了键盘切换的问题了。因为键盘切换的原理就是让链接内容获取焦点(focus)的。

a{outline:none;}
a:focus{outline:thin dotted;}

然而,实际上,事情不是想的那个样子。怎么了呢?通过:focus重新引入outline会使IE8和Firefox浏览器下:active的样式重新出现。于是,在单击文字或图片链接的时候,还是会看到链接轮廓框。同时,在chrome浏览器以及Safari浏览器下,:focus{{outline:thin dotted;}替换了浏览器默认focus时的样式。Opera浏览器不是覆盖原来的focus样式,而是添加,于是会出现双边框。 见下图(前者为chrome的默认focus样式替换,后者是Opera下的双边框):

chrome下focus样式被替换
Opera下的双边框

七、再添加:active进行消除

接上面。既然:focus引出了:active的样式,所以,如果再在后面添加:active{outline:none}岂不是可以让IE8或是Firefox点击时无虚框。结果如何呢?还不错,IE8或是Firefox浏览器下点击是没有虚框了,且不影响键盘TAB键的链接切换。就是代码似乎冗余了一点,而且覆盖了Chrome和Safari浏览器下默认的蛮酷的focus样式,Opera下的双边框问题依旧存在。

a{outline:none;}
a:focus{outline:thin dotted;}
a:active{outline:none;}

好,现在我们理一理,我们可以发现,这里的逻辑有点问题,类似于负负得正。显示a{outline:none}让所有的链接外框没有了,然后又设置:focus让外框又出现,然后又设置:active让外框又消失,这其中存在消失 – 出现 – 消失的逻辑,而最后一个消失起作用了,这种情况下,最终起作用的那个消失是与前面两者是没有关系的。所以,逻辑推断,:active是解决问题的关键。到底是不是如此呢?看下面内容。

八、仅仅使用:active去掉链接外框轮廓线

这里的核心样式很简单。

a:active{outline:none;}

结果是出其的好:可以去除用户点击图片式链接时的外框线的问题,同时保留了习惯使用键盘用户在链接获得焦点时虚框可见。并且不会重置浏览器默认的focus获得焦点的样式,或是产生双边框的问题。可以说是相当完美。

下图为IE8下键盘切换focus时的样式表现:

IE8下的focus时样式

九、使用:hover做进一步的弥补

后来的一些测试表明,仅仅使用:active还有一点小小的问题,就是用户点击一个链接和这个链接指向的页面加载的过程中,链接外框依旧会出现,这其实也不难理解,链接被点中,也处于:focus状态。由于本测试页面的链接基本上都是在页面自身,所以看不到此问题。一定程度上解决此问题的方法就是添加:hoveroutline:none属性。

a:hover,a:active{outline:none;}

另外,还有一种情况下,链接外框的问题没有解决,就是当用户点击了一个链接后,再点击浏览器的后退按钮的时候,此时outline就会出现。

十、IE6/7与链接外框

虽然本文主题是outline,与IE6/7形同陌路。但是IE6/7也是有链接虚框的。有个IE的私有属性可以有效的根除IE的链接虚框,就是hidefocus="true",如果您的页面想保证较高的可用性,这玩意最好不要用,或仅用在不重要的地方。这东西,也是个狠角色,很独裁,鳌拜。会让含有此属性的链接外框完全消失,什么键盘TAB切换根本鸟都不鸟,会有a{outline:none}同样的可用性问题,貌似还会屏蔽focus事件。

<a href="#" hidefocus="true">链接</a>

十一、最后的总结

首先,应该知道为何说:focus{outline:none}是不合理的了。考虑到页面的可用性,尤其对于键盘使用者的页面可用性,一旦设置了:focus{outline:none},键盘TAB切换是,虽然事实上实在不停的切换,但是由于outline样式为none,外框没有样式,用户根本不知道当前哪个链接(或是表单控件)处于focus获得焦点的状态,也就无法再页面上进行操作,这类用户包括残疾人士,使用网页阅读器,或是鼠标出问题的用户,或是就是个键盘使用爱好者。

事实上是存在双赢的方法的,将:focus{outline:none;}改成:active{outline:none;}这样,既可以让鼠标使用者点击时去掉丑陋的外框,又保留了键盘使用者需要看到的焦点外框,确实为两全其美的方法。如果您想更近一步,可以添加:hover{outline:none;},但我个人的看法是hover就不用加了,综合估量成本和收益,貌似成本要比收益大一点,当然,这里面含有主观因素,您不必跟我意见一致。

回到开始,本文的讨论前提是是在假设你要去除链接外框,考虑到页面的可用性问题,您应该对CSS怎么做。我的经验告诉我,很多事物,往往是原始的,默认的是最好的。马化腾马老板在其内部的产品会议上也提到这一点,点击这里,其针对的是浏览器默认的控件,尤指按钮。

所以,我们要不要通过样式花代码花心思改变链接外框的样式表现呢?至少我是不会的,除了会解决下外框延伸的问题或是极少的使用了a标签的非链接,我是不会动outline动外框的,因为我觉得这是吃力不讨好的事情,不做反而清闲,都交给浏览器吧。

最后,由于文章写了一半,浏览器出岔子,很多内容丢了重写(真是火),所以内容上可能有重复,或啰嗦,或上下衔接不自然,还望见谅。还有,您在使用过程中遇到什么类似问题,或是发现本文内容的不正确之处,欢迎指正。就这些,我要去买《阿凡达》的电影票了,嘿嘿。

十二、参考文章

1、Don’t Lose Your :focus
2、Better CSS outline suppression

(本篇完)

分享到:


发表评论(目前10 条评论)

  1. Maze说道:

    我想问一下,什么元素在什么情况下,会出现 outline 呢?
    我使用 jScrollPane 插件的时候,发现滚动的元素也会出现 outline。是否可以这样理解,可以使用键盘控制的元素都会出现outline?

  2. 一点灵犀说道:

    最近也碰到了类似的问题,仅Firefox下会出现,应用这个属性部分有效,感谢!
    用户可用性不可忽视,多谢提醒。

  3. L说道:

    css reset 顾名思义,就是归零,没有默认的东西影响到界面
    所谓“有问题”是从个人想实现的某种具体效果的角度来说的,所以“还比较出名的reset”对outline的处理“有问题”这个观点实在不敢苟同

  4. lonelyclick说道:

    最近在看normalize.css 的源码,发现它的对于outline的处理跟你讲的一样,给力!!!

  5. tinpe说道:

    在测试demo页面看第2个demo 看了下源代码 有点不懂 a标签的href=”#default_overflow_hidden” ,
    css中样式#default_overflow_hidden a{}选择器这样写可以吗?我自己本地试了下好像没反应。。还是说 这是特地针对 overflow:hidden 的

  6. 武勇说道:

    “仅仅使用:active去掉链接外框轮廓线”
    这个方法在Firefox3.6,取得焦点时候,外框还是向左延伸啊

  7. 过客说道:

    真是够麻烦的~一句话的事: hide-focus: expression( this.hideFocus=true );

    • 张 鑫旭说道:

      首先去除outline的虚框会大大降低页面的可用性,同时expression表达式是非常消耗性能的用法,再者此表达式仅IE浏览器有用。

  8. 行者说道:

    学习了,遇到过这个问题。没有好的解决方法。