CSS 选择器

1. 选择器语法

https://github.com/leeluolee/nes/wiki/Selector

一个选择器是一个或多个被连结符分隔的简单选择器序列组成的链。一个伪元素可能会附加到选择器中的最后一个简单选择器序列。

一个简单选择器序列是没有被连结符分隔的简单选择器组成的链。它总是以一个类型选择器通用选择器开始。除了类型选择器和通用选择器,没有其他类型的选择器允许在序列中。

一个简单选择器可以是类型选择器通用选择器属性选择器类选择器id选择器伪类

连结符可以是:空白、>+~

一个文档树的元素被选择器所代表,它是选择器的主题(subject)。一个选择器组成了一个简单选择器的单一序列,代表了任何满足它需求的元素。前面加上其他的简单选择器序列,且序列中的连结符施加了额外的匹配限制,所以一个选择器的主题总是最后一个简单选择器序列所代表的元素的子集。

一个空的选择器,没有包含简单选择器序列和伪元素,是一个无效的选择器

选择器中的字符可以根据在CSS2中相同的转义规则并通过来转义。

2. 选择器组

一个逗号分隔的选择器列表表示了被任何单一选择器选择的所有元素的组合。例如,在CSS中当一些选择器共享相同的声明时,它们可以组合成一个逗号分隔的列表。空格可能出现在逗号的前面或后面。

CSS实例:

h1 { font-family: sans-serif }
h2 { font-family: sans-serif }
h3 { font-family: sans-serif }

上面等价于:

h1, h2, h3 { font-family: sans-serif }

注意:在本例中等价是真的,因为所有的选择器是有效的选择器。如果选择器中的一个是无效的选择器,那么整个声明是无效的。

无效的CSS实例:

h1 { font-family: sans-serif }
h2..foo { font-family: sans-serif }
h3 { font-family: sans-serif }

不等价于:

h1, h2..foo, h3 { font-family: sans-serif }

在实际应用中也没有人这样写了。否则肯定早晚开除了。

3. 简单选择器

3.1 类型选择器

一个类型选择器是文档语言元素类型的名称,并使用CSS qualified names语法。一个类型选择器表示了在文档树中元素类型的实例。

实例

以下的选择器表示了在文档树中的h1元素:

h1

3.1.1 类型选择器和命名空间

类型选择器允许一个可选的命名空间组件:一个命名空间前缀被定义在元素名的前面,并通过|符号来分隔。

命名空间可能为空,代表了选择器没有命名空间。

一个*可被用作为命名空间前缀,表明代表了元素的所有命名空间。

元素类型选择器在没有命名空间组件时代表了元素不会考虑元素的命名空间(等价于*|),除非定义了一个默认的命名空间。如果一个默认命名空间被声明,这些元素会代表在默认命名空间中的元素。

那怎么定义默认命名空间呢?

@namespace "http://www.w3.org/1999/xhtml";
@namespace svg "http://www.w3.org/2000/svg";

上面的http://www.w3.org/1999/xhtml就为默认的命名空间。

总结(要注意的是|前后没有空格的哟):

ns|E 元素为E且在命名空间ns

*|E 元素为E且在任何命名空间中

|E 元素为E且没有命名空间

E 如果没有为选择器定义默认的命名空间,这个等价于*|E。否则等价于ns|E,且ns为默认的命名空间。

CSS实例:

