对于CSS隐藏文字也许大家并不陌生,第一想到的或许就是 text-indent:-999em。但是作为一个重构者,精益求精一直是我们追求的目标,抛开text-indent的适用场景和bug不谈,大家有没有想过这种方法的弊端呢?
显而易见,如果图片由于某些原因未加载的时候,设置了 text-indent:-999em导致文字移出了浏览器视口(可视区域),我们看到的会是一片空白。网页中最重要的是内容,显然此时的可用性大打折扣了。
那么下面就先给大家说说可用性
Web内容无障碍指南(WCAG 2.0)定义了web内容无障碍的四项基本原则:可感知、可操作、可理解和健壮性,借用下jace幻灯片的图:
根据以上原则,我们就可以更好的来阐述 隐藏文字的利弊了,分为以下四种情况:
文字隐藏 |
分类 |
作用 |
方法 |
1.完全隐藏 |
用户交互 |
display:none; |
|
2.对屏幕阅读器隐藏 |
减少干扰 |
tabindex=“-1” |
|
3.对机器不隐藏 |
屏幕阅读器,搜索引擎等机器可以识别 |
text-indent:-999em; line-height 较大值 ... |
|
4.图片未加载不隐藏 |
图片未加载时文字可以显示 |
这个是本文的重点 |
很多时候,由于视觉的要求,很多标题性的文字,我们也还是得去使用图片,比如这次改版的一淘首页:
所以可用性更好的CSS隐藏文字应该具备一下几点:
1)支持双向(bidi-directional )字符集语言;
即同时支持从左到右和从右到左(例如:阿拉伯语、希伯来语)方向的文字。
2)可感知:图片未加载的时候,文字可以正常显示,而不是空白;
在高对比度模式下,所有背景图片都会被隐藏掉,我们来看看一淘的一个频道页:http://price.etao.com/search.htm?cat=50080000&sort=cm
高对比度模式下会变成这样:
去比较 按钮完全不见了,只能盲人摸象。很多朋友可能不知道高对比度模式是作何用途的,他是微软为色弱群体提供的一种系统主题,使色弱用户能更好的识别页面内容。再次提醒大家页面内容才是主体,不要本末倒置了。对于这种按钮,更好的方法是不把文字写入背景,可用性和可维护性都会更好!(色弱属于色觉障碍,分色盲和色弱两类,色弱为辨色力不足。色盲包括红色盲、绿色盲及蓝色盲、全色盲。后两种少见,色弱也包括红、绿、蓝色弱)
3)可感知:屏幕阅读器,搜索引擎都可以正常识别文字;
这对于视觉障碍用户和SEO都是很有帮助的;
4)健壮:用最少的Html结构去实现,减少对空标签的依赖性,容易抽象为独立模块。
需要隐藏文字的图片通常作用是装饰性的,像网站的logo更适合使用img标签插入。
好了,下面我们来看看实现CSS隐藏文字的各种方法,同时给出对应的优缺点
先上 DEMO
1、暴力的 display:none
.mod1 .ir { display: none; }
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
NO |
NO |
NO |
YES |
YES |
NO |
YES |
NO |
点评:大量使用容易被搜索引擎认为作弊,而且文字是彻底隐藏。
2、万能的margin负值
.mod2 .ir {
margin-left: -999em;
}
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
YES |
NO |
NO |
YES |
YES |
NO |
YES |
NO |
点评:容易对布局造成影响,不适合模块化
扩展阅读:
3、text-indent 负值
.mod3 .ir{
text-indent:-999em;
overflow:hidden;
display:block;
}
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
YES |
NO |
NO |
YES |
YES |
NO |
YES |
IE问题多多 |
点评:firefox下会导致焦点框扩大,需要添加overflow:hidden,同时text-indent尽量用于block元素,否则问题多多。
详见:《text-indent小总结》http://ued.ctrip.com/blog/?p=2942
IE6/IE7下,使用负缩进的方法隐藏inline-block元素内的文本,该元素也会缩进相同的值。
text-indent方法不适用于从右到左方向的语言。
4、新颖的 font:0/0 a;
.mod4 .ir {
border: 0 none;
font: 0/0 a;
/* display:block;
margin-top:-1px; 修复 IE6 隐藏不完全 */
text-shadow: none;
color: transparent;
background-color: transparent;
}
.mod4 .ir br { display: none; }
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
YES |
NO |
NO |
YES |
YES |
NO |
YES |
IE6出现小点 |
点评:这个方法是html5-boilerplate 中使用的,效果不错,唯独IE6会显示一个小点,可以通过其他方法兼容IE6。
5、牛掰的 CSS clip 属性裁剪
.visually-hidden {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
padding: 0 !important;
border: 0 none!important;
height: 1px !important;
width: 1px !important;
overflow: hidden;
}
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
YES |
NO |
NO |
YES |
YES |
NO |
YES |
NO |
点评:用好clip,事倍功半,只是hack比较多,CSS代码比较多。由Jonathan Snook 最先提出的,详见 Hiding Content for Accessibility。
6、空标绝对定位遮盖法
.mod6 .ir-warp {
position: relative;
overflow: hidden;
white-space: nowrap;
word-wrap: normal;
}
.mod6 .ir {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
background: url(http://www.iyunlu.com/skin/tg/images/logo.png) no-repeat 0 0;
}
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
YES |
YES |
YES |
NO |
NO |
YES |
YES |
NO |
点评:添加了无语义的空标签,图片未加载和高对比度模式下可以显示文字,由于不可以设置背景颜色 ,透明图片无法完整遮挡住文字,除非使文字面积不超过图片不透明部分。
7、可操作欠佳的 position: absolute
.mod7 .ir-warp { position: relative; }
.mod7 .ir {
position: absolute;
top: -999em;
left: -999em;
overflow:hidden;
}
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
YES |
NO |
NO |
YES |
YES |
NO |
YES |
页面跳动 |
点评:可聚焦元素获得焦点时,页面会出现极品的滚动现象。
8、又见 overflow:hidden
.mod8 .ir {
display: block;
line-height: 0;
overflow: hidden;
}
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
YES |
NO |
NO |
YES |
YES |
NO |
YES |
NO |
点评:Apple的 voice Over 无法读出高度为0元素中的文字
9、高度三倍以上的line-height
.mod9 .ir {
display: block;
overflow: hidden;
height: 60px;
line-height: 180px;
}
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
YES |
NO |
NO |
YES |
YES |
NO |
YES |
NO |
点评:
10、另辟蹊径 content :url 插入图片(绝对定位方式)
.mod10 .ir-warp {
position: relative;
overflow: hidden;
}
.mod10 .ir:before {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
content: url("http://www.iyunlu.com/skin/tg/images/logo.png");
}
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
YES |
YES |
NO |
NO |
YES |
YES |
YES |
IE6、7不支持 |
点评:原理与方法6类似,使用更加符合语义的content插入装饰性图片,可维护性更好,很可惜IE6、7不支持:before伪元素。
11、content background 插入图片
.mod11 .ir-warp { overflow: hidden; }
.mod11 .ir:before {
content: "\200b";
background: url(http://www.iyunlu.com/skin/tg/images/logo.png) no-repeat 0 0;
display: block;
height: 100%;
}
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
YES |
NO |
NO |
YES |
YES |
定高 |
YES |
IE6、7不支持 |
点评:由于高度固定了,当图片未显示的时候依然占据空间,文字溢出被隐藏了所以还是无法显示出来。
12、精益求精content url+display:inline-block
.mod12 .ir-warp { overflow: hidden; }
.mod12 .ir:before {
content: url("http://www.iyunlu.com/skin/tg/images/logo.png");
display: inline-block;/* 配合 margin 作 spire 定位 */
}
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
YES |
YES |
NO |
YES |
YES |
NO |
YES |
IE6、7不支持 |
点评:强强联合,此方法可谓精益求精,图片未加载也能正确显示文字,同时还支持透明图片和设置背景颜色
13、使用相对定位遮盖
.mod13 .ir-warp {
display: block;
height: 100%;
overflow: hidden;
white-space: nowrap;
word-wrap: normal;
}
.mod13 .ir {
position: relative;
z-index: -1;
zoom: 1;
overflow: hidden;
}
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
YES |
YES |
YES |
NO |
NO |
YES |
YES |
IE6、7层级bug |
点评:比方法6更简单,没有无语义的空标签。如果外层标签存在绝对定位,注意IE6、7可能会出现层级bug,导致文字无法遮盖,Oh my god,西天如来、观世音菩萨、玉皇大帝赶紧收了IE6这个妖孽吧!
综上所述
方法12,13是我们的不二之选,两者互相补充,根据使用场景不同,大家可以选择最适合的方案,当然IE6、7这两朵奇葩需要我们特别对待。我们来看看两者合体后的情况:
正常情况
图片未加载
所有浏览器完美显示出文字,Safari,Opera,Chrome对于conten插入的图片加载失败时 均显示提示图标或者 “图像”文字,这个浏览器处理不同就不过多说明了。看看合体后的支持情况:
屏幕阅读器 |
图片未加载显示文字 |
高对比度模式显示文字 |
透明图片 |
设置背景色 |
是否需要定义宽高 |
是否支持Sprite |
兼容性 |
YES |
YES |
IE6,7显示 |
YES |
YES |
YES |
YES |
NO |
再看看 DEMO
展望未来
content 生成内容特别适合做一些装饰性的布局,因为content就是为此而生的,很多小图标的定位我们完全可以抛弃空标签了,还有强大的 CSS3 content:attr() 我们拭目以待。
content在闭合浮动(清除浮动)上也大显身手,有兴趣可以看看我的另外一篇文章:
关于content 的更多应用请看:CSS content内容生成技术以及应用
通过各种方法的优缺点互补,我们很容易获得最适合的方案,在做好兼容性布局后,应该往可用性等更深层次进取,不断尝试探索新的方法。最后送大家一句话:
做简单可依赖的人,写简单可依赖的CSS
CSS层叠之美,你发现了吗?
由于精力有限,本文难免存在错误与疏漏,还请不吝口水,欢迎补充和修正本文存在的不足,非常感谢!
参考文献:
Nine Techniques for CSS Image Replacement http://css-tricks.com/css-image-replacement/
Nouvelle méthode de remplacement de texte par une image http://css.4design.tl/nouvelle-methode-de-remplacement-de-texte-par-une-image
Another CSS image replacement technique http://nicolasgallagher.com/another-css-image-replacement-technique/
视觉隐藏内容 http://www.topcss.org/?p=418