CSS first-letter伪类元素的特点

所属分类: 网页制作 / CSS 阅读数: 257
收藏 0 赞 0 分享

有一次我试图让<div id="acticle"><p>……</p></div>中的P也能实现首字下沉,可是结果却失败了,得出的结论是:我们并不能隔着一层标签去控制子对象中的第一个字符。

由于这句存在误解的可能性(我就误解了他的意思),振之在第一时间就删除这句话。他的意思准确地说,是:first-letter这个伪类无法向下“继承”。例如:

复制代码
代码如下:

<div id="demo">
<p>我要实现首字下沉</p>
</demo>

 如果只定义#demo:first-letter,我们将看不到任何结果,必须使用#demo p:first-letter。和a:link这样的链接伪类不同,:first-letter(当然还有其他的)无法向下“继承”。之所以加上引号,是因为:first-letter的这种无法穿透子对象的特性和通常定义的继承有所区别。这一概念在《CSS权威指南》中是这样定义的:基于继承机制,样式不仅应用到指定元素,还会应用到它的后代元素。假设在上面的html代码中我们给外层定义一个边框:#demo { border: 1px solid #000; },我们知道这里无法向下继承的是border属性,而:first-letter是一个伪类元素,换个说法,:first-letter中的任何属性均不向下继承。

复制代码
代码如下:

#demo:first-letter { font-size:2.5em; font-family:"楷体_GB2312"; font-weight:bold;
line-height:1.2em; float:left; padding:5px 2px 0 0; color:#c00 }
#demo p:first-letter { font-size:2.5em; font-family:"楷体_GB2312"; font-weight:bold; 5: line-height:1.2em; float:left; padding:5px 2px 0 0; color:#c00 }

如果问题仅仅是这个,那么文章也到此结束了。但是在我测试:first-letter这个伪类元素的特质是否存在于各大浏览器的时候,我发现在IE8下,不论我如何设置我的css(如上),效果都是不可见的。原谅我的孤陋寡闻,我竟然怀疑起IE Tester的性能,我第一想到的是它对IE8的渲染核心设置有误。接着我升级了我的IE7……直到我在崭新的IE8 beta1浏览器中打开测试页的时候,我还是没有怀疑IE8,因为即使是IE5.5也是支持:first-letter伪类的。

叼着烟斗的名侦探说过:“除掉所有不可能的,留下来的,无论多么不合理,但它就是真相......!”是的,真相就是IE8 beta1不支持:first-letter(还有:first-line)。我希望这是beta1版本中的一处来不及修复的bug,因为在微软官方的IE5~IE8 CSS兼容表中,明确的标明了出去IE5不支持:first-letter外,其他版本一律支持。这一点,在许多博客中都被提及,例如怿飞的IE8 beta1 中的 CSS 属性。

如果你的兼容性检查列表中还没有IE8的名字,如果你觉得诸如首字下沉这样的额外视觉效果可有可无,那么你可以在这一行结束浏览了。但,如果你执着于此,希望IE8的用户也可以在你的网页上看到类似于报刊文章上的效果,你可以往下看。

在多次努力之后,我放弃折腾那可怜的css,IE8b1对于:first-letter的不支持,不是在css hack层面能解决的。我们只能求助于js。我们需要找到一个页面中第一个段落开始的地方,找到这个段落第一个字,让js将其处理为特殊样式:


复制代码
代码如下:

window.onload = initial;
function initial() {
var letter = document.getElementsByTagName('p')[0];
var word = letter.firstChild.nodeValue;
var num = word.substring(0,1);
var other = word.substring(1,word.length);
document.getElementsByTagName('p')[0].innerHTML= "<span id='first-letter-plus'>" + num + "</span>" + other;
}

原谅我的js水平,我始终无法直接定义num的方法,我只能给其添加一些标记,以至于代码如此臃肿,我相信一定有更简单、更强大的js方法。

接下来,我们只需要在css中这样定义:

复制代码
代码如下:

#demo #first-letter-plus { font-size:40px; font-family:"楷体_GB2312";
font-weight:bold; font-style: normal; line-height:1.2em; float:left;
padding:5px 2px 0 0; color:#c00; }

查看效果页面1,所有的浏览器都搞定了,这一切都建立在不关闭js的前提下。但是对于一些完美者来说,考虑到有人会关闭js运行浏览器时,我们需要再额外添加一些代码:

复制代码
代码如下:

#demo p:first-child:first-letter { font-size: 40px; font-family:"楷体_GB2312";
font-weight:bold; line-height:1.2em; float:left; padding:5px 2px 0 0;

这样在关闭js的情况下,FF、Opera以及Safari都可以正常显示应有的首字下沉效果,不过IE们就有些混乱,IE8b1天生不支持,无效果;IE7正常;IE6不识别:first-child:first-letter这样的用法;IE5.5神奇的识别了:first-letter,但是它忽略了:first-child,这导致了所有段落p都会有一个首字下沉的效果,这可不是我们排版上希望看到的。并且当你回复使用js的时候,在Opera中会产生一个有趣的现象,段落的前两个字都有了效果,查看效果页面2。这是因为在Opera中,第一个字包含在<span></span>中,效果由js实现,Opera认为p的:first-letter应该在<span></span>之后开始。