@namespace foo url(http://www.example.com);
 foo|h1 { color: blue }  /* first rule */
 foo|* { color: yellow } /* second rule */
 |h1 { color: red }      /* ...*/
 *|h1 { color: green }
 h1 { color: green }

第一条规则只会匹配在http://www.example.com命名空间中的h1元素。 第二条规则会匹配在http://www.example.com命名空间中的所有元素。 第三条规则只会匹配没有命名空间的h1元素。 第四条规则会匹配在任何命名空间中的h1元素。 第五条规则等价于第四条规则,因为没有默认的命名空间被定义。

3.2 通用选择器

通用选择器,用*来表示,它代表了任何元素类型的限定名。它代表了在文档树中的任何命名空间的任何单一元素,如果没有为选择器指定默认的命名空间。如果指定了默认的命名空间,可以看下面的通用选择器和命名空间

如果一个通用选择器不是选择器序列的唯一组件,或者它后面紧跟了伪元素,那么*可以省略,通用选择器隐含的表示存在。

实例:

  • *[hreflang|=en][hreflang|=en]是等价的
  • *.warning.warning是等价的
  • *#myid#myid是等价的

3.2.1 通用选择器和命名空间

通用选择器允许一个可选的命名空间组件。它可以按照以下方式来使用:

ns|*ns命名空间中的所有元素

*|* 所有元素

|* 所有没有命名空间的元素

* 如果没有默认指定默认的命名空间,则等价于*|*,否则等价于ns|*,如果ns为默认的命名空间。

3.3 属性选择器

选择器允许表示元素的属性。当选择器被用作为一个表达式来匹配元素时,属性选择器必须认为匹配元素如果元素有一个属性且匹配属性选择器所代表的属性时。

3.3.1 属性存在和值选择器

CSS2介绍了四种属性选择器:

[att] 代表了元素有一个att属性,不管属性的值是什么。

[att=val] 代表了元素有一个att属性,且值为val。这种可以用于选择例如:input[type="text"]

[att~=val] 代表了元素有一个att属性,且它的值为空白分隔的列表,其中的一个值为val,如果选择器中的val包含了空白,它永远不会代表什么。同样,如果val为空字符串,它永远不会代表什么。

[att|=val] 代表了元素有一个att属性,且它的值为val或者val紧跟着-

实例:

下面的属性选择器代表了h1元素,且它有一个title属性,且不管值为多少:

h1[title]

下面的例子选择器代表了一个span元素它的class属性的值为example

span[class="example"]

下面的选择器代表了一个a元素,且它的hreflang属性值为enen-US

a[hreflang|="en"]

3.3.2 子字符串匹配属性选择器

三个附加的属性选择器被提供给匹配属性值的子字符串:

[att^=val] 代表了元素有一个att属性,且值以val前缀开始。如果val为空字符串,则这个选择器不会代表任何元素

[att$=val] 代表了元素有一个att属性,且值以val后缀结束。如果val为空字符串,则这个选择器不会代表任何元素

[att*=val] 代表了元素有一个att属性,且值包含至少子字符串val的一个实例。如果val为空字符串,则这个选择器不会代表任何元素

实例:

下面的选择器代表了一个HTMLobject,引用了一个图片:

object[type^="image/"]

下面的选择器代表了一个HTML链接a,且它的href属性以.html结尾:

a[href$=".html"]

下面的选择器代表了HTML段落中title属性包含了子字符串hello

p[title*="hello"]

3.3.3 属性选择器和命名空间

在属性选择器中的属性名是以CSS限定名给出:先前已声明的命名空间前缀可预先准备给由命名空间分隔符|分隔的属性名。为了保持命名空间在XML中的推荐,默认的命名空间不会应用到属性中,因此,没有命名空间组件的属性选择器只应用到那些没有命名空间的属性。一个*可能被用于命名空间前缀以表明该选择器可匹配所有属性名而不用考虑属性的命名空间。

一个属性选择器有一个属性名包含了命名空间前缀,但是该命名空间没有在之前定义,这时该属性选择器是一个无效的选择器。

CSS实例:

@namespace foo "http://www.example.com";
[foo|att=val] { color: blue }
[*|att] { color: yellow }
[|att] { color: green }
[att] { color: green }

第一条规则只匹配有在http://www.example.com命名空间下的属性att,且值为val的元素。

第二条规则只匹配具有属性att,且不管属性的命名空间。

最后两条规则是等价的,且只匹配具有属性att,且该属性不在任何命名空间下的元素。

3.3.4 在DTDs中的默认属性值

属性选择器代表了在文档树中的属性值。文档树如何构建是在选择器之外的。在某些文档格式中,默认的属性值可以定义在DTD或其他地方,如果它们出现在文档树中的话,这些只能通过属性选择器来选择。选择器的设计应该使它们工作,不管默认值是否包含在文档树中。

例如,一个XML的用户代理可能并不需要去读取一个DTD外部子集,但是需要在文档的内部子集寻找默认属性值(看这里:XML10)。取决于用户代理,一个定义在DTD的外部子集的默认的属性值可能会或可能不会出现在文档树中。

一个识别XML命名空间的用户代理可能不需要利用它的对于那个命名空间的认知来对待默认的属性值,就好像它们就在文档中。(例如,一个XHTML的用户代理不需要利用它内置的该XHTML DTD的认知)

实例:

考虑一个元素example,它有一个属性radix,且其默认值为decimalDTD片段可能为:

<!ATTLIST EXAMPLE radix (decimal,octal) "decimal">

如果样式表包含了这些规则:

EXAMPLE[radix=decimal] { /*... default property settings ...*/ }
EXAMPLE[radix=octal]   { /*... other settings...*/ }

第一条规则可能不会匹配那些radix属性被设置为默认值的元素,即为明确设置。为了捕获所有情况,属性选择器的默认值必须被舍弃:

EXAMPLE                { /*... default property settings ...*/ }
EXAMPLE[radix=octal]   { /*... other settings...*/ }

3.4 类选择器

HTML工作,作者可能会使用句点符号(也就是.)来代替~=符号表示class属性。因此,对于HTMLdiv.valuediv[class~=value]是具有同样的含义的。该属性值必须紧跟在.符号后面。

如果用户代理具有命名空间特定的知识,且允许它确定哪个属性是class属性用于各个命名空间,用户代理可能使用.符号在XML文档中应用选择器。

CSS实例:

我们可以通过以下方式来分配样式给所有class~="pastoral"的元素:

*.pastoral { color: green }  /* all elements with class~=pastoral */

或者只是:

.pastoral { color: green }  /* all elements with class~=pastoral */

以下只分配样式给所有class~="pastoral"h1元素:

H1.pastoral { color: green }  /* H1 elements with class~=pastoral */

3.5 ID选择器

文档语言可以包含声明为ID类型的属性。ID类型属性的特殊之处在于在一致性的文档中没有两个这样的属性可以有相同的值,且不管携带该属性的元素类型;无论什么文档语言,一个ID类型属性可被用于唯一地标识其元素。

ID选择器是以#开头,然后紧跟着ID值。

实例:

以下ID选择器代表了一个h1元素,且它的id属性值为chapter1

h1#chapter1

不过很少会像上面这样写,一般是像下面这样:

#chapter1

3.6 伪类

伪类的概念被引入以允许选择位于该文档树以外或者使用其他简单选择器不能表达的信息。

一个伪类总是包含:跟着伪类的名称和一个可选的值被放在圆括号之间。

伪类中允许包含在选择器中的所有简单选择器序列。伪类可以出现在简单选择器序列的任何地方,类型选择器和通用选择器(可能省略)后面。伪类名是不区分大小写。一些伪类是相互排斥的,而另一些可以同时施加到相同的元素。伪类可能是动态的,在这个意义上,元素可能获得或失去一个伪类当用户与文档进行交互的时候。

3.6.1 动态伪类

动态伪类在特性上分类元素,除了它们的名字、属性或内容,原则上特性不能从文档树中推断出来。

动态伪类不会出现在文档源或文档树中。

3.6.1.1 链接伪类::link:visited

用户代理通常显示未访问的链接不同于之前访问过的。选择器提供了伪类:link:visited来区分它们。

  • :link伪类应用在那些没有被访问过的链接
  • :visited伪类应用在那些已经被用户访问过的链接

经过一定的时间,用户代理可能选择返回一个访问过的链接为:link状态。

这两种状态是互斥的。

实例:

下面的选择器代表了有一个external类的链接,且被访问过:

a.external:visited

用户代理可能会因此对待所有的链接为未访问链接,或者采取其他措施以保护用户的隐私,而对访问和未访问链接渲染出不同。

3.6.1.2 用户动作伪类:hover:active:focus

交互式用户代理有时会为了响应用户操作而改变呈现。选择器提供了三个伪类来选择这些用户正在作用的元素。

  • :hover伪类应用在当用户通过定位设备来指定元素,但不一定激活它时。例如,一个视觉用户代理可以应用伪类当光标悬停到元素所生成的盒子上时。用户代理不支持交互式媒体的不需要支持该伪类。支持交互式媒体的一些用户代理可能无法支持这个伪类。
  • :active伪类应用在正被用户激活的元素上。例如,在用户按下鼠标按钮和释放它之间。在多于一个鼠标按钮的系统,:active仅应用在主激活按钮(通常是鼠标左键),以及它们的任意别名。
  • :focus伪类应用在获得焦点的元素

这些伪类不是相互排斥的。一个元素可以在相同的时间匹配的几个伪类。

选择器没有定义当元素的父亲也在:active:hover状态时。

实例:

a:link    /* unvisited links */
a:visited /* visited links */
a:hover   /* user hovers */
a:active  /* active links */

或者结合多个动态伪类:

a:focus
a:focus:hover

3.6.2 目标伪类:target

一些URIs会引用资源内的一个位置。这种类型的URI是以#紧跟锚标识符结束。

有片段标识浮的URIs链接到文档内的某个元素,被称为目标元素。举例来说,这里给出了一个URI指向文档中一个名为section_2的锚。

http://example.com/html/top.html#section_2

一个目标元素可以使用:target伪类来表示。如果文档的URI没有片段标识符,则该文档没有目标元素。

实例:

p.note:target

这个选择器代表了一个p标签,且它有一个类note,且它是指定URI的目标元素时。

3.6.3 语言伪类:lang

如果文档语言指定了一个元素的人类语言如何确定,则可以使用选择器来代表基于该语言的元素。例如,在HTML中,语言是由lang属性和从meta元素的信息或HTTP协议联合决定的。XML使用一个叫做xml:lang的属性,并且还可能有其他的文档语言特定的方法,用于确定使用的语言。

伪类:lang(C)代表了在语言C中的元素。一个元素是否通过:lang被代表是完全基于元素的语言值是否和标识符C相等,或者是以标识符C开始并紧跟着-。对C和元素语言值的匹配是不区分大小写的。标识符C不必须是一个有效的语言名称。

C必须是一个有效的CSS标识符,且不能为空。

实例:

html:lang(fr-be)
html:lang(de)
:lang(fr-be) > q
:lang(de) > q

3.6.4 UI元素状态伪类

3.6.4.1 :enabled:disabled伪类

:enabled伪类代表了处于激活状态的用户界面元素;这些元素都有相应的禁用状态。

相反地,:disabled伪类代表了处于禁用状态的用户界面元素;这些元素都有相应的激活状态。

什么构成激活状态、禁用状态和用户界面元素是语言决定的。在一个典型的文档中大多数元素即不会是:enabled也不会是:disabled

那什么元素有这种状态呢,inputtextarea等元素。

<style>
input:disabled {
    border: 1px solid blue;
}
input:enabled {
    border: 1px solid red;
}
</style>

<input type="text" disabled>
<input type="text">
3.6.4.2 :checked伪类

单选框和复选框元素可以被用户切换。一些菜单项被勾选,当用户选择它们的时候。:checked伪类就是应用在这些有selectedchecked属性的元素,这些元素包含checkboxradiooption等。

实例:

<style>
input:checked + label {
    color: red;
}
</style>

<input type="checkbox">
<label>checkbox</label>
<input type="radio">
<label>radio</label>
3.6.4.3 :indeterminate伪类

这个是对于radiocheckbox有时处于一种模糊的状态,即不是checked,也不是unchecked

3.6.5 结构伪类

选择器引入了结构伪类的概念,允许基于在文档树中确定的信息来选择,但是不能通过其他简单选择器或连结符来表示。

当在它父亲的孩子列表中计算一个元素的位置时,独立文本和其他非元素节点不计算在内当计算在其父亲的孩子列表中的元素的位置,该指数的编号从1开始。

3.6.5.1 :root伪类

:root伪类代表了文档的根元素。在HTML4中总是html元素。

3.6.5.2 :nth-child()伪类

:nth-child(an+b)伪类可以代表在文档树中在它之前的有an+b-1个兄弟的元素,n可以为任何的正数或0,且有一个父元素。对于大于0的ab,这有效的将元素的孩子分成每组a个元素,然后选择每组中的第b个元素。例如,这使得选择器解决table中每隔一行的问题,并可以用于段落文本中每四个交替颜色。ab的值必须为整数。元素的子元素的索引是从1开始(要注意不是JavaScript等语言的0哟)。

除此之外,:nth-child()还可以接受oddeven作为参数。odd其实等价于2n+1even其实等价于2n

:nth-child()的参数必须匹配以下语法规则,INTEGER匹配[0-9]+,标记的其余部分是由Lexical scanner给出。

nth
  : S* [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? |
         ['-'|'+']? INTEGER | {O}{D}{D} | {E}{V}{E}{N} ] S*
  ;

实例:

tr:nth-child(2n+1) /* represents every odd row of an HTML table */
tr:nth-child(odd)  /* same */
tr:nth-child(2n+0) /* represents every even row of an HTML table */
tr:nth-child(even) /* same */

/* Alternate paragraph colours in CSS */
p:nth-child(4n+1) { color: navy; }
p:nth-child(4n+2) { color: green; }
p:nth-child(4n+3) { color: maroon; }
p:nth-child(4n+4) { color: purple; }

b的值前面有一个负号,则+字符必须从表达式中移除。

实例:

:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
:nth-child(10n+9)  /* Same */
:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */

a=0,则an部分可以不包含。当an未包含且b为非负数,则在b前面的+字符也可省略。

实例:

foo:nth-child(0n+5)   /* represents an element foo that is the 5th child
                         of its parent element */
foo:nth-child(5)      /* same */

a=1a=-1,数字可以从规则中省略。

实例:

bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
bar:nth-child(n+0)    /* same */
bar:nth-child(n)      /* same */
bar                   /* same but lower specificity (0,0,1) */

b=0,则每一个第a个元素被选择。在这种情况,+b-b部分可能省略,除非a部分已经被省略。

实例:

tr:nth-child(2n+0) /* represents every even row of an HTML table */
tr:nth-child(2n) /* same */

空白是允许出现在(之后)之前,也可以出现在+-任何一方以分割anb部分,当它们都没有省略的时候。

有效的实例:

:nth-child( 3n + 1 )
:nth-child( +3n - 2 )
:nth-child( -n+ 6)
:nth-child( +6 )

下面是无效的:

:nth-child(3 n)
:nth-child(+ 2n)
:nth-child(+ 2)

ab都为0时,该伪类没有选择文档树中的任何元素。

a的值可能为负数,但是只有在an+b的正数位置才可以被选择。

实例:

html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */
3.6.5.3 :nth-last-child()伪类

其实这个伪类和前面的:nth-child()是很类似的,它只是从最后一个元素开始计算索引。:nth-last-child(an+b)伪类可以代表在文档树中在它之的有an+b-1个兄弟的元素,n可以为任何的正数或0,且有一个父元素。这个可以参考上面的:nth-child()语法。它同样接受oddeven作为参数。

实例:

tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */

foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
                              counting from the last one */
3.6.5.4 :nth-of-type()伪类

这个伪类其实可以看成对:nth-child()施加了一个限制,那就是元素类型必须相同。:nth-of-type(an+b)伪类可以代表在文档树中在它之前有an+b-1个兄弟,且元素类型必须相同的元素,n可以为任何的正数或0,且有一个父元素。这个可以参考上面的:nth-child()语法。它同样接受oddeven作为参数。

实例:

img:nth-of-type(2n+1) { float: right; }
img:nth-of-type(2n) { float: left; }

再看一个例子:

<style>
/*#demo p:nth-of-type(even) {
    color: red;
}*/
#demo :nth-child(even) {
    color: blue;
}
</style>

