伪类

CSS 播客 - 第 15 集:伪类

假设您有一个电子邮件注册表单,并且希望在电子邮件表单字段包含无效电子邮件地址时,该字段带有红色边框。您是怎么做到的? 您可以使用 :invalid CSS 伪类,它是浏览器提供的众多伪类之一。

借助伪类,您可以根据状态变化和外部因素应用样式。这意味着,您的设计可以对用户输入(例如无效的电子邮件地址)做出响应。选择器模块中介绍了这些内容,本单元将对其进行更详细的介绍。

与伪元素(您可以在上一单元中详细了解)不同,伪会钩住元素可能处于的特定状态,而不是对元素的各个部分进行一般性样式设置。

互动状态

由于用户与您的网页互动,系统会应用以下伪类。

:hover

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 2.

Source

如果用户使用鼠标或触控板等指针设备,并将其放在某个元素上,您可以使用 :hover 钩住该状态以应用样式。这是一种提示用户可以与元素互动的实用方法。

:active

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

当用户在释放点击之前与元素进行积极互动(例如点击)时,系统会触发此状态。如果使用的是鼠标等指针设备,则此状态表示点击开始,但尚未释放。

:focus:focus-within:focus-visible

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

如果某个元素(例如 <button>)可以获得焦点,您可以使用 :focus 伪类对该状态做出响应。

您还可以使用 :focus-within 在元素的子元素获得焦点时做出响应。

可聚焦的元素(例如按钮)在获得焦点时会显示焦点圈,即使在被点击时也是如此。在这种情况下,开发者将应用以下 CSS:

button:focus {
    outline: none;
}

此 CSS 会在元素获得焦点时移除默认的浏览器焦点圈,这会给使用键盘浏览网页的用户带来无障碍问题。如果没有焦点样式,用户在使用 tab 键时将无法跟踪焦点当前的位置。借助 :focus-visible,您可以在元素通过键盘获得焦点时呈现焦点样式,同时使用 outline: none 规则在指针设备与其互动时阻止呈现焦点样式。

button:focus {
    outline: none;
}

button:focus-visible {
    outline: 1px solid black;
}

:target

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.3.

Source

:target 伪类会选择具有与网址片段匹配的 id 的元素。假设您有以下 HTML:

<article id="content">
    …
</article>

当网址包含 #content 时,您可以为该元素附加样式。

#content:target {
    background: yellow;
}

这对于突出显示可能通过跳转链接进行了专门关联的区域(例如网站上的主内容)非常有用。

历史状态

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

:link 伪类可应用于任何 <a> 元素,前提是该元素的 href尚未访问。

:visited

您可以使用 :visited 伪类为用户已访问的链接设置样式。这与 :link 相反,但出于安全考虑,您可以使用的 CSS 属性较少。您只能设置 colorbackground-colorborder-coloroutline-color 以及 SVG fillstroke 的颜色。

顺序很重要

如果您定义了 :visited 样式,则链接伪类可以替换它,前提是该伪类的特定性至少与它相同。因此,建议您使用 LVHA 规则,以特定顺序(:link:visited:hover:active)为链接设置伪类样式。

a:link {}
a:visited {}
a:hover {}
a:active {}

表单状态

以下伪类可在用户与表单元素互动时,选择处于各种状态的表单元素。

:disabled:enabled

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

如果浏览器停用了表单元素(例如 <button>),您可以使用 :disabled 伪类钩住该状态。:enabled 伪类适用于相反的状态,不过表单元素默认也是 :enabled,因此您可能不需要使用此伪类。

:checked:indeterminate

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

当支持的表单元素(例如复选框或单选按钮)处于选中状态时,:checked 伪类可用。

:checked 状态是二进制(true 或 false)状态,但当复选框既未选中也不未取消选中时,复选框确实具有中间状态。这称为 :indeterminate 状态。

例如,如果您有一个“全选”控件,用于选中一组中的所有复选框,则该控件就处于此状态。如果用户随后取消选中其中一个复选框,则根复选框将不再表示“全部”处于选中状态,因此应处于不确定状态。

<progress> 元素还具有可设置样式的未确定状态。一个常见的用例是,为其设置条纹外观,以指明所需的剩余数据量未知。

:placeholder-shown

Browser Support

  • Chrome: 47.
  • Edge: 79.
  • Firefox: 51.
  • Safari: 9.

Source

如果表单字段具有 placeholder 属性但没有值,则可以使用 :placeholder-shown 伪类将样式附加到该状态。字段中一旦有内容(无论是否包含 placeholder),系统便不会再应用此状态。

验证状态

Browser Support

  • Chrome: 10.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 5.

Source

您可以使用伪类(例如 :valid:invalid:in-range)响应 HTML 表单验证。:valid:invalid 伪类对于上下文非常有用,例如电子邮件字段包含需要匹配的 pattern,以便其成为有效字段。此有效值状态可向用户显示,帮助他们了解可以放心地进入下一个字段。

如果输入具有 minmax(例如数值输入),并且值在这些边界内,则可以使用 :in-range 伪类。

对于 HTML 表单,您可以使用 required 属性确定字段是否为必填字段。:required 伪类将适用于必填字段。可使用 :optional 伪类选择非必填字段。

按元素的编号、顺序和出现次数选择元素

有一组伪类会根据项目在文档中的位置选择项目。

:first-child:last-child

Browser Support

  • Chrome: 4.
  • Edge: 12.
  • Firefox: 3.
  • Safari: 3.1.

