破解缝隙之谜[转载自 http://learning.artech.cn/]

 好久没有写博客了 主要是自己太懒了

今天随意的浏览着网站 发现了曾经遇到的莫名其妙的问题,最后又总是莫名其妙的好了 一直不了解是怎么回事 后来就不了了之了 今天无意中看到 这个文章 恍然大悟,放到这里做个备注

不知道你们是否也遇到了这个问题 呵呵

以下全文转载

##############################################################################################

 

今天收到一位读者的问题,比较有趣,这里介绍给其他读者分享。首先这位读者在前几天的留言中问了这样一个问题:

“您好! 请问,将图片放于Div标签中时,底部与右部都会出现间隙,请问如何去除?”

这个问题问得很笼统,我也很难具体帮助他,因此只能给出一些指导性的原则,因此我这样回答了他:

“这个需要具体调试,看一看这个间隙到底什么原因造成的。关于调试,可以参考一下这篇文章:

http://learning.artech.cn/20080129.css-debug-skills.html

我猜想,这位朋友很认真地看了这篇文章,做出了努力,然后给我回信如下:

“感谢您的回复,经过您的指点,发现了问题的所在,但是问题依然没有解决。询问几个老师,都无法解决(已经ff,及ie测试)。闻前沿工作室的老师对此造诣颇深,烦请赐教!!!现附代码及效果图如下:”

代码:

1
2
3
4
5
<body>
<div style="border:1px solid #FF0000;">
<img src="images/logo1.jpg">
</div>
</body>

效果:

ie-css-bug

可以明显地看到图片和下边框之间出现了一条缝隙。而右侧的缝隙我想这位读者不应该有什么疑问,因为div是个块级元素,自然会有右伸展到右端,我觉得这个不是读者要问的问题。而这个关键的问题是底下的这条缝隙到底是怎么产生的呢?以及如何去掉这个缝隙呢?

下面我来解答一下这个问题。

首先要说说的是,这位读者是一个很善于学习的读者,从第一次提的问题,到第二次提的问题,可以发现,第一次的问题,别人很难了解他遇到的到底是什么问题,而第二次的问题,他做了三件事:

1:简化代码,暴露问题,得到了一段出现问题的最简代码,2:给出了这段非常简单的代码,3:给出了问题的效果图。

这样我们就可以一眼知道问题是什么了。这样对于提问者来说,就非常容易得到别人的帮助,比如你到某个论坛去发帖寻求帮助,如果做到了上面这三点,别 人就很容易能帮上你,而如果仅仅是一句话的描述,或者是把非常大的一段代码贴上去,别人就很难帮上你了。具体“提问的艺术”请参考:http://talking.artech.cn/thread-178-1-1.html

下面具体说一说这个缝隙到底是怎么来的。

第一步:摸底

假设现在我们遇到这个现象,不知道是什么原因,首先用各种浏览器都看一看,分别效果如何。也就是先摸摸底。当我们使用 Firefox 、IE 6 、IE 7 、IE 8 观察以后,可以发现,这个缝隙在IE 6和IE 7中都是存在的,而在Firefox和IE 8中去不存在,看来IE 8还是不错的。

ie-8-preview

btw,关于如何方便地使用多种IE浏览器查看一个网页,可以参见:《CSS调试工具推荐 —— IE Tester》

这里有一个经验之谈,如果在IE6和IE7中的效果不一样,而IE7和Firefox中效果相同,通常是IE6的bug,而如果IE6和IE7中的相同,而与Firefox不同,通常是他们对CSS标准的解释不同。

OK,读到这里,如果您以前没有遇到过这个问题,不妨先停下来,自己试试看,能不能快速地找到这个缝隙的产生原因。如果5分钟内搞定,可以认为自己的CSS基础知识过关啦~~~

第二步:尝试

此前我也没有遇到过这个问题,所以这里就要来点头脑风暴了,就像初中证明平面几何题,有时候是要靠点运气和灵感的。就好像在证明几何题中添加“辅助线”往往是最关键的一步,这里我们可以试试看在图片后面加几个字母,就相当于添加一条辅助线,看看效果如何。

add-some-text

看了上图,这下子就有线索了,请读者仔细看一下,一共六个字母,左右各三个,你发现各自的特点了吗?——右边的三个的下端都带有一个“钩”,而左边 的三个没有。到这里我们已经明显地感觉到问题很可能和它旁边的文字有关,因为这个缝隙的高度和这个“钩”的高度很一致。辅助线起作用了!

第三步:联想

我们这时联想一下文字和图像相关的内容,自然可以联想到“图片与文字的对齐方式”这个问题了,如果读者手边有“HTML+CSS网页设计与布局从入门到精通”这本书,翻到150页,第11.5节“图片与文字的对齐方式”,第2小节:“纵向对齐方式”,那么就一切真相大白了。这一小节讲的是:图像与它旁边文本之间的纵向对向方式由 vertical-align 属性控制,默认值为 baseline 方式,即“基线”对齐。

什么是基线呢?就是上面图中abc这三个字母的底端所在的水平线,英文26个字母,绝大部分都是没有“钩”的,他们的下端都是对齐于基线的,而默认下情况,图像与它旁边的文字也是基线对齐的,也就是说,你可以把这幅图像想象成一个字母,那么这个缝隙就存在了。

而在Firefox和IE 8种,为什么没有这条缝隙呢?是因为他们在对于只有图像,而旁边没有字母的时候,做了不同的处理。如果你用IE8查看一下加了字母以后效果,可以看到同样出现了这个缝隙。

第四步:解决

到这里,我们就可以非常容易地把这个缝隙去掉了: 给图片增加一个CSS设置,使图像与文字的底端,而不是基线对齐就可以了。

1
2
3
4
5
<body>
<div style="border:1px solid #FF0000;">
<img src="images/logo1.jpg" style="vertical-align:text-bottom">
</div>
</body>

第五步:总结

到这里,问题就解决了。从这个问题,我们可以总结几点。

1:要善于调试,善于从蛛丝马迹中寻找问题的本质原因。

2:调试的最重要的手段就是“简化代码、暴露问题”,要隔离出一段出现问题的最小代码集,这样寻找问题的解决方法就会容易得的。

3:要善于联想,尝试添加一些“辅助线”,帮你找到问题的关键。

4:基础知识要扎实,如果你根本就不知道有 vertical-align这样一回事,那么再怎么联系也没有用的。

5:书上的东西都是原理,真正如何灵活地运用到工作中,还需要靠不断地积累经验。


今天上午回答了一位读者的问题,有几位朋友在留言中给出了一些评论,其中 蓝月 网友给出了一个解决方法,使我想到了以前遇到的另一个问题,因此这里再补充,并更深入地扩展说明一下。

如果没有看过上一篇文章的读者,可以先看一下:你问我答(34)——破解缝隙之谜

蓝月指出,如果在div标记和img标记的尖括号都连起来写,不加空格,就不会出现这个缝隙了。例如这样写(请注意img标记的尖括号的位置):

1
2
3
        <div style="border:1px solid #FF0000;">
<img src="pic.jpg"
></div>

这里比较一下上面的写法和下面的写法有什么区别呢?

1
2
3
       <div style="border:1px solid #FF0000;">
<img src="images/logo1.jpg">
</div>

上面两种写法,再Firefox和IE 8中,是完全一样的,而在IE6和IE7种,却有所不同。

浏览器在解析HTML的时候,除了标记节点之外,还会根据需要生成文本节点。例如昨天的文章中,在图像的后面加了几个字母以后,就产生了一个文本节 点,在没有字母的时候,本来是不应该产生文本节点的,但是IE在解析上面一种写法的代码时,会把标记之间的空格解释为文本节点,从而根据默认的规则,图像 的底边和就会和文本的基线对齐,而产生了这样一条缝隙。

而当本来完全一样的代码,写成上面的第一种写法时,由于标记之间(尖括号之间)不加空格,因此IE6、IE7也不会解析出文本节点,从而也就不会产生这个缝隙了。这就解释了蓝月的方法为什么可以解决这个问题。

由此我又想到了另一个多次遇到过的针对IE6的问题,本质和这个问题是完全一样的,因此这里也介绍给大家。如下图所示的是一个很常用的效果,CSS的目的是将列表项目中的a元素改为块级元素,从而使得响应鼠标的范围扩展到li的矩形范围,而不仅仅是链接文字。

ie-li-preview.png

代码很简单,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style>
li a {
display:block;
background:#CCC;
border-bottom:1px #000 solid;
text-decoration:none;
}
li a:hover {
background:#BBB;
}
</style>
 
<body>
<ul>
<li><a href="#">First Item</a></li>
<li><a href="#">Second Item</a></li>
<li><a href="#">Third One!</a></li>
</ul>
</body>

事实上,以上代码在IE7、IE8、Firefox这些浏览器中都没有问题,但是在IE6中,效果将如下图所示:

ff-li-preview.png

在各个li之间为什么会产生这个缝隙呢?其实原理和上面谈到的原意是一样的,IE 6 在某些时候,会把标记尖括号之间的空格解释位文本节点,因此,解决方法就是把HTML代码的换一种写法:

1
2
3
4
5
    <ul>
<li><a href="#">First Item</a></li
><li><a href="#">Second Item</a></li
><li><a href="#">Third One!</a></li>
</ul>

可以看到,我们仅仅把

分在两行里写,以保证消除标记之间的空格,在IE 6中效果就立即正常了,如下图所示。

fixed-li-preview.png

需要说明的是,通过这种HTML格式的方式解决这个问题,未必是看起来最舒服的一种,当然通过CSS来解决也是可以的。不过这种方式的最大优点就是 快捷和直接,立竿见影,哪里多出了文本节点,就直接在HTML中消灭掉他。如果用CSS来解决则需要具体问题具体分析,会稍微麻烦一些,当然也是完全可行 的。

 

posted @ 2009-04-06 20:09  雨中漫步的太阳  阅读(392)  评论(0编辑  收藏  举报