CSS的核心选择器

 

 我们能真切地感觉到,选择器是CSS的核心部分。如果没有它们的话,我们除了把属性嵌入到每个元素里,就没有其他办法能把样式应用在元素上了,那真是太糟糕了。通过选择器赋予的选择任何形式任何种类元素的能力,我们可以只用很少的几行CSS完成很大一部分样式设置工作。

本章我们将深入探讨如何巧妙地使用选择器,并且概述一下哪些类型的选择器被普遍支持且应用最为广泛。 

伪类与伪元素

CSS中有两种“伪”字头的选择器:伪类(pseudo-class)和伪元素(pseudo-element)。CSS2.1中的伪类有:

 :link——未访问过的链接;

 :visited——访问过的链接;

 :hover——鼠标悬停的元素;

 :focus——获取焦点的元素;

 :active——激活的元素(例如一个被单击的链接元素);

 :first-child——作为其他元素第一个子元素的元素;

 :lang()——根据元素的lang属性确定的元素。

CSS2.1中的伪元素有:

 ::first-line

 ::first-letter

 ::before

 ::after

那么区别在哪儿呢?区别就在于这些伪选择器影响文档的方式不同。伪类的表现有点儿像给文档添加类,而伪元素的效果就好像有元素被插入到了文档中。

::first-letter为例,假设你要把每个h1的第一个字母增大到其他字母的两倍半(如图

2-1所示),很简单:

 

h1::first-letter {font-size: 250%;}

这就仿佛CSS和标记被修改成了这样:

h1 first-letter {font-size: 250%;}

<h1><first-letter>H</first-letter>owdy, y’all!</h1>


2-1 放大h1的第一个字母

 

这真的是浏览器内部真实发生的情况吗?谁知道呢,反正结果确实像是发生了这种情况,因此才有了“伪元素”这个名字。

类似地,伪类的表现就像是它们使文档中的元素被添加了新的类。例如,想象一下若对于每一个作为其他元素第一个子元素的元素,浏览器给它们都附加了一个名为first-child的类,然后就可以像下面这样为它们应用样式了:

 

li.first-child {border-left: none;}

只需要简单地把点改成冒号就变成了li:first-child,就可以得到同样的最终效果,而不用费力把类添加到所有标记上。

有时还会看到伪元素使用双冒号的语法,这是在CSS2.1之后引入的。截至撰写本书之时,还没有哪个浏览器要求你必须在伪元素前面使用双冒号的,一个冒号就可以了。

另外提醒读者,CSS3增加了如下一些伪类,截至撰写本书之时,它们中的大部分还没有被广泛地支持:

 :target

 :root

 :nth-child()

 :nth-of-type()

 :nth-last-of-type()

 :first-of-type

 :last-of-type

 :only-of-type

 :only-child

 :last-child

 :empty

 :not()

 :enabled

 :disabled

 :checked

 

为目标元素添加样式

当希望指向文档中的某个片段时,目标(target)会非常有用。什么,怎么实现?其实非常简单:

<a href="http://example.com/law.html#sec2-7">Section 2.7</a>

任何人单击这个链接(如果浏览器处理正确的话)将不止跳转到目标页,而且还会跳到页面中文档片段标识符(地址中的#sec2-7部分)出现的地方。这有时是通过锚点(anchor)实现的,但是只用ID来实现会更好一些。例如有如下两种场景:

<h3><a name="sec2-7">Exceptions</a></h3>

<h3 id="sec2-7">Exceptions</h3>

这两种情况下,当浏览器跳到了文档中的目标位置时,都不会有任何视觉提示告知你已经到达了目标位置,而使用:target伪类就可以给出视觉提示。例如,若想让作为某个文档片段标识符目标的h3拥有特定的提示效果(如图2-2所示),可以这样写:

h3:target {color: maroon;

background: #FFA;}


2-2 突出显示目标元素(另见彩插图2-2

 

当然,你或许想把这个样式应用到任何目标元素上,而不管它是什么元素,那么只需要把h3换成一个通用选择器即可,就像这样:

*:target {color: maroon;

background: #FFA;}

 

从技术上讲,这种情况下通用选择器也是可选的,可以把这个选择器简单地写成:target

如果想让目标样式多一点Web 2.0的感觉,还可以设置一个渐隐背景的效果。你懂的,就是那种“你已经完成了某项操作,所以页面上的一块背景会从黄色变到白色,让你知道已经完成了该项操作”的效果。通过:target和一个动画GIF可以很容易地实现这种效果,只需要创建一个从黄色渐变到白色(如果白色是你网站的背景色的话)的动画并且把它当做背景图像。

*:target {background: url(/pix/yellow-fade.gif);}

 

特殊性 

你很难快速地把特殊性(specificity)这个词读3遍,而若想彻底地掌握它甚至更难。但是,它却是理解CSS规则之间相互作用的关键。

特殊性是一个选择器“特殊程度”的数字表示,有3样东西经常被用来确定选择器的特殊性:

 每个元素描述符贡献0,0,0,1

 每个类、伪类或者属性描述符贡献0,0,1,0

 每个ID描述符贡献0,1,0,0

先不要抓狂,来看几个小例子。

div ul ul li 0,0,0,4 4个元素描述符

div.aside ul li 0,0,1,3 1个类描述符,3个元素描述符

a:hover 0,0,1,1 1个伪类描述符,1个元素描述符

div.navlinks a:hover 0,0,2,2 1个伪类描述符,1个类描述符,2个元素描述符

#title em 0,1,0,1 1ID描述符,1个元素描述符

h1#title em 0,1,0,2 1ID描述符,2个元素描述符

希望这些能够帮助你理解特殊性是如何计算的。那么,为什么是逗号呢?因为可以这么说,每个“级别”的特殊性的值都是相互独立的。因此,具有一个单独的类描述符的选择器会比由13个元素描述符组成的选择器拥有更高的特殊性。

.aside /* 0,0,1,0 */

div table tbody tr td div ul li ol li ul li pre /* 0,0,0,13 */

第一个选择器左数第三位的“1”胜过了第二个选择器同样位置的“0”,基于这样的事实,第二个选择器第四位的“13”(在这个非常有限的例子中)就毫无意义了。逗号可以使我们看得更清楚,否则选择器的特殊性可能被写成“10”和“13”,从而造成后者特殊性更高的假象(在CSS的早期还没有引入逗号分隔符时,这是经常出现的误解)。

还有另外一种常见的误解,就是特殊性的结构相近问题。例如,假设有如下两个选择器:

ul li {font-style: normal;}

html li {font-style: italic;}

它们当中哪个会赢呢?它们都有两个元素描述符,这意味着它们的特殊性都是0,0,0,2。其实,后写的会赢,与html元素相比ul元素在文档中的位置离li元素更近也不管用。特殊性只是单纯的数值,它不会以任何方式评估页面的结构。结果,列表元素将全部变成斜体,因为当特殊性相等时后声明的规则会胜出。

因为我说过有3样东西影响特殊性,所以你或许想知道特殊性标识符第一位的0是干嘛用的。其实,第一个0是用于行内样式(inline style)的,且仅用于行内样式。因此,如果有下面这样的样式和标记,则div的背景将会是蓝色。

div#header {background: purple;} /* 0,1,0,0 */

<div id="header" style="background: blue;"> <!-- 1,0,0,0 -->

 

——摘自《精彩绝伦的CSS》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值