display属性,display:inline-block
display:inline-block感觉与display:table-cell有些相似,例如对内部元素的包裹性。但是,由于display:inline-block最大的不同就是其没有父元素的匿名包裹特性,这使得display:inline-block属性的使用非常自由,可与文字,图片混排,可内嵌block属性元素,可以可以置身于inline水平的元素中。可谓黑白通吃,左右逢源。
inline-block属性的元素适用于inline box模型,所以,当其中的列表元素高度不一时,是不会有错位的。关于line box模型,我在之前的“css行高line-height的一些深入理解及应用”第二部分提到了,以及前面“CSS float浮动的深入研究、详解及拓展(一)”一文的“浮动的破坏性”部分中做过比较详细的介绍。一言以蔽之,就是每一行所有的inline元素和inline-block元素会共同形成一个line boxes,这个line box的高度由里面最高的元素决定。所以,即使inline-block属性的列表元素高度异常,撑开的是整个line boxes的高度,因而,不会与下一行的列表元素发生错位。如下面的我自己画得拙劣的示意图所示的:
根据一些前辈的说法,IE6/7不支持display:inline-block属性,只是可以让标签有类似于inline-block的属性,起初我也是接受这种说法的,不过后来又表示了怀疑,最近使用text-align:justify;做测试的时候的一些样式表现证实了:确实IE6/7是不支持display:inline-block属性,只是让其表现的跟inline-block一样,尤其对于inline水平的元素,其表现度可以用perfect一词来形容了。
对于IE8+以及现代浏览器,直接使用:
{display:inline-block;}
就可以了,支持任意水平的元素。
对于不支持的IE6/7浏览器该怎么办呢?如果是inline水平的元素(如a标签,span标签之类)跟上面一样,直接:
{display:inline-block;}
就可以了,对于这两个浏览器,其功效与*zoom:1;是一样的。
如果是block水平的元素,例如li标签。则需要多点代码,目前我知道的方法有两个,如下所示:
li {display:inline-block;...} li {display:inline;}
或者是:
li{display:inline; zoom:1;...}
block水平的inline-block化的元素与inline水平的在表现层又是有差异的,这个后面会谈到。
一点小阻挠:inline-block元素间的换行符空格间隙问题
在完整的展示兼容性的像素级的inline-block元素列表布局前,有必要讲讲使用display:inline-block列表布局经常会遇到的“换行符/空格间隙问题”。
如果inline-block元素间有空格或是换行产生了间隙,那是正常的,应该的。如果没有空格与间隙才是不正常的(IE6/7 block水平元素)。真正的inline-block元素,就像个图片一样。例如,两个不在一行的img标签,形成的两个图片之间就会有间隙,如下图所示:
您可以狠狠地点击这里:换行符与inline-block元素间间隙demo
要让这些空格不出现,最简单的最容易理解的就是让列表的结束标签与下一个列表的开始标签连在一起,就像是:
<li> <span>...</span> </li><li> <span>...</span> </li>
但是,这种做法好傻啊,而且HTML代码的可读性很不好。尤其考虑到现实情况:后台人员可能不清楚标签换行对样式的影响,直接后台repeat的时候,换行了。所以,此方法顶多临时应付些小打小闹的地方,要想广泛使用,显然业余了。
其实,我们只要细细想想,空格符本质上就是个字符,与a,b,c,d这些字符是个同一个属性的东西,只是他是空格,透明的看不见而已(但可以选中)。所以,只要我们使用让文字宽度为0的那些方法,不就可以解决inline-block元素间换行符间隙的问题啦!
于是,很自然而然的,想到了以下样式:
{font-size:0;}
我还记得我大学时候解决IE6下标签高度无法小于11像素bug时的方法,就是使用的font-size:0;这属性可以让莫名的空格啊神马东东的都变成浮云。我们来试下,可否用来消除inline-block元素间的换行间隙的问题。
如下测试代码:
<div style="font-size:0;"> <img data-src="http://image.zhangxinxu.com/image/study/s/s128/mm1.jpg" /> <img data-src="http://image.zhangxinxu.com/image/study/s/s128/mm2.jpg" /> </div>
现在来看看几个主流浏览器下的反应,首先是Firefox浏览器:
然后是IE7浏览器:
哦呵呵,来看看大神Chrome浏览器:
希望越大失望越大,Chrome下的空格对于font-size:0貌似很不屑一顾。唉,这个问题在Chrome还是婴儿阶段的时候就有了,到现在还没有改过来。
经过我稀里哗啦一轮番的浏览器测试,发现就只有Chrome浏览器对font-size:0置若罔闻,连同样内核的Safari都不会这样。
您可以狠狠地点击这里:font-size:0清除换行符间隙demo
虽然Chrome目前国内份额有限,但是毕竟有不少高端用户在用啊。所以,一旦Chrome不支持font-size:0,那么,此方法显然不能应用到实际项目中,在加上IE和Safari下还是有1像素的间隙,所以此方法就此刷掉。现在得去考虑其他更好的方法。
我们一起开动脑筋,还有什么CSS属性可以影响文字的水平间距的。啊,只见脑袋上灯泡一亮,有了,不是有个letter-spacing属性嘛。可以控制文字间的水平距离的,支持负值,可以让文字水平方向上重叠(line-height是让文字垂直方向上重叠)。哟呵呵,心动不如行动,还拿那两张美女图片做示例,看看letter-spacing属性可否抹掉换行符产生的间距。参见如下测试代码:
<div style="letter-spaceing:-4px;"> <img data-src="http://image.zhangxinxu.com/image/study/s/s128/mm1.jpg" /> <img data-src="http://image.zhangxinxu.com/image/study/s/s128/mm2.jpg" /> </div>
先来看看一向表现优异的Firefox3.6浏览器,如下图:
很不错吧,再来看看前面让我们失望的Chrome浏览器:
嘿嘿,也是不错,希望就在眼前,看看IE新生主力军IE8下的表现:
再来看看对inline-block属性不支持的IE7浏览器:
您可以狠狠地点击这里:letter-spacing去除间隙空格
结果让人心里咯噔了一下,晕那,好像没有作用诶!不会啊,我很清楚的记得即使IE6/7浏览器也是支持letter-spacing去空格的。后来我仔细对比,发现这里的letter-spacing:-4px是有所用的,只是默认的空格间隙比较大,所以,即使舍去4像素间距,还是有一段空白内容。但是,我清楚的记得在Arial字体下,空格间距应该是兼容的,为何这里就IE6/IE7浏览器下不一样呢?后来,我反复测试,终于发现了一个第一次看到的bug,“冒号影响了空格间隙的水平大小”。现将“效果:”这个小标题后面的中文冒号还成英文的,结果,空格间距一下子兼容了,真是很神奇,我不得不佩服IE6/7浏览器的怪异指数。
您可以狠狠地点击这里:IE6/7下冒号英文化后间隙demo
IE6/7浏览器本身就是个怪胎,喜欢不走寻常路。在这两个浏览器下,block水平的元素inline-block化之后,会直接忽略换行符的间隙。所以,这里还有一点点疑虑没有解决。既然IE6/7浏览器div,li 这些标签inline-block化后没有空格间隙,那么使用letter-spacing负值会不会让列表元素水平重叠呢?啊,这个问题就不要担心了,如果元素间本身没有空格,使用letter-spacing属性是不会发生水平重叠的问题的。例如下面的测试代码:
<div style="letter-spacing:-4px;"> <img data-src="http://image.zhangxinxu.com/image/study/s/s128/mm1.jpg" style="border-right:4px solid #066;" /><img data-src="http://image.zhangxinxu.com/image/study/s/s128/mm2.jpg" style="border-left:4px solid #F36;" /> </div>
结果如下图:
也就是说,如果元素间本身就没有间隔,无论letter-spacing的值多小,元素都不会重叠。但是,如果有空格间隙存在,letter-spacing会发生重叠的。所以,我们无需为IE6/7元素会不会重叠这个问题担心了。
您可以狠狠地点击这里:letter-spacing与无间隙重叠demo