我们需要在创建一个整洁、简单的视觉设计和提供可访问的内容和功能之间做平衡。一个通用的解决办法是向屏幕阅读器提供补充文本,并通过CSS隐藏这些文本。请访问我们的屏幕阅读器测试:无障碍隐藏内容方案来了解更多关于隐藏内容的可访问性的信息。
从Jonathan的这篇博文 Adaptive Themes中的评论和其他地方的提问来看,许多开发者仍然对这个问题感到困惑。因此,首先扼要重述一下基本的声明,当提及隐藏内容时:
使内容对辅助技术(AT)可访问的技术
position:absolute; clip:rect(1px 1px 1px 1px);
position:absolute; left:-999em;
position:absolute; top:-999em;
text-indent:-999em;
使内容无法访问的技术(所有用户均不可见)
visibility:hidden; /* in most screen readers*/
display:none; /*in most screen readers and with some exceptions http://juicystudio.com/article/screen-readers-display-none.php*/
overflow:hidden; height:0; /* In VoiceOver */
补充说明一下,在使用上面最后一条规则时,如果 Voice Over忽略了内容,这不是 因为height:0(通常都是这样认为),而是由于overflow:hidden,这是说的通的,因为0 × 0像素的盒子不能隐藏内容。
技术与挑战
您可以查看Hiding Content for Accessibility,这篇文章总结了不同的技术及其陷阱,但总之,每种方法都要解决下面这些共同问题:
- 它应使元素消失(仿佛文档中不存在该元素):这意味着应该没有多余的空白、没有滚动条、不能出现与层叠相关的问题(不可点击)等。
- 当隐藏容器中的元素获得焦点时,应防止出现意外的滚动。 也就是说,当用户使用tab导航到隐藏容器内的可聚焦的元素时,网页不应该跳跃。
- 双向(bidi)字符集语言友好。 即该技术应该同时支持从右到左,从左到右的界面,如阿拉伯文和希伯来文。
注:检测屏幕阅读器能否访问你隐藏的内容的一种简单的方法,就是使用键盘来访问隐藏容器内的可聚焦元素(可以在容器中添加一条链接)。如果键盘导航能够跳至隐藏容器内的元素,那么内容是可以访问的 。
最好的方法(理论上)
以我的愚见,迄今为止最好的方法– 是 Jeff Burnz 的clip technique 。很简短,并且与方向无关。就是这样:
.element-invisible { position: absolute !important; clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ clip: rect(1px, 1px, 1px, 1px); }
注意,所有的浏览器都理解第一条clip的声明,但IE6和7不能理解第二个正确的语法(逗号分隔值,标准中使用的方法)。
不幸的是,Webkit、Opera以及IE(在一定程度上)使用这种方法会产生问题。会产生不必要的滚动条,取决于隐藏元素的布局和/或在页面上的位置。总之,这些浏览器可以剪切盒子,但其行为就好像被剪切的元素保持了其原有的布局。注意虽然盒子真的被裁切了,即使在页面上好像仍然占有空间,但它不干扰周围的元素。
这种行为与规范不符 : 已被裁剪的内容不会溢出( Content that has been clipped does not cause overflow) 。如果有人知道答案,请留言。
方案二
Jonathan Snook 和他雅虎的同事想出了解决WebKit /Opera下问题的一个方案。它结合了两种技术:
.element-invisible { position: absolute !important; height: 1px; width: 1px; overflow: hidden; clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ clip: rect(1px, 1px, 1px, 1px); }
如果我们能够依靠clip的话 ,这已经很好了,但我们不能。请记住clip和overflow之间的主要区别是,它们针对的盒子不一样。一个是边界框(border box ),而另一个是内容框(content box )。上面的规则可以有效地“抹掉”边框和内边距(内容框外边缘),但不能在大多数浏览器中防止滚动条。
所以,更“保险”的规则是:
.element-invisible { position: absolute !important; clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ clip: rect(1px, 1px, 1px, 1px); padding:0 !important; border:0 !important; height: 1px !important; width: 1px !important; overflow: hidden; }
它看起来不好看,但它能够防止与盒模型相关的的问题。我写的声明使用了一个特定的顺序,如果有一天clip的效果与人们期望的一致,那么我们就可以去掉clip后面的所有声明,只使用:
.element-invisible { position: absolute !important; clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ clip: rect(1px, 1px, 1px, 1px); }
Tab键导航
这个“问题”是关于明眼键盘用户的。如果隐藏的内容是垂直偏移( 即position:absolute; top:-999em;),那么Tab键跳到隐藏容器内的可聚焦元素时,页面会出现滚动。在任何情况下,即使没有偏移(即position:absolute; left:-999em;,其行为也是混乱的,因为没有视觉线索告诉这些用户他们在页面的哪个位置。
我们可以尝试为使用指点设备和键盘来导航的人“修复”这个问题,但这可能并不奏效。我们的想法是使用伪类 :hover把隐藏容器中的可聚焦元素从Tab键序列中移除。例如,使用这样的规则:
body:hover .element-invisible a, body:hover .element-invisible input, body:hover .element-invisible button { display: none; }
只要用户把鼠标光标放在页面上,上面的规则可以把链接和表单控件从Tab键顺序中删除了(请注意,此规则在IE7下可能会造成性能问题)。
类名的语义
我不肯定类名中使用element是否有语义(如element-hidden )。好像有点冗余,一个选择符总是与元素相匹配的。我更倾向于使用html5boilerplate的方法,他们使用visuallyhidden,这里我使用连字符:
.visually-hidden { position: absolute !important; clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ clip: rect(1px, 1px, 1px, 1px); padding:0 !important; border:0 !important; height: 1px !important; width: 1px !important; overflow: hidden; } body:hover .visually-hidden a, body:hover .visually-hidden input, body:hover .visually-hidden button { display: none !important; }
使内容不可访问
如果你的目标是向所有的用户隐藏内容,按照Webaim的建议同时使用visibility和display:
.hidden { visibility: hidden; display: none; }
这是2007年的建议,如果谁有更好的方法,请留言。
更多阅读
- Invisible Content Just for Screen Reader Users.
- Hiding Content for Screen Reader Users (this is about the practice, not about the technique per se).
- Screenreader Visibility
FROM: Clip your hidden content for better accessibility BY Thierry Koblentz(是TJK Design、 EZ-CSS和 CSS 101的站长,Twitter @thierrykoblentz 。)
/* Hide only visually, but have it available for screenreaders: h5bp.com/v */
.visuallyhidden {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
/* Extends the .visuallyhidden class to allow the element to be focusable when navigated to via the keyboard: h5bp.com/p */
.visuallyhidden.focusable:active,
.visuallyhidden.focusable:focus {
clip: auto;
height: auto;
margin: 0;
overflow: visible;
position: static;
width: auto;
}