Source

如果您想查找第一个或最后一个项,可以使用 :first-child:last-child。这些伪类将返回一组同级元素中的第一个或最后一个元素。

:only-child

Browser Support

  • Chrome: 2.
  • Edge: 12.
  • Firefox: 1.5.
  • Safari: 3.1.

Source

您还可以使用 :only-child 伪类选择没有同级兄弟元素的元素。

:first-of-type:last-of-type

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 3.1.

Source

您可以选择 :first-of-type:last-of-type,它们看起来似乎与 :first-child:last-child 执行相同的操作,但请考虑以下 HTML:

<div class="my-parent">
    <p>A paragraph</p>
    <div>A div</div>
    <div>Another div</div>
</div>

以及以下 CSS:

.my-parent div:first-child {
    color: red;
}

由于第一个子元素是段落,而不是 div,因此没有任何元素会呈现红色。在这种情况下,:first-of-type 伪类非常有用。

.my-parent div:first-of-type {
    color: red;
}

即使第一个 <div> 是第二个子元素,但它仍然是 .my-parent 元素中第一个此类元素,因此根据此规则,它将呈红色。

:nth-child:nth-of-type

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 3.1.

Source

您也不局限于第一个和最后一个子项以及类型。借助 :nth-child:nth-of-type 伪类,您可以指定位于特定索引的元素。CSS 选择器中的编号从 1 开始。

您还可以向这些伪类传递多个索引。如果您想选择所有偶数元素,可以使用 :nth-child(even)

您还可以使用 An+B 微语法创建更复杂的选择器,以便在均匀间隔的时间间隔内查找项。

li:nth-child(3n+3) {
    background: yellow;
}

此选择器会从第 3 项开始,选择每 3 项中的 1 项。此表达式中的 n 是索引,从 0 开始,3 (3n) 是该索引的乘数。

假设您有 7 个 <li> 项。第一个被选中的项是 3,因为 3n+3 会转换为 (3 * 0) + 3。下一次迭代会选择第 6 项,因为 n 现在已递增到 1,即 (3 * 1) + 3)。此表达式同时适用于 :nth-child:nth-of-type

您可以使用此 nth-child 测试工具或此数量选择器工具来试用此类选择器。

:only-of-type

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 3.1.

Source

最后,您可以使用 :only-of-type 在兄弟元素组中查找某一类型的唯一元素。如果您想选择只有一个项目的列表,或者想查找段落中唯一的粗体元素,这非常有用。

查找空元素

有时,识别完全空的元素会很有用,并且也有一个伪类可用于此目的。

:empty

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

如果元素没有子元素,则系统会对其应用 :empty 伪类。不过,子元素不仅仅是 HTML 元素或文本节点,它们还可以是空白,这可能会在调试以下 HTML 时造成困惑,让您疑惑为什么它不适用于 :empty

<div>
</div>

原因在于,开头和结尾 <div> 之间有一些空格,因此“empty”不起作用。

如果您对 HTML 的控制力较弱,并且想要隐藏空元素(例如所见即所得内容编辑器),:empty 伪类会很有用。在这里,编辑者添加了一个多余的空段落。

<article class="post">
 <p>Donec ullamcorper nulla non metus auctor fringilla.</p>
 <p></p>
 <p>Curabitur blandit tempus porttitor.</p>
</article>

借助 :empty,您可以找到并隐藏该标签。

.post :empty {
    display: none;
}

查找和排除多个元素

某些伪类可帮助您编写更紧凑的 CSS。

:is()

Browser Support

  • Chrome: 88.
  • Edge: 88.
  • Firefox: 78.
  • Safari: 14.

Source

如果您想在 .post 元素中查找所有 h2liimg 子元素,可能会考虑编写如下选择器列表:

.post h2,
.post li,
.post img {
    
}

借助 :is() 伪类,您可以编写更紧凑的版本:

.post :is(h2, li, img) {
    
}

:is 伪类不仅比选择器列表更紧凑,而且更宽容。在大多数情况下,如果选择器列表中存在错误或不受支持的选择器,整个选择器列表都将无法再使用。如果 :is 伪类中传递的选择器存在错误,它会忽略无效的选择器,但会使用有效的选择器。

:not()

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

您还可以使用 :not() 伪类排除项目。例如,您可以使用它为不具有 class 属性的所有链接设置样式。

a:not([class]) {
    color: blue;
}

:not 伪类还有助于您提高无障碍功能。例如,<img> 必须具有 alt,即使它是空值也是如此,因此您可以编写 CSS 规则,为无效图片添加粗红色轮廓:

img:not([alt]) {
    outline: 10px red;
}

检查您的理解情况

测试您对伪类的了解程度

伪类的行为就像已将类动态应用于元素一样,而伪元素的作用于元素本身。

正确
注意是否在选择器中使用单个或双个 : 作为关键区分字符
错误
伪元素用于部分,伪类用于状态。

以下哪些是功能伪类?

:is()
🎉
:target
功能伪类后面带有 (),表示它们接受参数。
:empty
功能伪类后面带有 (),表示它们接受参数。
:not()
🎉

以下哪些伪类是由于用户互动而产生的?

:hover
🎉
:press
再试一次!
:squeeze
再试一次!
:target
🎉
:focus-within
🎉

以下哪些是 <form> 状态伪类?

:enabled
🎉
:fresh
再试一次!
:indeterminate
🎉
:checked
🎉
:in-range
🎉
:loading
再试一次!
:valid
🎉