在 CSS 中,伪类和伪元素的区别是什么?

a:link或者 div::after..。

关于这种差异的信息似乎很少。

37568 次浏览

A pseudo-class filters existing elements.
a:link意味着所有 <a>都是 :link

伪元素是一种新的伪元素。
div::after是指在 <div>之后不存在的元素。

::selection是伪元素的另一个示例。
它并不意味着所有被选中的元素; 它意味着被选中的内容范围,它可能跨越多个元素的某些部分。

From the Sitepoint docs:

伪类类似于 HTML 中的类,但是在标记中没有明确指定。有些伪类是动态的ーー它们的应用是用户与文档交互的结果。-http://reference.sitepoint.com/css/pseudoclasses.比如 :hover, :active, :visited

伪元素 匹配文档树中不显式存在的虚元素。伪元素可以是动态的,因为它们表示的虚元素可以更改,例如,当浏览器窗口的宽度改变时。它们还可以表示由 CSS 规则生成的内容。-http://reference.sitepoint.com/css/pseudoelements.比如 ::before, ::after, ::first-letter

CSS 3 selector recommendation对两者都很清楚,但我还是要试着展示它们的不同之处。

Pseudo-classes

Official description

引入了伪类的概念,以允许基于文档树之外的信息或者不能用其他简单选择器表示的信息进行选择。

伪类总是包含一个“冒号”(:) ,后面跟着伪类的名称,并且可以选择在括号之间加上一个值。

在选择器中包含的所有简单选择器序列中都允许使用伪类。在简单选择器序列中的任何位置都允许伪类,在前导类型选择器或通用选择器之后(可能略去)。伪类名不区分大小写。一些伪类是相互排斥的,而另一些则可以同时应用于同一个元素。伪类可能是动态的,在这个意义上,当用户与文档交互时,元素可能获取或丢失伪类。

Source

这是什么意思?

The important nature of pseudo-classes is stated in the very first sentence: “伪类概念[ ... ] 许可选择 . It enables the author of an stylesheet to differ between elements based on information that “位于文档树之外”, for example the current status of a link (:active,:visited). Those aren't saved anywhere in the DOM, and there exists no DOM interface to access these options.

另一方面,可以通过 DOM 操作访问 :target(您可以使用 window.location.hash来通过 JavaScript 查找对象) ,但是这个 “不能用其他简单的选择符表示”

因此,基本上一个伪类将像 简单选择器序列中的任何其他 简单的选择器一样细化所选元素集。请注意,一系列简单选择器中的所有简单选择器都将同时求值。要获得伪类的完整列表,请检查 CSS3选择器建议。

例子

