CSS 伪类和伪元素
什么是伪类?
伪类是选择器的一种,它用于选择处于特定状态的元素,比如当它们是这一类型的第一个元素时,或者是当鼠标指针悬浮在元素上面的时候。它们表现得会像是你向你的文档的某个部分应用了一个类一样,帮你在你的标记文本中减少多余的类,让你的代码更灵活、更易于维护。
伪类就是开头为冒号的关键字:
:pseudo-class-name
例如,:hover
可被用于在用户将鼠标悬停在按钮上时改变按钮的颜色。
/* 所有用户指针悬停的按钮 */ button:hover { color: blue; }
所有的伪类以同样的方式实现。它们选中你的文档中处于某种状态的那部分,表现得就像是你已经向你的HTML加入类一样。看下MDN上的另外几个示例:
用户行为伪类
一些伪类只会在用户以某种方式和文档交互的时候应用。这些用户行为伪类,有时叫做动态伪类,表现得就像是一个类在用户和元素交互的时候加到了元素上一样。案例包括:
a:link, a:visited { color: rebeccapurple; font-weight: bold; } a:hover { color:hotpink; }
<p><a href="">Hover over me</a></p>
伪元素是啥?
伪元素以类似方式表现,不过表现得是像你往标记文本中加入全新的HTML元素一样,而不是向现有的元素上应用类。伪元素开头为双冒号::
。
::pseudo-element-name
备注:一些早期的伪元素曾使用单冒号的语法,所以你可能会在代码或者示例中看到。现代的浏览器为了保持后向兼容,支持早期的带有单双冒号语法的伪元素。
例如,如果你想选中一段的第一行,你可以把它用一个<span>
元素包起来,然后使用元素选择器;不过,如果包起来的单词/字符数目长于或者短于父元素的宽度,这样做会失败。由于我们一般不会知道一行能放下多少单词/字符——因为屏幕宽度或者字体大小改变的时候这也会变——通过改变HTML的方式来可预测地这么做是不可能的。
::first-line
伪元素选择器会值得信赖地做到这件事——即使单词/字符的数目改变,它也只会选中第一行。
article p::first-line { font-size: 120%; font-weight: bold; }
<article> <p>Veggies es bonus vobis, proinde vos postulo essum magis kohlrabi welsh onion daikon amaranth tatsoi tomatillo melon azuki bean garlic.</p> <p>Gumbo beet greens corn soko endive gumbo gourd. Parsley shallot courgette tatsoi pea sprouts fava bean collard greens dandelion okra wakame tomato. Dandelion cucumber earthnut pea peanut soko zucchini.</p> </article>
这表现得就像是<span>
神奇地包在第一个被格式化的行一样,每当行长改变的时候还会更新。
你可以看到它把两段的第一行都选中了。
把伪类和伪元素组合起来
如果你想让第一段的第一行加粗,你需要把:first-child
和::first-line
选择器放到一起。试着编辑前面的实时示例,让它使用下面的CSS。这里的意思是,我们想选择一个<article>
元素里面的第一个<p>
元素的第一行。
article p:first-child::first-line { font-size: 120%; font-weight: bold; }
生成带有::before和::after的内容
有一组特别的伪元素,它们和content
属性一同使用,使用CSS将内容插入到你的文档中中。
你能用这些插入一个文本字符串,和在下面的实时示例里那样。试着改变content
属性的文本值,看看输出是怎么改变的。你也能改变::before
伪元素为::after
,看到这段文本插入到了元素的末尾而不是开头。
.box::before { content: "This should show before the other content." }
<p class="box">Content in the box in my HTML page.</p>
从CSS插入文本字符串,我们并不会在Web浏览器上经常这么做,因为对于一些屏幕阅读器来说,文本是不可见的,而且对于未来别人的查找和编辑也不是很方便。
这些伪元素的更推荐的用法是插入一个图标,例如下面的示例加入的一个小箭头,作为一个视觉性的提示,而且我们并不希望屏幕阅读器读出它。
.box::after { content: " ➥" }
<p class="box">Content in the box in my HTML page.</p>
这些伪元素经常用于插入空字符串,其后可以像页面上的其他元素被样式化。
下个示例,我们已经用 ::before
伪元素加入了个空字符串。我们把它设为了display: block
,以让它可以用width和height进行样式化。然后我们可以用CSS像任何元素那样样式化。你可以摆弄CSS,改变它的外观和行为。
.box::before { content: ""; display: block; width: 100px; height: 100px; background-color: rebeccapurple; border: 1px solid black; }
<p class="box">Content in the box in my HTML page.</p>
::before
和::after
伪元素与content
属性的共同使用,在CSS中被叫做“生成内容”,而且你会见到这种技术被用于完成各种任务。CSS Arrow Please网站就是一个著名的示例,它帮你用CSS生成一个箭头。在你创建你的箭头的时候看下CSS,你将会看到实际使用的::before
和::after
伪元素。无论什么时候你看到了这些选择器,都要看下content
属性,以了解文档中添加了什么。
标准伪类索引
:active
:any-link
:blank
:checked
:current
(en-US):default
:defined
:dir()
:disabled
:drop
:empty
:enabled
:first
:first-child
:first-of-type
:fullscreen
:future
(en-US):focus
:focus-visible
:focus-within
:has()
:host
:host()
:host-context()
:hover
:indeterminate
:in-range
:invalid
:is()
:lang()
:last-child
:last-of-type
:left
:link
:local-link
(en-US):not()
:nth-child()
:nth-col()
(en-US):nth-last-child()
:nth-last-col()
(en-US):nth-last-of-type()
:nth-of-type()
:only-child
:only-of-type
:optional
:out-of-range
:past
(en-US):placeholder-shown
:read-only
:read-write
:required
:right
:root
:scope
:target
:target-within
(en-US):user-invalid
(en-US):valid
:visited
:where()