CSS中的伪类和伪元素有啥区别?

Posted

技术标签:

【中文标题】CSS中的伪类和伪元素有啥区别?【英文标题】:What is the difference between a pseudo-class and a pseudo-element in CSS?CSS中的伪类和伪元素有什么区别? 【发布时间】:2011-12-25 13:54:30 【问题描述】:

a:linkdiv::after 之类的东西...

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

【问题讨论】:

@ŠimeVidas 到什么帖子?链接? 我觉得the spec 很清楚... @tybro0103 我没有找到。我想这确实从来没有在这里被问过......不过我发现了这个:***.com/questions/7757943/what-is-a-pseudo-element @zzzzBov 我觉得我需要翻译才能理解 :) 感谢您发布这个问题。我不知道为什么我在recent blitzkrieg on questions with the [pseudo-selector] tag 之后没有想到自己发布它... 【参考方案1】:

来自 Sitepoint 文档:

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

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

【讨论】:

【参考方案2】:

以下是简单的答案:

当我们需要根据元素的状态应用css时,我们使用pseudo-class。如:

    在锚元素悬停时应用 css (:hover) 在获得对 html 元素 (:focus) 的关注时应用 css。等

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

    将 css 应用于元素的第一个字母或第一行 (::first-letter) 在元素内容之前或之后插入内容(::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>

【讨论】:

【参考方案3】:

简而言之,来自 MDN 上的Pseudo-classes:

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

div:悬停 背景颜色:#F89B4D;

并且,来自 MDN 上的 Pseudo-elements:

CSS pseudo-element 是添加到选择器的关键字,它可以让您 为所选元素的特定部分设置样式。例如, ::first-line 可用于设置段落第一行的样式。

/* 每个

元素的第一行。 */ p::第一行 颜色:蓝色; 文本转换:大写;

【讨论】:

【参考方案4】:

帮助我理解差异的简短描述:

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

【讨论】:

【参考方案5】:

一个概念性的答案:

伪元素指的是文档的一部分,但您还不知道。例如第一个字母。在你只有文字之前。现在您有了可以定位的第一个字母。这是一个新概念,但始终是文档的一部分。这也包括::before 之类的东西;虽然那里没有实际内容,但始终存在先于其他事物的概念——现在您正在指定它。

伪类是 DOM 中某物的状态。就像类是与元素相关联的标签一样,伪类是与浏览器或 DOM 或其他任何东西相关联的类,通常作为对状态变化的响应。当用户访问一个链接时——该链接可以呈现“已访问”状态。您可以想象浏览器将“已访问”类应用于 Anchor 元素。 :visited 将是您为该伪类选择的方式。

【讨论】:

【参考方案6】:

伪类

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

原始伪类定义了元素的动态状态,随着时间的推移或通过用户干预进入和退出。 CSS2 扩展了这个概念,包括虚拟概念文档组件或文档树的推断部分,例如第一个孩子。伪类的运行就像将幻象类添加到各种元素中一样。

限制:与伪元素不同,伪类可以出现在选择器链中的任何位置。

示例伪类代码:

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 名称之后。每个选择器只能指定一个伪元素。要解决单个元素结构上的多个伪元素,必须进行多个样式选择器/声明语句。

伪元素可用于常见的排版效果,例如首字母大写和首字下沉。它们还可以处理不在源文档中的生成内容(带有“之前”和“之后”)。下面是一些添加了属性和值的伪元素的示例样式表。

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

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;

来源:Link

【讨论】:

【参考方案7】:

CSS 3 selector recommendation 对两者都很清楚,但无论如何我都会尝试展示它们的区别。

伪类

官方说明

引入伪类概念是为了允许基于位于文档树之外或无法使用其他简单选择器表达的信息进行选择。

伪类总是由一个“冒号”(:) 组成,后跟伪类的名称,还可以选择括号之间的值。

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

Source

这是什么意思?

伪类的重要性质在第一句话中说明:“伪类概念[...] 允许选择。它使样式表的作者能够根据“位于文档树之外” 的信息在元素之间进行区分,例如链接的当前状态 (:active,:visited)。这些不会保存在 DOM 中的任何位置,并且不存在访问这些选项的 DOM 接口。

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

所以基本上一个伪类会像sequence of simple selectors 中的任何其他simple selector 一样精炼选定元素的集合。请注意,一系列简单选择器中的所有简单选择器将同时被评估。有关伪类的完整列表,请查看 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;

伪元素

官方说明

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

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

:: 表示法由当前文档引入,以建立伪类和伪元素之间的区分。为了与现有样式表兼容,用户代理还必须接受之前在 CSS 级别 1 和 2 中引入的伪元素的单冒号表示法(即 :first-line、:first-letter、:before 和 :after)。本规范中引入的新伪元素不允许这种兼容性。

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

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

Source

这是什么意思?

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

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

我猜最大的不同是“每个选择器只能出现一个伪元素”。该说明说这可能会发生变化,但截至 2012 年,我认为我们在未来不会看到任何不同的行为 (it's still in CSS4)。

示例

以下示例将使用伪类:lang 和伪元素::after 为给定页面上的每个引用添加一个语言标签:

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

Selectors Level 3 4. Selector syntax 6.6 Pseudo-classes 7. Pseudo-elements CSS 2.1 Specification(已过时但仍然提供信息) 5.2 Selector syntax:

简单选择器可以是类型选择器或通用选择器,后跟零个或多个属性选择器、ID 选择器或伪类,顺序不限。如果所有组件都匹配,则简单选择器匹配。

5.10 Pseudo-elements and pseudo-classes

【讨论】:

我同意 DanMan 对 SLaks 回答的评论,因为伪类并不是真正充当“过滤器”,而是更多地充当“描述符”。例如,:not(.someclass):nth-child(even) 并不意味着过滤掉没有.someclass 的元素,而是在剩余的元素中过滤掉偶数出现的元素。相反,它表示同时是其父级both :not(.someclass) :nth-child(even) 的任何元素。更深入的解释可以在this answer和this answer找到。 @BoltClock:我相信我最喜欢“characteristic-classifier”这个词,因为这就是它们最初在CSS2中的描述:"Pseudo-classes classify elements on characteristics other than their name"。但是,我仍然没有找到我满意的确切措辞。【参考方案8】:

伪类过滤现有元素。a:link 表示所有&lt;a&gt;s 是:link

伪元素是一个新的假元素。div::after 表示&lt;div&gt;s 之后不存在的元素。

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

【讨论】:

+1 尽管从技术上讲 div::afterdiv 的子代,出现在其内容之后而不是元素本身之后。 我会说“进一步描述”,而不是“过滤器”。 伪元素是“新的伪元素”。它不能每次都是一个新的假元素,例如 p::first-letter 目标是现有的(不是新的假的)第一个字母。

以上是关于CSS中的伪类和伪元素有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

伪类选择器,伪类和伪元素的区别

浅谈css伪类和伪元素的区别、优先级

CSS3伪类和伪元素的特性和区别

css中的伪类和伪元素

css3的伪(伪类和伪元素)大合集

伪类和伪元素有啥区别?