下面的示例将把所有偶数行涂成灰色(#ccc) ,所有不能被5个白色和每隔一行品红色除以的不均匀行。

table tr:nth-child(2n) td{
background-color: #ccc;
}


table tr:nth-child(2n+1) td{
background-color: #fff;
}


table tr:nth-child(2n+1):nth-child(5n) td{
background-color: #f0f;
}

Pseudo-elements

Official description

伪元素创建关于文档树的抽象,这些抽象超出了文档语言所指定的范围。例如,文档语言不提供访问元素内容的第一个字母或第一行的机制。伪元素允许作者引用这些无法访问的信息。伪元素还可以为作者提供一种引用源文档中不存在的内容的方法(例如,::before::after伪元素允许访问生成的内容)。

伪元素由两个冒号(::)和伪元素的名称组成。

当前文档引入 ::表示法是为了区分伪类和伪元素。为了与现有样式表兼容,用户代理还必须接受 CSS 级别1和2中引入的伪元素的前一个冒号表示法(即: 第一行、 : 第一个字母、 : 之前和: 之后)。这种兼容性对于本规范中引入的新伪元素是不允许的。

每个选择器只能出现一个伪元素,如果出现,它必须出现在表示选择器主题的简单选择器序列之后。

注意: 这个规范的未来版本可能允许每个选择器有多个伪元素。

来源

这是什么意思?

这里最重要的部分是 “伪元素允许作者 < strong > 引用[ . . ]否则无法访问的信息 和它们 ”也可以为作者提供一种引用源文档中不存在的内容的方法(例如,ABC0和 ::after伪元素允许访问生成的内容)。”。最大的区别在于,它们实际上创建了一个新的虚拟元素,可以对其应用规则甚至伪类选择器。它们不过滤元素,它们基本上过滤内容(::first-line::first-letter)并将其包装在一个虚拟容器中,作者可以按照自己的意愿(好吧,几乎)对其进行样式化。

例如,::first-line伪元素不能用 JavaScript 重建,因为它严重依赖于当前使用的字体、字体大小、元素宽度、浮动元素(可能还有一天中的时间)。好吧,这并不完全正确: 人们仍然可以计算所有这些值并提取第一行,但是这样做是一个非常繁琐的活动。

我想最大的区别是 “每个选择器只能显示一个伪元素”。注意事项说,这可能会有所改变,但截至2012年,我不认为我们看到任何不同的行为在未来(还在 CSS4里)。

例子

下面的示例将使用伪类 :lang和伪元素 ::after向给定页面上的每个引号添加 language-tag:

q:lang(de)::after{
content: " (German) ";
}


q:lang(en)::after{
content: " (English) ";
}


q:lang(fr)::after{
content: " (French) ";
}


q:not(:lang(fr)):not(:lang(de)):not(:lang(en))::after{
content: " (Unrecognized language) ";
}

TL;DR

伪类在一系列选择器中充当简单的选择器,从而根据非表示特征对元素进行分类,伪元素创建新的虚元素。

参考文献

W3C

伪级

伪类是一种选择 HTML 文档某些部分的方法,原则上不基于 HTML 文档树本身及其元素,也不基于名称、属性或内容等特征,而是基于其他虚幻条件,如语言编码或元素的动态状态。

最初的伪类定义了随时间或通过用户干预进入和退出的元素的动态状态。CSS2扩展了这个概念,包括虚拟概念文档组件或文档树的推断部分,例如第一子代。伪类的操作就好像幻像类被添加到各种元素中一样。

RESTRICTIONS: Unlike pseudo-elements, pseudo-classes can appear anywhere in selector chain.

示例伪类代码:

a:link /* This selects any "a" element whose target has not been visited.*/
{
padding : 4px;
text-decoration : none;
width : 10%;
color : #000000; /* black text color */
background-color : #99FF99; /* set to a pastel green */
border-top : 2px solid #ccffcc; /* highlight color */
border-left : 2px solid #ccffcc; /* highlight color */
border-bottom : 2px solid #003300; /* shadow color */
border-right : 2px solid #003300; /* shadow color */
}


a:visited /* This selects any "a" element whose target has been visited.*/
{ padding : 4px;
text-decoration : none;
color : #000000; /* black text color */
background-color : #ccccff; /* set to a lavender */
border-top : 2px solid #ffffff; /* highlight color */
border-left : 2px solid #ffffff; /* highlight color */
border-bottom : 2px solid #333366; /* shadow color *
border-right : 2px solid #333366; /* shadow color */
}


a:hover /* This selects any "a" element which is in a hover state. This is a state during pointer movement within the rendering region of an element. The user designates an element but does not activate it. */
{
color : #000000; /* black text color */
background-color : #99cc99; /* desaturated color */
border-top : 2px solid #003300; /* shadow color */
border-left : 2px solid #003300; /* shadow color */
border-bottom : 2px solid #ccffcc; /* highlight color */
border-right : 2px solid #ccffcc; /* highlight color */
}


a:focus /* This selects any "a" element which currently has focus. Focus is a state during which an element accepts keyboard input or other forms of text input. */
{
padding : 4px;
text-decoration : none;
width : 10%;
color : #000000; /* black text color */
background-color : #ffff99; /* set to a pastel yellow */
border-top : 2px solid #ffffcc; /* highlight color */
border-left : 2px solid #ffffcc; /* highlight color */
border-bottom : 2px solid #666633; /* shadow color */
border-right : 2px solid #666633; /* shadow color */
}


a:active /* This selects any "a" element which is in a state of activation. Active is a state during pointer activation (eg: press and release of a mouse) within the rendering region of an element.*/
{
padding : 4px;
text-decoration : none;
width : 10%;
color : #000000; /* black text color */
background-color : #ff99ff; /* set to a pink */
border-top : 2px solid #ffccff; /* highlight color */
border-left : 2px solid #ffccff; /* highlight color */
border-bottom : 2px solid #663366; /* shadow color */
border-right : 2px solid #663366; /* shadow color */
}

演示上述伪类代码的呈现的页面

伪元素

伪元素用于寻址元素的子部分。它们允许您对元素内容的一部分设置超出文档中指定的样式。换句话说,它们允许定义实际上不在文档元素树中的逻辑元素。逻辑元素允许在 CSS 选择器中处理隐含的语义结构。

限制: 伪元素只能应用于外部和文档级上下文,而不能应用于行内样式。伪元素被限制在它们可以出现在规则中的位置。它们可能只出现在选择器链的末端(在选择器的主题之后)。它们应该紧跟在选择器中找到的任何类或 ID 名之后。每个选择器只能指定一个伪元素。要处理单个元素结构上的多个伪元素,必须创建多个样式选择器/声明语句。

Pseudo-elements can be used for common typographic effects such as initial caps and drop caps. They can also address generated content that is not in the source document (with the "before" and "after") An example style sheet of some pseudo-elements with properties and values added follows.

/* 下面的规则选择标题1的第一个字母,并将字体设置为2em,草书体,背景为绿色。First-tter 为块级元素选择第一个呈现的字母/字符。*/

h1:first-letter {
font-size : 2em;
font-family : "Lucida Handwriting", "Lucida Sans", "Lucida Console", cursive;
background-color : #ccffcc;
}


/* The following rule selects the first displayed line in a paragraph and makes it bold. First-line selects the first rendered line on the output device of a block-level element. */


p:first-line {
font-weight : bold;
}


/* The following rule selects any content placed before a blockquote and inserts the phrase "Quote of the day:" in bold small caps with a green background. */


blockquote:before {
content : "Quote of the day:";
background-color : #ccffcc;
font-weight : bold;
font-variant : small-caps;
}


/* The following rule selects any content placed before a "q" element and inserts the smart open quote. */


q:before {
content : open-quote;
}


/* The following rule selects any content placed after a "q" element and inserts the smart close quote. */


q:after{
content : close-quote;
}

来源: 林克

A conceptual answer:

  • A pseudo-element refers to things that are part of the document, but you just don't know it yet. For example the first letter. Before you only had text. Now you have a first letter that you can target. It is a new concept, but was always part of the document. This also includes things like ::before; while there isn't actual content there, the concept of something before something else was always there -- now you are specifying it.

  • 伪类是 DOM 中某些事物的状态。就像类是与元素关联的标记一样,伪类是通过浏览器或 DOM 或其他方式关联的类,通常作为对状态变化的响应。当用户访问某个链接时,该链接可以呈现“访问”状态。您可以想象浏览器将类“访问”应用到 Anchor 元素。然后,:visited将成为您选择该伪类的方式。

简短的描述帮助我理解了其中的区别:

  • 伪类描述了一种特殊的状态。
  • 伪元素匹配虚元素。

下面是一个简单的答案:

当需要基于元素的 国家应用 css 时,我们使用 < strong > 伪类 ,例如:

  1. 将 css 应用于锚定元件(:hover)的悬停
  2. 当获得 html 元素(:focus)等的焦点时应用 css。

当需要将 css 应用到元素的 特定的部分或新的 插入的内容时,我们使用 伪元素。例如:

  1. 将 css 应用于元素的第一个字母或第一行(::first-letter)
  2. 在元素的内容之前或之后插入内容(::before::after)

下面是两者的例子:

<html>


<head>
<style>
p::first-letter {  /* pseudo-element */
color: #ff0000;
}


a:hover {          /* pseudo-class */
color: red;
}
</style>
</head>


<body>
<a href="#" >This is a link</a>
<p>This is a paragraph.</p>
</body>


</html>

简而言之,来自 MDN 的 伪课程:

CSS pseudo-class是添加到选择器的关键字,它指定 所选元素的特殊状态。例如,:hover 当用户将鼠标悬停在按钮上时,可用于应用样式。

div:hover {
background-color: #F89B4D;
}

And, from 伪元素 on MDN:

CSS 伪元素是添加到选择器中的关键字,它使您可以 style a specific part of the selected element(s). For example, ::first-line can be used to style the first line of a paragraph.

/* The first line of every <p> element. */
p::first-line {
color: blue;
text-transform: uppercase;
}