<div id="demo">
    <p>1</p>
    <p>2</p>
    <p>3</p>
    <a href="">4</a>
    <p>5</p>
    <p>6</p>
    <p>7</p>
</div>

你可以在浏览器中对比以下这两个选择器的效果哟。

3.6.5.5 :nth-last-of-type()伪类

这个伪类和:nth-of-type(),只是从最后一个元素开始计算索引啦。:nth-last-of-type(an+b)伪类可以代表在文档树中在它之an+b-1个兄弟,且元素类型必须相同的元素,n可以为任何的正数或0,且有一个父元素。这个可以参考上面的:nth-child()语法。它同样接受oddeven作为参数。

实例:

body > h2:nth-of-type(n+2):nth-last-of-type(n+2)
3.6.5.6 :first-child伪类

:nth-child(1)相同。:first-child伪类代表一个元素为其他元素的第一个子元素。

实例:

下面的例子代表了一个p元素是div中的第一个元素。

div > p:first-child

选择器可以匹配下面HTML中div中的p

<p> The last P before the note.</p>
<div class="note">
   <p> The first P inside the note.</p>
</div>

但是不能匹配下面divp元素,因为p不是div中的第一个子元素。

<p> The last P before the note.</p>
<div class="note">
   <h2> Note </h2>
   <p> The first P inside the note.</p>
