CSS 播客 - 第 15 集:伪类
假设您有一个电子邮件注册表单,并且希望在电子邮件表单字段包含无效电子邮件地址时,该字段带有红色边框。您是怎么做到的?
您可以使用 :invalid
CSS 伪类,它是浏览器提供的众多伪类之一。
借助伪类,您可以根据状态变化和外部因素应用样式。这意味着,您的设计可以对用户输入(例如无效的电子邮件地址)做出响应。选择器模块中介绍了这些内容,本单元将对其进行更详细的介绍。
与伪元素(您可以在上一单元中详细了解)不同,伪类会钩住元素可能处于的特定状态,而不是对元素的各个部分进行一般性样式设置。
互动状态
由于用户与您的网页互动,系统会应用以下伪类。
:hover
如果用户使用鼠标或触控板等指针设备,并将其放在某个元素上,您可以使用 :hover
钩住该状态以应用样式。这是一种提示用户可以与元素互动的实用方法。
:active
当用户在释放点击之前与元素进行积极互动(例如点击)时,系统会触发此状态。如果使用的是鼠标等指针设备,则此状态表示点击开始,但尚未释放。
:focus
、:focus-within
和:focus-visible
如果某个元素(例如 <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
:target
伪类会选择具有与网址片段匹配的 id
的元素。假设您有以下 HTML:
<article id="content">
…
</article>
当网址包含 #content
时,您可以为该元素附加样式。
#content:target {
background: yellow;
}
这对于突出显示可能通过跳转链接进行了专门关联的区域(例如网站上的主内容)非常有用。
历史状态
:link
:link
伪类可应用于任何 <a>
元素,前提是该元素的 href
值尚未访问。
:visited
您可以使用 :visited
伪类为用户已访问的链接设置样式。这与 :link
相反,但出于安全考虑,您可以使用的 CSS 属性较少。您只能设置 color
、background-color
、border-color
、outline-color
以及 SVG fill
和 stroke
的颜色。
顺序很重要
如果您定义了 :visited
样式,则链接伪类可以替换它,前提是该伪类的特定性至少与它相同。因此,建议您使用 LVHA 规则,以特定顺序(:link
、:visited
、:hover
、:active
)为链接设置伪类样式。
a:link {}
a:visited {}
a:hover {}
a:active {}
表单状态
以下伪类可在用户与表单元素互动时,选择处于各种状态的表单元素。
:disabled
和:enabled
如果浏览器停用了表单元素(例如 <button>
),您可以使用 :disabled
伪类钩住该状态。:enabled
伪类适用于相反的状态,不过表单元素默认也是 :enabled
,因此您可能不需要使用此伪类。
:checked
和:indeterminate
当支持的表单元素(例如复选框或单选按钮)处于选中状态时,:checked
伪类可用。
:checked
状态是二进制(true 或 false)状态,但当复选框既未选中也不未取消选中时,复选框确实具有中间状态。这称为 :indeterminate
状态。
例如,如果您有一个“全选”控件,用于选中一组中的所有复选框,则该控件就处于此状态。如果用户随后取消选中其中一个复选框,则根复选框将不再表示“全部”处于选中状态,因此应处于不确定状态。
<progress>
元素还具有可设置样式的未确定状态。一个常见的用例是,为其设置条纹外观,以指明所需的剩余数据量未知。
:placeholder-shown
如果表单字段具有 placeholder
属性但没有值,则可以使用 :placeholder-shown
伪类将样式附加到该状态。字段中一旦有内容(无论是否包含 placeholder
),系统便不会再应用此状态。
验证状态
您可以使用伪类(例如 :valid
、:invalid
和 :in-range
)响应 HTML 表单验证。:valid
和 :invalid
伪类对于上下文非常有用,例如电子邮件字段包含需要匹配的 pattern
,以便其成为有效字段。此有效值状态可向用户显示,帮助他们了解可以放心地进入下一个字段。
如果输入具有 min
和 max
(例如数值输入),并且值在这些边界内,则可以使用 :in-range
伪类。
对于 HTML 表单,您可以使用 required
属性确定字段是否为必填字段。:required
伪类将适用于必填字段。可使用 :optional
伪类选择非必填字段。
按元素的编号、顺序和出现次数选择元素
有一组伪类会根据项目在文档中的位置选择项目。
:first-child
和:last-child
如果您想查找第一个或最后一个项,可以使用 :first-child
和 :last-child
。这些伪类将返回一组同级元素中的第一个或最后一个元素。
:only-child
您还可以使用 :only-child
伪类选择没有同级兄弟元素的元素。
:first-of-type
和:last-of-type
您可以选择 :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
您也不局限于第一个和最后一个子项以及类型。借助 :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
最后,您可以使用 :only-of-type
在兄弟元素组中查找某一类型的唯一元素。如果您想选择只有一个项目的列表,或者想查找段落中唯一的粗体元素,这非常有用。
查找空元素
有时,识别完全空的元素会很有用,并且也有一个伪类可用于此目的。
:empty
如果元素没有子元素,则系统会对其应用 :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()
如果您想在 .post
元素中查找所有 h2
、li
和 img
子元素,可能会考虑编写如下选择器列表:
.post h2,
.post li,
.post img {
…
}
借助 :is()
伪类,您可以编写更紧凑的版本:
.post :is(h2, li, img) {
…
}
:is
伪类不仅比选择器列表更紧凑,而且更宽容。在大多数情况下,如果选择器列表中存在错误或不受支持的选择器,整个选择器列表都将无法再使用。如果 :is
伪类中传递的选择器存在错误,它会忽略无效的选择器,但会使用有效的选择器。
:not()
您还可以使用 :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