行内非替换元素的高度由 'line-height' 特性值决定,'margin' 'padding' 'border' 都不加入行内框高度的计算(也不参加线框高度的计算),但是他们还是在行内框周围得到渲染。
具体描述请参考 CSS 2.1 规范的 10.8.1 Leading and half-leading
行内非替换元素的宽度不由 'width' 属性决定,他的实际宽度由其中的内容具体宽度决定,如果为空元素,那么宽度的计算值自然也就是 0。
具体描述请参考 CSS 2.1 规范的 110.2 Content width: the 'width' property
根据标准文档描述可以断定,如果空的行内非替换元素存在 'margin' 'padding' 'border' 值,不管实际宽度是否为 0 ,他都应被渲染出来。
当一个空的内联非替换元素前,存在其他内联元素(包裹匿名内联元素)时,如果他们之间仅存在唯一的空文本节点就有可能导致这个空内联非替换元素消失,不在文档流中占据渲染空间。
这个问题会导致布局中某小部分内容消失,如果这部分消失的标记具有交互功能,则这个功能将不可能再被用户使用到。
Chrome Safari |
---|
这个问题发生在普通非替换行内元素上,根据 HTML 4.0 规范定义,一般常用的此类元素有: A,ABBR1,ACRONYM,B,BDO,BIG,CITE,CODE,DEL,DFN,EM,FONT,I,INS,KBD,LABEL,Q,S,SAMP,SMALL,SPAN,STRIKE,STRONG,SUB,SUP,TT,U,VAR 等。
【注】:ABBR 标记在 IE6 浏览器中存在脚本处理问题可参考文章 BT9023: IE6 中对 ABBR 元素的相关实现有误 ,本文中将不把此元素列为测试范畴。
以下代码将通过脚本程序构建这些元素的空标记形式,通过样式表让每个元素都拥有了 'border ‘特性,根据规范他应该给被渲染出来。并且每个元空素绑定 click 事件,如果元素不可见,则可以用以此方式检查该元素是否还可以响应用户事件。代码构建了四组示例,第一组中空标记之前的匿名行内非替换元素与空标记之间存在唯一空文本节点;第二组中两个元素间存在多余一个文本节点, 第三组中个元素与空标记紧密相连,第四组在第一组基础上将标记变为非空情况。
<style> a,acronym,b,bdo,big,cite,code,del,dfn,em,font,i,ins,kbd,label,q,s,samp,small,span,strike,strong,sub,sup,tt,u,var {font-size:30px; line-height:50px; border:10px solid #0F0; cursor:pointer;} div.info{font-size:12px; line-height:18px; color:#060; background:#EEE;margin:30px 0 30px 0;} </style> <script> var inlineElements = { 'a':'<a></a>', 'acronym':'<acronym></acronym>', 'b':'<b></b>', 'bdo':'<bdo></bdo>', 'big':'<big></big>', 'cite':'<cite></cite>', 'code':'<code></code>', 'del':'<del></del>', 'dfn':'<dfn></dfn>', 'em':'<em></em>', 'font':'<font></font>', 'i':'<i></i>', 'ins':'<ins></ins>', 'kbd':'<kbd></kbd>', 'label':'<label></label>', 'q':'<q></q>', 's':'<s></s>', 'samp':'<samp></samp>', 'small':'<small></small>', 'span':'<span></span>', 'strike':'<strike></strike>', 'strong':'<strong></strong>', 'sub':'<sub></sub>', 'sup':'<sup></sup>', 'tt':'<tt></tt>', 'u':'<u></u>', 'var':'<var></var>' } function getElementSize(element){ return {w:element.offsetWidth,h:element.offsetHeight}; } function getStyle(element,styleName){ return (element.currentStyle) ? element.currentStyle[styleName.replace(/-[a-z]/g, function() { return arguments[0].charAt(1).toUpperCase(); })] : (document.defaultView && document.defaultView.getComputedStyle) ? document.defaultView.getComputedStyle(element, null).getPropertyValue(styleName) : null ; } function bindEvent(element,eventName,fn){ element["on"+eventName] = fn; } function buildElementInfo(tagName,element){ var elementSize = getElementSize(element); document.writeln('<div class="info">'); document.writeln(tagName,' 标记的宽为:',elementSize.w,'px; ','标记的高为:',elementSize.w,'px; ', 'display 值为:', getStyle(element,'display')); document.writeln("</div>"); } function buildElement(title,type,html){ var elementSize,element; document.write(title); for (var i in inlineElements) { document.writeln('<div>'); switch(type){ case 1: document.writeln(i); document.writeln(" "); break; case 2: document.write(i); break; case 0: case 3: document.writeln(i); break; } document.writeln(inlineElements[i]); document.writeln("其他文本内容……"); document.writeln('</div>'); element = document.getElementsByTagName(i)[type]; element.innerHTML = html; buildElementInfo(i,element); bindEvent(element,"click",(function(i){return function(){alert(i+" 标记被点击")}})(i)) } } buildElement('<h2>空行内非替换元素前仅存在唯一空文本节点情况</h2>',0,""); buildElement('<h2>空行内非替换元素前存在不唯一空文本节点情况</h2>',1,""); buildElement('<h2>空行内非替换元素与前一行内元素紧密相连渲染情况</h2>',2,""); buildElement('<h2>有文本内容的行内非替换元素非紧密相连渲染情况</h2>',3,"tag"); </script>
各浏览器运行结果如下:
IE6 IE7 IE8(Q) | IE8(S) Firefox Opera | Chrome Safari | |
---|---|---|---|
空行内非替换元素前仅存在唯一空文本节点情况 | |||
样式是否被渲染 | 否1 | 是 | 否2 |
是否占据渲染空间 | 是 | 是 | 否2 |
是否可被点击 | 是 | 是 | 否2 |
空行内非替换元素前存在不唯一空文本节点情况 | |||
样式是否被渲染 | 否1 | 是 | 是 |
是否占据渲染空间 | 是 | 是 | 是 |
是否可被点击 | 是 | 是 | 是 |
空行内非替换元素与前一行内元素紧密相连渲染情况 | |||
样式是否被渲染 | 否2 | 是 | 是 |
是否占据渲染空间 | 是 | 是 | 是 |
是否可被点击 | 是 | 是 | 是 |
有文本内容的行内非替换元素非紧密相连渲染情况 | |||
是否被渲染 | 是 | 是 | 是 |
是否占据渲染空间 | 是 | 是 | 是 |
是否可被点击 | 是 | 是 | 是 |
【注1】:这是 IE6 IE7 IE8(Q) 的空行内元素渲染问题,可以参考文章:RD3029: IE6 IE7 IE8(Q) 的空非替换行内元素渲染方式存在差异。
【注2】: Chrome Safari 中要排除 Q 标记的表现情况,因为这个标记会自动向标记内补充双引号作为文本内容,这破坏了本测试用例对空标记渲染检测的原意。
根据汇总表格可以看出:
避免使用的空的非替换行内元素,如果必须需要标记内不显示出文本内容,可以使用 'text-indent' 特性将文本负缩进至屏幕外。
操作系统版本: | Windows 7 Ultimate build 7600 |
---|---|
浏览器版本: |
IE6
IE7 IE8 Firefox 3.6.10 Chrome 7.0.544.0 dev Safari 5.0.2 Opera 10.62 |
测试页面: | webkit_inline_elment_hidden.html |
本文更新时间: | 2010-10-09 |
webkit Chrome Safari inline non-replace inline element 空文本节点 空非替换行内元素 渲染 消失 隐藏