因此,我们需要改动一下css:

复制代码
代码如下:

#demo p > *:first-child:first-letter { font-size: 40px; font-family:"楷体_GB2312";
font-weight:bold; line-height:1.2em; float:left; padding:5px 2px 0 0; color:#c00; }

这样以来,Opera中的奇怪现象也消失了。查看这个效果页面3。

说实话,我并不推荐使用如此繁复的代码(效果页面2和3)实现一个首字下沉。就好像在html中不推荐使用<q></q>那样。直接使用效果页面1的代码,让js去做这个在IE中找不到平衡点的事情——js开启,大家都有同样的效果;js关闭,效果也一起消失。因为它不仅使得IE8可以应用首字下沉的效果,也避免了其他版本IE在对:first-child:first-letter这样的一个css应用上的处理差异(直接使用:first-letter会让每个段落开头都有一个首字下沉效果,这也是为什么振之在他的博客正文中不使用这个效果的原因)。

上帝保佑,IE8正式推出的时候可以支持:first-child(还有:first-line)。

更多精彩内容其他人还在看

CSS配合JavaScript做酷的动态页面效果

  利用CSS配合JavaScript的可以做很多更酷的动态页面效果,在本教程的最后给大家简单介绍一下CSS配合JS的应用。首先,要搞清楚事件和动作的概念。在客户端脚本中,JavaScript 通过对事件进行响应来获得与用户的交互。例如,当用户单击一个按钮或者在某段文字上移动鼠标
收藏 0 赞 0 分享

WEB标准,Web前端开发工程师必备技术列表

  想要打造并拥有一流的Web产品开发团队,在团队成员基础能力上一定要下功夫。对于Web前端产品开发来说,仅仅掌握Web1.0时代简单的"网页套接"是完全不够的。我结合自己的团队配备,特此罗列了Web前端产品工程师所涉及的技能列表如下:   通过许多实际项目,
收藏 0 赞 0 分享

用CSS制作Alpha滤镜测试板

alpha滤镜给制作网页特效提供了较大的创作空间,但由于它控制参数较多,在实际应用时,为了确定一组合适的参数值,不得不反复调整修改,在编辑窗口和预览窗口来回倒腾,甚是麻烦,本文介绍了一种简单的方法。制作一个“Alpha滤镜参数测试板”,在测试板上输入参数
收藏 0 赞 0 分享

非常流行的所谓的气泡窗口

普通的Alt无法自定义风格,而Sweet Titles通过JS脚本与CSS的集合.自定义了这种伪Alt风格. 前一段时间非常流行的,就所谓的气泡窗口(鼠标移到链接处出现的). 我们这里实现的用的是Sweet Titles的插件.显示效果完全由CSS控制.. 先下载Sweet Ti
收藏 0 赞 0 分享

CSS教程:li和ul标签用法举例

LI代码的格式化: A).运用CSS格式化列表符: ul li{ list-style-type:none; } B).如果你想将列表符换成图像,则: ul li{ list-style-type:none; list-style-image: url(/blog/images/
收藏 0 赞 0 分享

CSS教程:CSS中的定位(position)

  使用CSS来定位页面内层的位置,一直是比较难以掌握的事情,很多时候,往往被绝对定位的元素,总是以浏览器的左上角为坐标原点,此时,如果浏览器的大小改变,被定义的层就会偏离设计想要的位置,让人很挠头。   其实,要想控制好层的绝对定位,只要理解CSS中关于定位
收藏 0 赞 0 分享

CSS教程:盒模型(BOX Model)

  如果想熟练掌握DIV和CSS的布局方法,首先要对盒模型有足够的了解。每个HTML元素都可以看作一个装了东西的盒子,盒子里面的内容到盒子的边框之间的距离即填充(padding),盒子本身有边框(border),而盒子边框外和其他盒子之间,还有边界(margin),如图1所示。
收藏 0 赞 0 分享

无延迟翻滚的图形与CSS混合风格按钮

  在一个具有图形背景的按钮中添加CSS风格的文本,这种建立按钮的方法结合了具有CSS翻滚(CSS rollover)标记的开发速度和效率,从而有效地提高按钮外表图像的三维效果。   相比于常规的图形按钮,这些图形/CSS混合按钮可易于建立和载入,因为你只需要为空白按钮外面
收藏 0 赞 0 分享

css里expression实现界面对象的批量控制

用过css样式我们就知道, 可以定义一批对象的class属性来指定同一个样式来统一界面. 但如何统一同类型的对象的事件? 比如:界面有无数个 <img src="**.jpg"> 如何实现鼠标经过此图片, 图片的src变成是**_over.jpg?
收藏 0 赞 0 分享

CSS教程:水平对齐(text-align)

  水平对齐(text-align),用以设定元素内文本的水平对齐方式。   1.语法   text-align具体参数如下: 语法:text-align:left|right|center|justify 说明:设定元素内文本的水平对齐方式。 参数:left:左
收藏 0 赞 0 分享
查看更多