</div>
3.6.5.7 :last-child伪类

:nth-last-child(1)相同。:last-child伪类代表一个元素为其他元素的最后一个子元素。

实例:

ol > li:last-child
3.6.5.8 :first-of-type伪类

:nth-of-type(1)相同。:first-of-type伪类代表一个元素,它是父元素中第一个具有相同元素名的元素。

实例:

dl dt:first-of-type {
    color: red;
}

<dl>
 <dt>gigogne</dt>
 <dd>
  <dl>
   <dt>fusée</dt>
   <dd>multistage rocket</dd>
   <dt>table</dt>
   <dd>nest of tables</dd>
  </dl>
 </dd>
</dl>
3.6.5.9 :last-of-type伪类

:nth-last-of-type(1)相同。:last-of-type伪类代表一个元素,它是父元素中最后一个具有相同元素名的元素。

实例:

tr > td:last-of-type
3.6.5.10 :only-child伪类

该伪类代表了一个元素,它的父元素除了它没有其他元素。其实等价于:first-child:last-child

3.6.5.11 :only-of-type伪类

该伪类代表了一个元素,它的父元素除了它没有其他元素,且和指定的元素类型相同。等价于:first-of-type:last-of-type

3.6.5.12 :empty伪类

:empty伪类代表了一个元素始终没有子元素。

