2007-08
14

又懒了一下,好几天没更新了。其实上周买的书到了,这几天在忙着看书, 没顾得上研究技术。昨天一口气看完了《CSS禅意花园》, 觉得这本书不愧CSS设计的王者称号,无论从欣赏还是学习的角度,这本书都值得一读。

当然,原书网站CSS Zen Garden也一定要去看看。

今天先来介绍一个从这本书上学到的小技巧:如何用图片替换文字

所谓图片替换文字就是用图片代替HTML中的某个文字元素,如标题。网站设计中很常用, 比如我想用图片而不是文字来显示blog标题,我可以在本应当显示<h1>的地方显示一个<img>, 但这样页面中失去<h1>会影响搜索引擎评分。当然我也可以通过css给<h1>设置一个背景图片, 但<h1>内的文字必须显示,否则也会影响搜索引擎评分。 可以使用下面的方法之一来通过CSS完美解决。

Fahrner图像替换(Fahrner Image Replacement, FIR)

该技巧由设计师Douglas Bowman在2003年3月首次发布。 该技巧的实现方法如下:用span将要替换的文本包围起来,再通过css隐藏这个span即可。 例如,HTML文本如下:

<h1 id="blogtitle"><span>idv2</span></h1>

可以通过以下的CSS实现替换:

#blogtitle {
  background: url(img/title.png) top left no-repeat;
  width: 348px;
  height: 25px;
}

#blogtitle span {
  display: none;
}

上面这个技巧的优点在于代码简单、兼容性好,但如果浏览器设置为不显示图片却使用CSS, 那么<h1>的地方就会一片空白。

实际上这个方法是一切图像替换方法的基础,随着技术的发展,更好的图像替换方法出现了。

通过height属性实现

该方法由Seamus Leahy和Stuart Langridge发现。

HTML代码:

<h1 id="blogtitle">idv2</h1>

CSS代码:

#blogtitle {
  padding: 25px 0 0 0;
  overflow: hidden;
  background: url(img/title.png) top left no-repeat;
  height: 0px !important;
  height /**/: 25px;
}

该方法的要点是:设置height为0px并通过 !important 属性确保它不会被覆盖, 同时使用padding-top属性设置实际的显示高度。

由于IE的盒模型显示bug,需要使用hack(上述的/**/部分)。 这里关键的是 height /**/ 的值要和padding-top设置为相同。

这个方法可以在IE5.0及以上版本、Netscape 7、Opera 6以及以上版本、Firefox、IE5.2(Mac)、 Safari上使用。优点是不需要多余的<span>;缺点是依然没有解决浏览器禁用图像时的空白问题。

通过text-indent属性实现

该方法由Mike Rundle提出,可以说是最简单实用的方法了。

HTML代码:

<h1 id="blogtitle">idv2</h1>

CSS代码:

#blogtitle {
  text-indent: -5000px;
  background: url(img/title.png) top left no-repeat;
  height: 25px;
}

其思路就是用负的text-indent属性将文字移动到屏幕之外。

这个方法可以在IE5.0及以上版本、Netscape 7、Opera 6以及以上版本、Firefox、IE5.2(Mac)、 Safari上使用。优点是不需要多余的<span>、CSS简单;缺点是依然没有解决浏览器禁用图像时的空白问题。

较为复杂但完美的方法

Levin Alexander提出了一个能够解决浏览器禁用图像时的空白问题的方法。 就是不再将文本放在<span>内,而是从<span>中移出来,和<span>一起放在父元素中, 然后将背景图像应用在这个<span>上,并用该<span>盖住文字。 这样就可以解决浏览器禁用图像的问题,但缺点就是不能使用透明图像 (否则被遮盖的文字会露出来),而且CSS代码也较为繁琐。

由于代码较长,在这里就不写了,有兴趣的可以去参考《CSS禅意花园》这本书。




这篇文章有 5 条评论了,快来一起讨论讨论吧!
#1
smalldust
2007-08-20 23:03

说实话,我觉得这些代码一点也不美,甚至有些丑陋——就是因为它们繁琐地为了实现一个CSS本身不支持的效果利用各种Bug和系统本身的漏洞,使得代码的可读性下降。

我认为,优秀的代码应该是和自然语言一样清晰易懂,意图清楚地写在一句句的程序当中。可是显然“text-indent: -5000px;”等语句已经远远偏离了他们的愿意。如果真是非要这样才能“不显示文字显示图像”和“搜索引擎评分”兼得的话,我宁愿舍弃其中之一。

#2
charlee
2007-08-20 23:14

呵呵,又要说一句smalldust同学不爱听的话了。
如果非要舍弃hack的话,我宁愿舍弃IE浏览器。
要知道绝大部分的hack都是针对IE的——IE5 on Mac, IE6,甚至是IE7。
Firefox、Opera和Safari虽然对标准支持各异,
但毕竟不会给开发者带来如此众多的麻烦。

至于 text-indent,那么我想先问一个最简单的问题,
在高级语言没有诞生之前,人们是如何清除寄存器的呢?
恐怕不会有人使用 MOV AX,0,而是使用 XOR AX AX吧。
广义来说这不也是hack的一种吗?

再举个例子,[url=http://tech.idv2.com/2006/12/05/fast-sqrt/]快速平方根算法[/url],
这个算不算hack呢?

hack的出现我认为是由于标准尚不完善,
相信随着CSS的不断完善和各大浏览器厂商对CSS的支持度的提高,
这些问题终究会进入博物馆的。

令我奇怪的是,以微软的实力,不可能在实现CSS上技术能力不足,
不求走在最前端,哪怕不落后总该能办到吧。
但事实上哪怕是最新的IE7也仅仅支持了CSS2标准中的几条。
真是令人费解,商业目的?

#3
smalldust
2007-08-21 21:55

报告Charlee老师,我本身也不喜欢IE浏览器(我更多时候都是用Firefox)。可是这个Hack好像不是针对IE的,而是针对CSS本身的缺陷的啊?在Firefox里难道可以很用很漂亮干净的代码完成用图片做Title文字吗?

其实我个人觉得,我个人很注重技术本身是否优秀,而不是开发商(而不是觉得Windows好Linux不好,然后就什么都是Windows上的好)。

举例来说,我个人很推崇.NET,是因为它把面向对象做得很好;但是同时我很鄙视ASP.NET,觉得它浪费资源巨多,却还不如PHP/JSP功能全面;为了完成一个功能也要调用无数个Class无数个Method,是一个典型的过度设计。

#4
charlee
2007-08-22 17:48

啊。是我误会你了。的确应该注重技术而不是注重提供商 :)

至于那个hack,的确不是针对浏览器bug而是针对CSS标准上的问题。
而至于这种hack是否应该使用,我在上一篇评论也发表观点了。

总结一下就是,
如果它能保证永远正确,并能为绝大部分开发者接受,那么就是可用的。

就像 XOR AX, AX 一样。

我也很反对那些针对浏览器解释bug的hack(虽然我也在用)
不过在目前各个浏览器对CSS的支持良莠不齐的情况下,
我们还不得不依赖于这些hack是不是?

ps. 咱俩似乎讨论过很多关于微软和Linux的技术话题了,
哪天专门开个话题深入讨论一下?

#5
CSS禅意花园(1)-使用图片替换文字 - anzy.cn/css
2008-10-14 10:40

[…] 原始链接http://tech.idv2.com/2007/08/14/image-replacing/ […]

添加评论