实例:

p:empty可以代表以下html片段:

<p></p>

foo:empty不能代表以下片段:

<foo>bar</foo>
<foo><bar>bla</bar></foo>
<foo>this is not <bar>:empty</bar></foo>

3.6.6 空白

本节有意留为空白。(本节之前定义了一个:contains()伪类)

3.6.7 否定伪类

否定伪类,:not(x)是一个功能性的符号,它接受一个简单选择器作为参数。它代表了这些不是参数所代表的元素。

否定不能嵌套,:not(:not(...))是无效的。要注意当伪元素不是简单选择器,所以它们不是:not()的有效参数。

实例:

以下选择器匹配在HTML中没有被禁用的按钮:

button:not([DISABLED])

默认的命名空间声明不会影响否定伪类的参数,除非该参数是一个通用选择器或类型选择器。

实例:

假设默认的命名空间为http://example.com/,下面的选择器代表了所有不在该命名空间的元素:

*|*:not(*)

4. 伪元素

在文档语言规定之外,伪元素创建了一个关于文档树的抽象引用。例如,文档语言不提供机制来访问的一个元素的内容的第一个字母或第一行。伪元素允许作者引用这个本来无法访问的信息。伪元素还能提供作者一种方式去引用源文档中不存在的内容(::before::after)。

一个伪元素是由::跟着伪元素名称组成的。

::符号在文档中被引入是为了在伪类和伪元素之间建立一个区别。为了与现有的样式表的兼容性,用户代理必须同样接受一个冒号:的写法。

4.1 ::first-line伪元素

::first-line伪元素描述了元素的内容中被格式化的第一行。

CSS实例:

p::first-line { text-transform: uppercase }

上面的规则意思为将每个p元素的第一行的每个字母变为大写。

注意,第一行的长度取决于许多因素,包括该页面的宽度,字体大小等。因此,一个普通的HTML段落,如:

<P>This is a somewhat long HTML 
paragraph that will be broken into several 
lines. The first line will be identified
by a fictional tag sequence. The other lines 
will be treated as ordinary lines in the 
paragraph.</P>

其中折行如下所示:

THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
will be broken into several lines. The first
line will be identified by a fictional tag 
sequence. The other lines will be treated as 
ordinary lines in the paragraph.

该段落可能可能被用户代理重写,包括虚构的标签::first-line。这个虚构的标签序列有助于说明属性如何继承。

<P><P::first-line> This is a somewhat long HTML 
paragraph that </P::first-line> will be broken into several
lines. The first line will be identified 
by a fictional tag sequence. The other lines 
will be treated as ordinary lines in the 
paragraph.</P>

如果伪元素折断了一个真实的元素,所需的效果通常被描述为一个虚构的标签序列关闭,然后重新打开该元素。例如:

<P><SPAN class="test"> This is a somewhat long HTML
paragraph that will be broken into several
lines.</SPAN> The first line will be identified
by a fictional tag sequence. The other lines 
will be treated as ordinary lines in the 
paragraph.</P>

用户代理会像下面这样处理:

<P><P::first-line><SPAN class="test"> This is a
somewhat long HTML
paragraph that will </SPAN></P::first-line><SPAN class="test"> be
broken into several
lines.</SPAN> The first line will be identified
by a fictional tag sequence. The other lines
will be treated as ordinary lines in the 
paragraph.</P>

4.1.1 CSS中格式化的第一行的定义

在CSS中,::first-line伪元素只能在block-like容器上有效果,这些容器有block boxinline-blocktable-captiontable-cell

一个元素的格式化第一行可能发生在相同流的一个block-level后代中(例如,一个block-level后代没有脱离流)。例如,在<DIV><P>This line...</P></DIV>DIV的第一行为p元素的第一行。

table-cellinline-block的第一行不能成为一个祖先元素的格式化的第一行。因此,在<DIV><P STYLE="display: inline-block">Hello<BR>Goodbye</P> etcetera</DIV>中,DIV的格式化第一行不是Hello的那一行。

一个用户代理应当表现的就好像::first-line的虚拟开始标签伪元素被嵌套到最内层的block-level元素中。例如:

<DIV>
  <P>First paragraph</P>
  <P>Second paragraph</P>
</DIV>

加上虚拟标签后:

<DIV>
  <P><DIV::first-line><P::first-line>First paragraph</P::first-line></DIV::first-line></P>
  <P><P::first-line>Second paragraph</P::first-line></P>
</DIV>

::first-line伪元素类似于一个inline-level元素,但有一定的限制。以下CSS属性应用到一个::first-line伪元素:字体属性、背景属性、颜色属性、word-spacingletter-spacingtext-decorationvertical-aligntext-transformline-height。用户代理也可能应用其他属性。

在CSS继承时,发生在第一行的子元素的一部分只从::first-line伪元素继承::first-line上可应用的属性。对于所有的其他属性,继承时从第一行伪元素的非鱼伪元素父元素中继承。

4.2 ::first-letter伪元素

::first-letter代表了一个元素的第一个字母,如果在该行中在它前面没有任何其他内容。::first-letter伪元素可能被用于首字母大写等用途。

标点符号,即第一个字母前面或后面也应包括在内。

enter image description here

当第一个字母为数字时,::first-line也同样被应用,例如,在67 million dollars is a lot of money.中的6

4.2.1 在CSS中的应用

在CSS中,::first-letter伪元素只能在block-like容器上有效果,这些容器有blocklist-iteminline-blocktable-captiontable-cell

::first-letter伪元素可和所有这些包含文本的元素或有一个后代包含文本且在相同的流的元素使用。用户代理也应该表现为好像虚拟的标签被加上。

实例:

<div>
<p>The first text.

表现为:

<div>
<p><div::first-letter><p::first-letter>T</...></...>he first text.

table-cellinline-block的第一个字母不能成为一个祖先元素的的第一字母。因此,在<DIV><P STYLE="display: inline-block">Hello<BR>Goodbye</P> etcetera</DIV>中,DIV的第一字母不是H。实际上,DIV没有第一个字母。

如果元素是一个list item::first-letter应用在主体框标记后的第一个字母。如果list item设置了list-style-position: inside,用户代理将忽略该列表项的::first-letter。如果一个元素有::before::after内容,::first-letter应用的时候包含了::before::after的内容。

实例:

例如:

p::before {content: "Note: "}

p::first-letter匹配Note中的N

在CSS中,::first-letter伪元素类似于一个inline-level元素,如果该元素的floatnone;否则,它和浮动元素相同。

4.3 空白

这里是故意留白的。(之前定义了::selection伪元素)

4.4 ::before::after伪元素

这两个伪元素在CSS21中定义。

原文地址:https://www.cnblogs.com/rubylouvre/p/4276216.html