<一个类="边境-2 border-solid rounded-sm font-medium transition-colors cursor-pointer disabled:cursor-not-allowed disabled:pointer-events-none text-center bg-primary-700 border-primary-700 text-white hover:bg-primary-500 hover:border-primary-500 hover:text-white focus-visible:bg-primary-500 focus-visible:border-primary-500 focus-visible:text-white dark:hover:bg-primary-200 dark:hover:border-primary-200 dark:hover:text-body dark:focus-visible:bg-primary-200 dark:focus-visible:border-primary-200 dark:focus-visible:text-body disabled:bg-primary-100 disabled:border-primary-100 disabled:text-primary-400 text-sm px-2 hidden py-1 mx-4 lg:block dark:bg-primary-700 dark:border-primary-700 dark:text-white" id="join-premium" href="//www.shaoxingby.com/premium/pricing/?ref_source=premium&ref_medium=topnav">加入溢价

本章没有全面介绍所有的选择器,因为这本身就可能占据一整本书的篇幅。相反,我们将关注具有良好浏览器支持的选择器,这些选择器可能在您当前的工作中很有用。有些材料可能是老掉牙的,但它们是作为上下文而包含的。

选择器的类型

选择器可以分为四种基本类型:简单、复合、组合子和复杂。

简单的选择器是最古老的CSS选择器形式,可能是最常用的类型。简单选择器为匹配元素指定一个条件。通用选择器()是一个简单的选择器。类型(或元素)选择器也是如此,例如p伪元素选择器,比如:首字母.属性选择器,例如[隐藏],类选择器等.message-error,以及ID选择器,例如#报头也属于这一类。

化合物选择器,例如p:胎.message.error,是一组简单的选择器,它反映了在对元素应用规则时要同时满足的一组条件。换句话说,.message.error将匹配

,但不是< div class = "消息" >< div class = "错误" >

组合子选择器表达元素之间的关系。有四种:

  • 的<年代trong class="">后代选择符文章页
  • 的<年代trong class="">子选择符>),例如.sidebar > h2
  • 的<年代trong class="">相邻兄弟组合子+),例如Ul + p
  • 的<年代trong class="">一般兄弟组合子),例如P ~图

规则应用于组合子选择器中最右边的元素,当它符合组合子所指示的条件时。我们将在本章后面详细讨论组合子选择器。

最后,还有复杂的选择器。<年代trong class="">复杂的选择器由一个或多个由组合子分隔的复合选择器组成。选择器Ul:not(.square) > a[rel=external]是复杂选择器的示例。

选择器可以分组到所谓的<年代trong class="">选择器列表用逗号分隔。选择器列表将样式应用于匹配的元素<新兴市场类="">任何列表中的选择器。例如,规则文章,div {padding: 20px;}添加20像素的填充<新兴市场类="">这两个文章< >而且< div >元素。

了解你正在使用的选择器类型将帮助你掌握CSS中更令人困惑的一个方面:<年代trong class="">特异性.保持低特异性可以增加CSS规则的可重用性。选择器如#菜单> .pop-open意味着您只能使用.pop-open当它是#菜单,即使在您的项目中其他地方存在类似的交互。

我们将在第二章回到特异性。”<一个href="#一个rchitecture" class="" target="_blank">CSS架构与组织”。然而,在本章的剩余部分,我们将讨论特定的选择器组:组合器、属性选择器、伪元素和伪类。

组合子

正如我们上面看到的,一个组合子是一个字符序列,它表达了它两侧选择器之间的关系。使用组合子创建一个复杂的选择器。在某些情况下,使用复杂的选择器可能是定义样式的最简洁的方法。

在上一节中,我们列出了四个组合子:后人(通过空格)、子(>),相邻的兄弟姐妹(+),以及一般兄弟姊妹().

我们来解释一下这些组合子。我们将使用它们向如下所示的HTML表单添加样式。

我们将使用组合符样式的HTML表单"loading=

上图中的表单是使用以下HTML块创建的:

后代组合子

你们可能对子组合子很熟悉。它在CSS的早期就已经存在了(尽管在CSS2.1之前它没有一个合适的名字)。它被广泛使用和支持。

子组合子只是一个空白字符。它按照模式将父选择器与其子选择器分开一个B,在那里B包含的元素是一个.让我们从上面的标记中添加一些CSS,看看它是如何工作的:

我们刚刚改变了表单标题的颜色,其结果如下所示。

子组合子的效果"loading=

让我们添加更多的CSS,这一次是增加定价消息的大小(“Tickets are $10 each”)。我们也将它设置为热粉色:

然而,这个选择器有一个问题,如下图所示。我们的选择器太宽泛了。

哦!我们的选择器太宽泛了"loading=

我们实际上增加了文本的大小<新兴市场类="">所有我们表单的段落,这不是我们想要的。我们如何解决这个问题?让我们试试子组合子。

子组合子

与子组合子相比,子组合子(>)只选取<新兴市场类="">直接的孩子元素的。它遵循这个模式A > b,匹配任何元素B在哪里一个是直接祖先。

打个比方,如果元素是人,子组合子将匹配母元素的子元素。但是后代组合子也会匹配她的孙子和曾孙。让我们修改之前的选择器,使用子组合子:

的直接子结点形式都会受到影响,如下图所示。

子组合子的效果"loading=

相邻兄弟组合子

与相邻的兄弟组合子(+),我们可以选择相互跟随且具有相同父元素的元素。它使用模式A + b.样式应用于B元素是<新兴市场类="">立即之前一个元素。

让我们回到我们的例子。注意,在Billing Address部分中,我们的标签和输入是紧挨着的。这意味着我们可以使用相邻的兄弟组合子使它们位于不同的行上:

你可以在下图中看到结果。

相邻的组合符来拯救"loading=

你可以在上图中看到,我们的一些标签与它们的输入字段保持在同一行上。在这种情况下,有一个< span >元素之间的<标识>而且<输入>元素,这意味着它们不是相邻的兄弟元素。为了匹配不相邻的兄弟元素,我们必须使用一般的兄弟组合子(我们将在下一节中看到)。

让我们看看另一个组合了通用选择器()使用类型选择器:

这个例子添加了5他们页边距到每一页的顶部和底部<自定义字段>元素,如下图所示。

使用相邻的兄弟组合子来调整字段集元素的下边距"loading=

因为我们使用的是通用选择器,所以没有必要担心前一个元素是否是另一个元素<自定义字段>< p >元素。

相邻兄弟选择器的更多使用

Heydon Pickering在他的文章"<一个href="http://alistapart.com/article/axiomatic-css-and-lobotomized-owls" class="" target="_blank">不言自明的CSS和额叶切除猫头鹰”。

一般的兄弟组合子

使用一般的兄弟组合子()我们可以选择具有相同父元素的元素,而不考虑它们是否相邻。给定这个模式A ~ b,此选择器匹配所有B前面有一个元素。

让我们再次查看Number of Tickets字段。它的标记看起来像这样:

我们的<输入>元素的后面<标识>元素,但是有一个< span >中间的元素。相邻的兄弟组合子将不能在这里工作。让我们把相邻的兄弟组合子改为一般的兄弟组合子:

现在我们所有的<输入>元素与其元素位于单独的一行上<标识>元素,如下图所示。

组合子的目标是兄弟元素,不管它们是否相邻"loading=

因为通用的兄弟组合子匹配任何后续的兄弟组合子,所以您需要谨慎地使用它。考虑下面的标记和CSS:

这里我们用了一般的兄弟组合子和an<标题>元素。结果,<新兴市场类="">每一个元素后面的段落元素<标题>元素的背景为黄色。的后面的段落也包括在内< h2 >标题,如下所示。

记住,一般的兄弟组合子匹配A后面的每个元素B,而不管它在文档中的位置"loading=

如果您可以控制文档的标记,我建议使用类选择器而不是一般的兄弟组合器。一般的兄弟组合子使你很容易意外地设计出比你想要的更多的元素。

属性选择器

介绍了<一个href="https://www.w3.org/TR/CSS21/" class="" target="_blank">CSS Level 2规范,属性选择器可以根据属性的存在来设置元素的样式,例如(控制)对于媒体播放器,或者(禁用)对于表单字段。

还可以使用属性选择器根据属性及其值匹配元素。例如,要设置提交按钮的样式,你可以使用下面的CSS:

还有一些属性选择器用于部分匹配属性值和子字符串。能够部分匹配属性值是我最喜欢的CSS选择器特性之一。如果仔细使用,它们可以减少需要编写的规则和声明的数量。我们很快就会看到它们。我们将介绍的大多数属性选择器都是老式的。但是,为了上下文和完整性,我将它们包括在内。

关于引号的注意事项

在大多数情况下,引用属性选择器的值是可选的。这两个(type =复选框)而且(type = "复选框")是属性选择器的有效且受良好支持的语法。当属性的值包含空格或标点符号时,使用引号[class = " piechart动画”)[data-action =“模态接近”):(id =“- 2.2节”)

匹配用空格分隔的属性值

空格分隔的属性值选择器将元素与属性(丙氨酸)和一个值列表,其中之一是瓦尔.这可以是接受空格分隔值的任何属性,包括数据- *

诚然,用空格分隔的属性列表并不常见。它们有时与the连用rel属性和<一个href="http://microformats.org/wiki/existing-rel-values" class="" target="_blank">微格式描述人和文档之间的关系。例如,我们可以这样标记外部链接:

然后,我们可以使用这个基于存在的属性选择器来匹配包含朋友作为其属性值之一:

结果如下图所示。

使用属性选择器样式化bob网站的链接"loading=

匹配连字符属性值

使用属性选择器可以完成的更有趣的任务之一是使用(attr | = val)在第一个连字符之前匹配属性值的第一部分。例如,(朗| = en)匹配的元素是< p lang =“en - us”>

此选择器的主要目的是使用语言和语言代码,例如en - us而且es-MX

假设我们有一些这样的标记:

我们可以将法语文本斜体化,并在文本两侧添加与语言相适应的角引号(«and»):

这个选择器最酷的地方在于,即使没有连字符,它也能工作。所以上面的风格也适用于< p lang =“fr”>.我们可以通过添加元素选择器来进一步限制这些选择器的范围,例如p[朗| =“fr”]

这个选择器不局限于语言代码。我们可以将它与任何连字符属性值一起使用。考虑下面的标记:

这些都是文章宣传片或预告片。它们共享一些相同的视觉特征和行为,以及前缀为促销.在这里,我们也可以使用连字符的属性选择器来匹配这些类名:

接下来,为每个部分类型设置特定的边框颜色,你将实现如下图所示的布局。

使用连字符属性为元素设置样式"loading=

我们也可以使用ID名称的选择器。例如,[id | =全球]将匹配# global-footer#全局菜单等等。

按子字符串匹配属性值

当属性值与特定子字符串匹配时,还可以使用(att ^ = val)(att美元= val)而且(丙氨酸* = val)

^ =的子字符串进行匹配<新兴市场类="">开始属性值的。例如,考虑使用链接电话:(非标)或mailto:.由于它们与其他超链接的行为不同,因此有必要对它们进行不同的样式,只是为了给用户一个提示。点击“致电这家公司”链接:

我们可以选择这个和那个电话:链接,使用(href ^ = "电话:").让我们添加一些声明:

你可以在下图中看到结果。

我们的新生意叫这个。按钮"loading=

$ =的子字符串进行匹配<新兴市场类="">结束属性值的。例如,如果我们想给PDF文件链接一个特殊的颜色,我们可以使用美元(href = " . pdf”)

这个选择器对于匹配属性值以相同后缀结尾的元素也很方便。例如,您可以同时匹配两者除了<类= " sports-sidebar " >而且除了<类= " arts-sidebar " >(类=美元栏)

* =选择器匹配子字符串<新兴市场类="">在任何职位在属性值中。使用选择器(类* =栏),我们可以选择一个类为的元素sports-sidebar-a,<新兴市场类="">随着元素和类sports-sidebar而且arts-sidebar

按大小写匹配属性值

在大多数情况下,CSS是一种不区分大小写的语言。这两个颜色:番茄而且颜色:番茄做同样的事情。这两个p{…}而且P{…}将样式段落放在HTML中,HTML是否使用< p >< P >.属性名也是如此,其中(href)而且(HREF)两者都会匹配href = "…"而且HREF = "…"

然而,这并不适用于属性<新兴市场类="">值.字母大小写与这些有关。在以下标记中,我们的ID属性< div >标签混合大小写字母:

< div >,我们可能会使用它的ID选择器,即,# MixedCaseIDExample.但我们必须按照HTML中显示的方式使用它。使用# mixedcaseidexample举个例子,这是行不通的。

但还有另一种选择。我们可以使用不区分大小写的属性匹配。它是由<一个href="https://drafts.csswg.org/selectors-4/" class="" target="_blank">选择器4级规范。

不区分大小写的属性匹配使用标志,指示这些样式应应用于任何大小写组合:

现在我们的选择器将匹配ID属性,不管它的值是mixedcaseidexampleMixedCaseIDExample,或mIxEdCaSeIdExAmPlE

在某些情况下,您可能希望强制区分大小写的值匹配。要强制区分大小写的匹配,请使用年代国旗:

年代国旗匹配# mixedcaseidexample,但不是# MixedCaseIDExample# mIxEdCaSeIdExAmPlE

伪类和伪元素

CSS3和CSS4中添加的大多数新选择器根本不是属性选择器。它们是伪类和伪元素。

虽然您可能在CSS中使用过伪类和伪元素,但您可能没有想过它们是什么,以及它们之间有什么不同。

伪类让我们根据不同于文档树的信息(比如它们的状态)或不能使用简单选择器表示的信息来设置对象的样式。例如,一个元素只有在用户与它交互时才能有悬停或聚焦状态。与:徘徊而且:专注伪类,我们可以为这些状态定义样式。否则,我们必须依赖脚本来添加和删除类名。

伪元素,另一方面,让我们为没有直接出现在文档树中的元素设置样式。HTML没有定义firstletter元素,所以我们需要另一种方式来选择它。的:首字母伪元素给了我们这种能力。

警惕普遍选择

在没有简单选择器的情况下使用伪类和伪元素相当于在通用选择器中使用它们。对于选择器,例如:没有((type =无线电)),每一个元素缺少一个类型属性和价值广播将match-including< html >而且身体< >.为了防止这种情况,使用:不()作为复合选择器的一部分,例如与类名或元素一起,如在p: not (. error)

同样地,单独使用类名、id和属性选择器可以通用地应用它们。例如,.warning而且(type =广播)是一样的* .warning而且* (type =广播)

伪元素

的<一个href="http://dev.w3.org/csswg/css-pseudo-4/" class="" target="_blank">CSS伪元素模块第4级规范澄清了现有伪元素的行为,并定义了几个新的伪元素。我们将重点介绍目前有浏览器支持的软件:

  • 后::在元素的内容之后插入额外的生成内容

    <李类="">::之前在元素的内容之前插入额外的生成内容

    <李类="">:首字母选择元素的第一个字母

    <李类="">::一线选择元素的第一行

    <李类="">::标记样式列表项的项目符号和数字<摘要>元素

    <李类="">::占位符样式为窗体控件设置占位符文本占位符属性

    <李类="">::选择样式光标选择的文本

其中,:首字母::一线::选择::标记而且::占位符影响作为文档源一部分的内容。的::之前而且后::另一方面,伪元素向文档中注入内容。让我们更仔细地看看这些伪元素。

::之前而且后::

大多数伪元素允许我们选择已经是文档源的一部分的内容(即您所创建的HTML),但这不是由语言指定的。但::之前而且后::不同的工作。这些伪元素将生成的内容添加到文档树中。这些内容在HTML源代码中不存在,但可以通过可视化方式获得。

为什么要使用生成内容?例如,你可能想通过在它们的标签后面添加内容来指示哪些表单字段是必需的:

必需的表单字段使用要求HTML属性。由于该信息已经可用于DOM,因此使用::之前后::添加助手文本是补充的。它不是关键内容,所以它不是文档源的一部分也没关系。

生成内容和可访问性

一些屏幕阅读器和浏览器组合可以识别和读取生成的内容,但大多数都不能。你不能确定内容生成使用::之前后::将提供给辅助技术使用者。你可以在Leonie Watson的文章中读到更多<一个href="http://tink.uk/accessibility-support-for-css-generated-content/" class="" target="_blank">CSS生成内容的可访问性支持”。

的另一个用例::之前后::正在向内容添加前缀或后缀。例如,上面提到的表单可能包括helper文本,如下所示:

让我们用using将助手文本括在红色括号中::之前而且后::

结果如下所示。

使用::before和::after添加补充内容"loading=

这两个::之前而且后::行为类似于其他后代元素。它们继承父节点的可继承属性,并包含在父节点中。它们还与其他元素框交互,就像它们是真正的元素一样。

每个选择器有一个伪元素

目前,每个选择器只允许一个伪元素。选择器如p::一线::无效且不受支持。

这意味着我们可以使用::之前而且后::与CSS网格和Flexbox。一个用例是装饰标题,如下所示。

使用带有::before和::after的网格布局来创建装饰标题"loading=

创建这个标题所需的CSS如下所示:

你可以在第5章阅读更多关于CSS Grid和Flexbox布局的内容。<一个href="#layouts" class="" target="_blank">布局”。

创建排版效果:首字母

::之前而且后::伪元素注入内容,:首字母处理作为文档源一部分存在的内容。与:首字母,我们可以创建首字母效果,如大写字母,就像你可能在杂志或书籍布局中看到的那样。

首字母和大写字母

一个<年代trong class="">初始资本是位于文本块开头的大写字母,该文本块设置的字体大小大于正文副本的其余部分。一个<年代trong class="">减少资本(或首字母大写)类似于首字母,但在第一段中插入至少两行。

这个CSS代码片段为每个元素添加了一个首字母大写< p >元素:

结果如下所示。

使用::first-letter伪元素创建首字母大写"loading=

从上图中你可能已经注意到,:首字母会影响行高如果你设置了一个无单位的行高对于元素。在这种情况下,每一个< p >元素继承了行高的值为1.5身体< >元素。有三种方法可以缓解这种情况:

  • 降低…的价值行高:首字母伪元素。值为.5似乎大多数时候都很好,取决于字体。<李类="">设置一个行高单位在:首字母伪元素。<李类="">设置一个行高单位在身体< >或者是:首字母的父母。

第一种选择保留了使用无单位的垂直节奏行高.第二个选项限制了使用固定的行高只是那些伪元素。然而,选项三很可能会创建一个副作用,需要更多的CSS来撤销。

为什么没有单位?

的Mozilla开发人员网络条目行高解释了为什么<一个href="https://developer.mozilla.org/en-US/docs/Web/CSS/line-height" class="" target="_blank">无单位值都是要走的路。

在这种情况下,让我们减小行高p::首字母.5(并重写文件属性以使用字体速记法):

此更改产生如下图所示的结果。

减轻::首字母对行高的影响"loading=

注意这里,我们调整了每一个的底边距< p >元素来补偿减少的部分行高p::首字母

创建drop capital需要多写几行CSS。与首大写字母不同,与降大写字母相邻的文本将其环绕起来。这意味着我们需要加浮:左;到我们的规则集:

浮动一个元素(在本例中是伪元素)会导致剩余的文本围绕它流动,如下所示。

用首字母::创建一个小写字母"loading=

请注意:首字母可能很难风格像素完美的准确性跨浏览器,除非你使用px快速眼动大小、边距和行高的单位。

有时文本元素的第一个字母实际上是标点符号,例如在一篇新闻报道中,开头是一段引文:

在本例中,为定义的样式:首字母修改开头标点符号和第一个字母,如下所示。所有浏览器都以相同的方式处理这个问题。

如果标点符号紧接在字母或数字字符的前面,它们也可以接受::first-letter样式"loading=

然而,当标点符号是由元素生成时,它就不一定是这样工作的。考虑下面的标记:

当前浏览器通常呈现<问>元素,在所包含的文本前后使用适合语言的引号。Safari、Chrome和Edge会忽略开引号。但是,Firefox 90及以下版本适用:首字母样式转换为开头的引号,而不是第一个字母。

Firefox将::first-letter样式应用于q元素的开头引号"loading=

在基于chrome的浏览器和Safari中,<问>元素和段落的第一个字母都被重新设置样式。下图显示了它在Chrome中的外观。

Chrome在使用q元素时忽略了开头的引号和第一个字母"loading=

根据<一个href="http://dev.w3.org/csswg/css-pseudo-4/" class="" target="_blank">CSS伪元素模块第4级应包括第一个字母或字符的前面或后面的标点符号。然而,规范没有明确说明这是否也适用于生成的标点符号。

在Firefox 90及更早版本中,某些标点符号会导致Firefox忽略:首字母规则。这些字符包括但不限于美元符号($)、插入符号(^)、反撇号(')和波浪号(~)字符。到目前为止,Firefox也不适用:首字母样式转换为表情符号。

无论第一个字符是否使用::之前内容属性,或包含在文档源中。这个问题没有解决办法。避免使用这些字符作为第一个字符,如果你也使用:首字母

:首字母伪元素不适用于元素<一>< b >,或<代码>.的父元素也不适用显示物业价值内联

创建排版效果::一线

::一线伪元素的工作原理类似于:首字母,但会影响元素的整个第一行。例如,每个段落的第一行可以有更大的文本,并且颜色与段落的其他部分不同:

你可以在下图中看到结果。

使用::first-line伪元素"loading=

注意,每个段落的第一行受到影响,而不是第一句话。字体大小和元素宽度决定了第一行能容纳多少字符。

属性可以强制第一行的结束< br ><人力资源>元素,如下所示。

强制使用br元素结束一行"loading=

不幸的是,这远非完美。如果元素的宽度只够容纳72个字符,则添加< br >元素的第80个字符之后将不会影响::一线伪元素。你会得到一个奇怪的换行符。

类似地,使用不间断空格(,),以防止单词之间的换行不会产生影响::一线.相反,坐在前面的单词,将被强制放到与其后面的文本同一行。

生成的内容是使用::之前将成为第一行的一部分,如下图所示。

生成的内容成为第一行的一部分"loading=

如果生成的文本足够长,它将填充整个第一行。但是,如果我们加上a显示:块declaration-such作为P::before {content: '!! ';显示:块;}-内容将成为整个第一行。

当Chrome(如图所示),Edge和Safari将::放在{display: block;}内容之前作为第一行"loading=

不幸的是,Firefox 90及以下版本对此的处理方式不同。的值被正确地插入内容属性,但添加显示:块导致::一线规则完全失败。

并非所有属性都与::一线.仅支持以下几种:

  • 背景背景:前缀的属性<李类="">颜色
  • 字体字体- - - - - -属性的前缀组<李类="">字母间距
  • 行高
  • 不透明度
  • 文字修饰,包括扩展的属性,如text-decoration-line
  • 首字母
  • 文本阴影
  • 词间距
  • vertical-align

用户界面::选择

::选择伪元素是所谓“高亮伪元素”的定义之一<一个href="http://dev.w3.org/csswg/css-pseudo-4/" class="" target="_blank">CSS伪元素模块第4级规范。它以前是Selectors Level 3规范的一部分,是目前浏览器支持的唯一一个高亮显示伪元素。〇其他3处::目标文本::拼写错误而且::语法错误-仍在不断变化。

::选择,我们可以将CSS样式应用于用户用鼠标突出显示的内容。默认情况下,突出显示内容的背景和文本颜色由用户的系统设置决定。但是,开发人员可以更改高亮显示的外观—如下所示,其中选择颜色已设置为绿色。

一个使用::selection的高亮设置示例"loading=

不是每个CSS属性都可以使用::选择.规范只允许以下几个属性:

  • 颜色
  • 背景颜色
  • 文字修饰,以及相关属性,如text-decoration-style
  • 文本阴影
  • 边框颜色
  • 填充颜色
  • 笔划宽度

到目前为止,只有文本阴影颜色而且背景颜色已经在浏览器中实现。让我们来看一个例子:

这个CSS为用户突出显示的任何元素添加石灰绿色背景,并将文本颜色更改为深红色。该示例适用于支持的所有浏览器::选择,你可以在下图中看到效果。

使用::selection伪元素在石灰绿色背景上设置深红色文本"loading=

颜色组合

在选择前景色和背景色时::选择,请牢记易接近性。一些颜色组合无法产生足够的对比度,视力较低的用户无法阅读。其他颜色组合对于色盲用户来说可能难以辨认。在选择最终颜色之前,一定要使用对比度检查器和色盲模拟器。

自定义列表和摘要图标::标记

::标记是表示项目符号的伪元素还是元素的数字指示符显示的价值列表项.在大多数当前浏览器版本中,应用默认的用户-代理样式表显示:列表项<李>而且<摘要>元素。

任何带有列表项显示值将生成一个标记框,可以选择和样式使用::标记.使用一个显示其他值列表项——例如显示:内联显示:网格-删除标记框和使用的能力::标记

浏览器支持::标记

Safari 14.2及以下版本,Chrome/Edge 88及以下版本不支持::标记当与<摘要>元素。相反,使用:: -webkit-details-marker伪元素。但是,请记住:: -webkit-details-marker仅限于颜色而且字体属性。

::标记,我们可以为无序列表定义自定义项目符号内容,或者改变有序列表中数字的大小和颜色:

您可以在下面的图像中看到该规则的效果。

使用::marker设置有序列表的样式"loading=

只有一小部分CSS属性可以使用::标记,详见<一个href="https://www.w3.org/TR/css-lists-3/" class="" target="_blank">CSS列表和计数器模块级别3规格:

  • 颜色
  • 内容
  • 方向
  • 字体,以及它的手性,如字体大小而且粗细
  • 空白
  • 动画和过渡属性,例如animation-transition而且transition-delay
  • text-combine-upright
  • unicode-bidi

规范的未来版本可能会扩展这个列表。到目前为止,我们仅限于上述属性。

Safari的进一步限制

Safari 14.2及以下版本仅部分支持::标记.的值,但不显示颜色和字体样式内容财产。

由于这些限制,李::在可以更灵活地添加自定义项目符号或数字。使用::之前让你可以更好地控制项目和内容之间的水平间距,以及垂直对齐。它在旧的浏览器中也得到了很好的支持。

在支持两者的浏览器中,您可以选择同时使用两者::标记而且::之前

在前面的例子中,我们使用了::标记设置列表项项目符号的内容和颜色::之前管理标记和每个列表项内容之间的间距。您可以在下面看到结果。

使用::before来管理::标记和列表项内容之间的空格"loading=

在大多数情况下,列表样式属性与::标记伪元素。添加一个list-style:大写罗马数字例如,声明为无序列表设置数字标记。然后你可以使用::标记更改大小和颜色:

但有一个例外:如果你设置内容列表项的属性::标记,大多数浏览器将呈现该值而不是的值list-stylelist-style-type

下图显示了在Firefox 90中,::标记优先于list-style当两者都被定义和支持时。

支持::marker元素的Firefox 90显示content属性的值,尽管包含了列表样式的值"loading=

样式输入::占位符

基于文本的表单输入有一个占位符属性,它可以让我们添加关于字段期望的数据类型的提示:

的值,大多数浏览器都会显示占位符属性设置为不透明度降低的黑色文本,如下图所示。

具有占位符属性的电子邮件表单控件"loading=

属性可以更改此文本的外观::占位符伪元素选择器。让我们改变占位符文本的颜色和大小:

这就是我们看到的。

使用::placeholder更改表单控件中占位符文本的外观"loading=

占位符文本可能有害

占位符文本可以<一个href="https://www.smashingmagazine.com/2018/06/placeholder-attribute/" class="" target="_blank">让很多用户感到困惑尤其是那些有认知障碍的人。请考虑使用位于窗体控件附近的描述性文本。的占位符文本也不能替代<标识>元素。控件中使用标签,即使您使用占位符属性。

::占位符支持相同的CSS属性子集::一线.当改变外观时::占位符文字,选择颜色和文字大小,创造足够的对比。Firefox包含一些工具来检查基本的可访问性错误,比如文本和背景颜色的对比度差。

在本章的后面,我们将讨论: placeholder-shown伪类,它应用于表单控件本身。

伪类

正如本章前面提到的,伪类帮助我们根据无法从文档树中收集到的信息或无法使用简单选择器定位的信息定义文档的样式。其中有逻辑和语言学上的伪类,例如:不()而且:朗(),以及用户触发的伪类,例如:徘徊而且:专注,并形成状态伪类,例如:检查而且:无效

样式的:根文件的

在CSS代码段和演示中经常看到的一个伪类是:根伪类。的:根伪类匹配文档的根元素。在使用HTML时,这将匹配< html >元素。对于SVG文档,它是svg < >元素。

你可以选择:根超文本标记语言如果您需要为样式表定义一组自定义属性(变量),这些属性将在HTML和SVG文档之间共享。下面的示例使用:根和自定义属性来定义调色板:

从SVG或HTML文档链接此样式表可以使这些属性以使用超文本标记语言而选择器没有。

使用高亮显示页面片段:目标

片段标识符是以。开头的URL的一部分性质的,#大# footnote1.你可能用它们来创建页面内导航链接——有时被称为“跳转链接”。与:目标伪类时,我们可以突出显示与该片段对应的文档部分。

例如,你在讨论区有一系列评论:

加上一些CSS和其他花哨的部分,它可能看起来有点像下图所示。

一个你可能会在博客上看到的评论区必威滚"loading=

上面代码中的每个注释都有一个片段标识符,这意味着我们可以用一个锚链接直接链接到它,例如< a href = " #评论- 1146937891 " >< a href = " http://example.com/post/评论- 1146937891 " >.方法指定注释的样式:目标伪类:

当有人点击链接到文章< >类的元素评论,浏览器会把他们带到那条评论,并给它一个黄色的背景,如下所示。

黄色背景的评论区"loading=

你可以使用CSS的任意组合:目标,但要谨慎使用可以显示或隐藏内容的属性。调整z - index属性,例如,可以隐藏页面上的内容,但仍然将其暴露给辅助技术。这可能不是你想要的。

为没有子元素使用的元素设置样式:空

有时所见即所得(所见即所得)编辑器会添加空白< p >内容中的元素。如果样式表也使用。这些空元素可能会影响文档布局p作为类型选择器。可以在视觉上排除这些元素,但是使用:空伪类:

选择器规范定义的早期版本:空元素作为不包含任何元素或文本节点的元素—包括空格或换行符。这意味着对于大多数当前的实现,p:空匹配< p > < / p >,但不是< p > < / p >

也许意外,:空将<新兴市场类="">总是匹配< img >而且<输入>元素与通用选择器一起使用时(同样,:空*:空).为<输入>元素,即使字段包含文本也是如此。

与此同时,你可以用: placeholder-shown伪类用于选择空白表单控件字段。我们将在本章后面讨论这个选择器。

简洁而有弹性的选择器:是()

:是()伪类是css中可用的三个逻辑伪类之一——另外两个是:不()而且: ()(我们将在下一节中讨论)。

我可以:有()父选择器?

CSS selector Level 4还定义了第四个逻辑伪类,:有().不幸的是,:有()缺乏浏览器支持,所以我们不会在本章中讨论它。它有时被称为难以捉摸的“父选择器”,这是一个长期以来一直希望但难以实现的概念。2021年初,Igalia宣布了一项<一个href="https://groups.google.com/a/chromium.org/g/blink-dev/c/hqkcKdDrhXE" class="" target="_blank">原型的意图支持:有().完全的浏览器支持可能需要一些时间。与此同时,父元素选择仍然是JavaScript的专利。

你可以使用:是()创建更简洁和弹性的选择器。它是一个接受选择器列表作为参数的函数伪类。这里有一个例子:

在本例中,我们的选择器匹配<标题>< h2 >< h3 >,或< h4 >类的子元素文章< >.这相当于这样写:

这是一个更长的选择器列表!使用:是()显著减少选择器的长度。

之前:是()

的早期版本:是()伪类,: -webkit-any ().主要的区别在于: -webkit-any ()不支持选择器列表参数。Selectors Level 4规范的早期版本还定义了:匹配()伪类。取而代之的是:是()

:是()函数接受所谓的a<年代trong class="">宽容选择器列表.考虑下面的CSS:

上面的选择器匹配空白的输入元素<新兴市场类="">或有可见的占位符文本。这里有一个问题:大多数浏览器还不支持:空白伪类。尽管如此,我们的声明仍将应用于匹配的元素: placeholder-shown.宽容选择器列表告诉浏览器忽略浏览器不能理解的选择器。

宽容选择器列表是一个较新的CSS概念。早期的CSS规范定义了浏览器应该如何处理它不能完全解析的选择器列表,无论错误是由于缺乏浏览器支持还是拼写错误。如CSS 2.1规范所述:

css2.1赋予逗号特殊的含义()在选择器中。然而,由于不知道逗号是否会在未来的CSS更新中获得其他含义,所以整个语句应该是<一个href="https://www.w3.org/TR/2011/REC-CSS2-20110607/syndata.html" class="" target="_blank">忽略了如果在选择器的任何地方有错误,即使选择器的其余部分在css2.1中看起来合理。

换句话说,如果标准选择器列表中的任何项不受支持,浏览器将忽略整个规则。使用:是(),另一方面,让浏览器忽略它不理解的选择器。

浏览器支持

是的,:是()让我们编写弹性选择器,但是这种弹性仍然需要浏览器的支持。如果浏览器不支持:是()时,原解析规则仍然适用。整个规则将会失效。

用否定选择器:不()

:不()伪类则相反:是().它返回所有元素<新兴市场类="">除了对于那些匹配选择器参数的。例如,p: not (.message)每一个匹配< p >元素,<新兴市场类="">不上一节课消息

下面是一个使用文本输入类型和单选按钮的表单示例:

在HTML中,与无线电类型关联的标签有.label-radio类。我们可以用:不()来定位这些元素.label-radio类:

最终结果如下所示。

使用:not()伪类来设置表单标签的样式"loading=

这里有一个稍微复杂的例子。让我们为文本输入创建样式。这些包括输入类型,如号码、电子邮件、文本以及密码和URL。让我们通过排除单选按钮、复选框和范围输入来做到这一点:

:是(),:不()Pseudo-class接受单个选择器或选择器列表作为参数。它将匹配列表中所有受支持的选择器。

Chrome和Edge版本87及以下,以及Firefox版本83及以下,实现了早期的定义:不()它不接受选择器列表。相反,这些浏览器接受单个选择器参数。对于这些浏览器,我们需要一种不同的方法。

你的直觉可能会像这样重写前面的例子:

不幸的是,这行不通。每个选择器都会覆盖前一个选择器。这相当于键入:

相反,你需要使用以下选择器:

每一个实例:不()在这个选择器中进一步筛选列表,达到我们想要的结果。

伪元素不是有效的参数:是()而且:不().选择器如:是(::首字母):是(::标记,::-webkit-details-marker)不匹配任何元素,浏览器将忽略与该选择器相关的规则。

调整选择器特异性: ()

CSS选择器4级规范调用: ()“特异性调整伪类”。它也是一个函数伪类,接受选择器或选择器列表作为参数。使用: ()限制选择器的专一性的影响而不改变它。

考虑下面的CSS代码片段:

在这个例子中,我们的第一个规则比第二个规则有一个更具体的选择器。因此,第二条规则永远不会应用,链接也不会得到波浪状的粉红色下划线。

我们的导航链接缺少波浪状的粉色下划线,因为选择器不够具体"loading=

解决这个问题的方法之一就是改变资产净值一个导航:不是(徘徊).这样做会增加规则的专一性,这可能不是您想要的。让我们尝试: ()而不是:

添加: ()对浏览器说:“应用此样式到<一>只有在它们没有悬停状态时才有元素。”现在我们的导航链接有了弯弯曲曲的下划线。

使用:where()来调整选择器的特异性"loading=

再次,使用: ()不会改变特异性<新兴市场类="">价值选择器的。事实上,它的特异性值为零。相反,把它看作是阐明你的意图的一种方式。

根据索引选择元素

CSS还提供了基于元素在文档子树中的位置来匹配元素的选择器。这些被称为<年代trong class="">child-indexed伪类,因为它们依赖于元素的位置或顺序,而不是它的类型、属性或ID。有五个:

  • :第一个孩子
  • :胎
  • :独生子女
  • : nth-child ()
  • : nth-last-child ()

:第一个孩子而且:胎

你可能已经从名字中猜到了:第一个孩子而且:胎伪类使得选择节点(元素)的第一个子或最后一个子元素成为可能。和其他伪类一样,:第一个孩子而且:胎当它们是复合选择器的一部分时,副作用最小。

让我们看看下面的HTML和CSS:

这段代码产生如下所示的结果。使用:第一个孩子它本身匹配的元素比我们想要的要多。

使用:first-child本身匹配的元素比我们想要的要多"loading=

因为:第一个孩子是否不合格,二者兼有< h2 >元素和第一个<李>元素是粉红色的。毕竟,< h2 >的第一个子元素是身体< >和苹果<李>的第一个子元素是< ul >元素。但为什么剩下的<李>元素的绿色?嗯,那是因为:胎也是不合格的,还有< ul >是body的最后一个子。这实际上和打字是一样的*:第一个孩子而且*:胎

如果我们符合条件:第一个孩子而且:胎通过添加一个简单的选择器,这一切都更有意义。让我们把选择限制在列表项目上。改变:第一个孩子李:第一个孩子而且:胎李:胎.结果如下所示。

限定:使用简单选择器的第一个孩子和:最后一个孩子"loading=

:独生子女

:独生子女伪类匹配的元素是另一个元素的唯一子元素。在下面的例子中,我们有两个父元素< div >元素及其子元素。第一个< div >包含一项,而第二项包含三项:

使用.fruit:only-child {color: #9c27b0;/*紫罗兰*/}将匹配苹果< span class = "果" > < / span >,因为它是第一个的唯一孩子< div >.第二项都没有< div >但是,要匹配,因为有三个兄弟姐妹。您可以在下面看到它的样子。

用:only-child匹配元素"loading=

: nth-child ()而且: nth-last-child ()

可以选择文档的第一个和最后一个子项。但是如果我们想选择奇数或偶数元素呢?也许我们想选择文档子树中的第六个元素,或者对每第三个元素应用样式。这就是: nth-child (): nth-last-child ()伪类开始发挥作用。

就像:没有(),: nth-child ()和:nth-last-child ()也是函数伪类。他们接受一个单一的参数,该参数应该是以下其中之一:

  • 奇怪的关键字<李类="">的甚至关键字<李类="">整数(如2或8)<李类="">表单中的一个参数一个+ B(一个是阶跃间隔,B是抵消,和n表示正整数的变量)。这一个+ B语法说明请参见<一个href="http://www.w3.org/TR/css-syntax-3/" class="" target="_blank">CSS语法模块第三级

最后一项有一定程度的复杂性。我们很快就会回来。

两者之间的区别: nth-child ()而且: nth-last-child ()是起点。: nth-child ()向前计数和: nth-last-child ()数落后。CSS索引使用计数数字,从1开始,而不是0。

这两个: nth-child ()而且: nth-last-child ()对交替模式很有用。创建斑马条纹表行颜色是一个完美的用例。下面的CSS给偶数表行一个浅的蓝灰色背景:

下面是在浏览器中看到的结果。

使用:n -child(even)来样式表行"loading=

改变: nth-child (): nth-last-child ()由于计数是从底部开始的,因此将此条带颠倒。

从底部开始计数:n -last-child()"loading=

用更复杂的参数来尝试一些复杂的例子怎么样?我们将从下图所示的文档开始,其中包含20个< div >物品。

一个包含20个div元素的文档"loading=

: nth-child ()而且: nth-last-child (),我们可以在特定位置选择单个子节点。我们可以选择特定位置之后的所有子元素,或者我们可以选择带有偏移量的倍数元素。让我们改变第6项的背景颜色:

这就得到了下面的结果。

使用:n -child()按索引选择单个项"loading=

但是如果我们想选择每三个元素呢?这就是一个+ B语法有:

再一次,一个是阶跃间隔。这是一个乘数n,从0开始。因此,如果一个那么等于33 n匹配每第三个元素(第3、第6、第9个元素,等等)。这正是所发生的,如下图所示。

使用An+B语法选择每三个元素"loading=

计算与n

我们在前面注意到选择器很重要<新兴市场类="">元素从1。然而,n变量是否代表任何数字<新兴市场类="">从零.的3 n在我们的.item: nth-child (3 n)上面的选择器产生3 x 03 × 13 × 2等等。当然,3 x 0等于0,所以我们看不到任何基于此的视觉样式,因为没有元素0。注意这一点很重要n从0开始,因为,我们将在下面看到,当我们介绍+n + 8将从8开始产生结果(因为0 + 8= 8)。

当我们使用时,事情变得更加有趣: nth-child ()而且: nth-last-child ()选择某一点之后的所有元素。让我们试着选择除前七个元素之外的所有元素:

这里没有阶跃值。结果,n + 8匹配每个元素n从第8个元素开始,如下所示。

使用步骤An+B微语法选择项目8到20"loading=

负的偏移量

负偏移和范围值也是有效的。使用: nth-child (- n + 8)将我们的选择颠倒,并匹配前八个元素。

我们还可以使用偏移量和步长值来选择从第5个元素开始的每3个元素:

您可以在下面看到该选择器的结果。

从第五个元素开始,每隔第三个元素进行选择"loading=

根据索引选择特定类型的元素

前一节中讨论的伪类匹配元素,前提是它们占据文档子树中的给定位置。例如,p: nth-last-child (2)选择每一个< p >元素,它是其父元素的倒数第二个元素。

在本节中,我们将讨论<年代trong class="">类型化的子索引伪类.这些伪类也根据它们的索引值匹配元素,但是匹配仅限于特定类型或标记名称的元素,例如选择第五个< p >元素,或者全部为偶数索引< h2 >元素。

有5个这样的伪类,它们的名称与它们的非类型化对应类的名称相同:

  • : first-of-type
  • : last-of-type
  • : only-of-type
  • : nth-of-type ()
  • : nth-last-of-type ()

这些伪类和子索引伪类之间的差别很小。在哪里p: nth-child (5)只有当它是a时才匹配第五项< p >元素,p: nth-of-type (5)匹配所有< p >元素,然后找到第五个< p >元素在其中。

让我们从一个略有不同的文档开始。它仍然有20个项目,但其中一些是< p >元素,有些是< div >元素。的< p >元素有圆角,如下图所示。

有20个条目的文件,p个元素表示圆角"loading=

使用: first-of-type: last-of-type,:仅输入

: first-of-type,我们可以选择第一个匹配选择器的元素。不如我们先把第一份给你< p >石灰绿色背景元素:

这将匹配每一个< p >第一个元素< p >元素的父元素。

匹配第一个子元素p"loading=

: last-of-typePseudo-class的工作原理类似,匹配其父类的最后一个此类元素。

:last-of-type伪类匹配类型的最后一个元素"loading=

然而,: only-of-type如果某个元素是其父元素的该类型的唯一子元素,则匹配该元素。在下图中,我们使用p:only-of-type来匹配段落元素的唯一子元素。

使用p:only-of-type来匹配作为段落元素的唯一子元素"loading=

让我们看另一个使用的例子: first-of-type,但这次用的是伪元素。还记得:首字母本章前面提到的伪元素?正如你所看到的,它为每个元素都创建了一个初始资本。现在我们更进一步,将初始大写限制在第一段:

现在我们的段落将有一个首字母大写,即使它前面有一个标题。

使用:first-of-type和::first-letter伪元素"loading=

使用: nth-of-type ()而且: nth-last-of-type ()

: nth-of-type ()而且: nth-last-of-type ()也是函数伪类。他们接受同样的论点: nth-child ()而且: nth-last-child ().但就像: first-of-type而且: last-of-type时,索引解析为相同类型的元素。例如,选择每个奇数< p >元素,我们可以使用奇怪的关键字与: nth-of-type ()

从下图中可以看出,这只匹配奇数<新兴市场类="">段元素,即使它们之间还有其他元素类型。

选择奇数索引的p个元素:n -of-type(奇数)"loading=

同样,使用: nth-last-of-type(甚至)选择偶数< p >元素,但从最后开始计数< p >元素,在本例中是第18项。

选择偶数索引的p个元素:n -last-of-type(偶数)"loading=

使用*类型的带有非元素选择器的伪类

“of-type”选择器设计为与元素选择器一起使用,例如p: first-of-type.您可能会倾向于使用“of-type”选择器来定位其他类型钩子的第一个实例,例如类.item: first-of-type.但这可能会导致意想不到的结果。在接下来的标记中,我们有三个列表项和一个段落元素,它们的class属性值都为

假设我们只想以类的第一个元素为目标.如果我们添加一条规则.item:first-of-type{背景:洋红色;},您可能希望只有第一个列表项具有洋红色背景。然而,正如你在下面的图片中看到的那样,事实并非如此。

当:first-of-type作为复合选择器的一部分与类名一起使用时,浏览器如何解析它"loading=

相反,段落元素的背景也是洋红色的。因为它是文档中的第一个段落类型元素,所以它也匹配.item: first-of-type选择器。

选择器第4级规范添加了一个新的参数语法: nth-of-type ()/: nth-last-of-type ()为了使其行为更符合开发人员的期望:的[S]语法,[S]是非元素选择器。

要使用前面的标记示例,可以选择元素的第一个实例类使用以下CSS:

这与第一个元素匹配类属性值。然而,到目前为止,Safari是唯一支持这种语法的浏览器。

基于输入的样式化表单字段

让我们看一下一些特定于表单字段和表单字段输入的伪类。这些伪类可用于根据用户输入的有效性设置字段样式,无论该字段是必需的还是当前启用的。

接下来的所有伪类都是特定于表单的。因此,不太需要使用选择器来限制范围。使用:启用不会产生副作用< span >元素。但是,当您希望以不同的方式设置不同类型的表单控件时,限制范围是有帮助的。

:启用而且:禁用

顾名思义,这些伪类匹配具有(或缺乏)HTML5的元素禁用属性。这可以是诸如<输入><选择>< >按钮<自定义字段>

默认情况下启用表单元素。也就是说,只有当禁用属性已设置。使用输入:启用将匹配每个输入元素没有禁用属性。相反,按钮:禁用将匹配所有按钮元素与禁用属性:

下图显示了:启用而且:禁用我们的国家< >按钮元素。

处于:enabled(左)和:disabled(右)状态的按钮"loading=

要求:而且:可选

属性的存在或不存在决定了必需和可选状态要求属性。记住,在HTML5中,属性的存在与否决定了它的值。换句话说,要求= " false "效果与要求= " true "要求= "需要"而且要求.例如:

大多数浏览器只在表单提交后指示是否需要该字段。与要求:伪类,我们可以在提交前向用户指示该字段是必需的。例如,下面的CSS将为我们的电子邮件字段添加黄色边框:

用:required表示一个字段是必需的"loading=

:可选类的工作原理类似,通过匹配不具有要求属性。以下面的CSS为例:

这将在Firefox 86中产生以下结果。

一个可选的选择元素,样式为:optional伪类,在Firefox 86中呈现"loading=

:检查

与我们已经讨论过的其他与表单相关的伪类不同,:检查仅适用于单选和复选框窗体控件。顾名思义,这个伪类允许我们为选定的输入定义单独的样式。

为了创建跨浏览器的自定义单选按钮和复选框输入,我们需要在选择器上稍微聪明一点。让我们结合一个相邻的兄弟组合子,一个伪元素,和:检查创建自定义单选按钮和复选框控件。例如,当一个标签的单选按钮被选中时,要改变它的样式,我们可以使用下面的CSS:

这将使标签加粗,并在选中其关联控件时增加其大小。但是,我们可以通过使用::之前我们的伪元素<标识>元素注入自定义控件:

这为我们提供了如下所示的定制控件。

使用相邻的兄弟组合子和伪类之前的::创建自定义无线电控件"loading=

当然,为了使这种技术工作,我们的HTML需要适当地结构化:

  • <标识>元素必须与其相邻<输入>控制。<李类="">窗体控件必须具有id属性之外的的名字属性(例如,).<李类="">标签必须有属性,其值必须与表单控件的ID匹配(例如,巧克力<标签=“巧克力" > < / >标签).

关联<标识>使用,确保当用户单击或点击标签或其子伪元素(::之前).

:不确定

:不确定伪类允许您为处于不确定状态的元素设置样式。只有三种类型的元素可以具有不确定状态:

  • < >进步元素,当不清楚还有多少工作要做时(比如等待服务器响应时)<李类="">分组输入(type =广播)表单控件,然后用户选择一个选项<李类="">输入(type =复选框)控件时,不确定的属性设置为真正的(这只能通过DOM脚本来完成)

不确定的复选框

CSS-Tricks.com提供了一个有用的<一个href="https://css-tricks.com/indeterminate-checkboxes/" class="" target="_blank">不确定复选框控件概述,包括何时以及为什么要使用它们。

让我们看一个使用< >进步元素:

注意这里我们没有包含a价值属性。对于大多数基于WebKit和blink的浏览器,是否存在价值属性决定是否< >进步元素具有不确定状态。另一方面,Firefox设置了一个不确定的状态< >进步元素时,价值属性为空。

不幸的是,< >进步元素仍然需要供应商前缀的伪元素。这是我们的CSS:

这个CSS提供了如下所示的进度条。

状态不确定的进度条"loading=

价值进步元素发生变化时,它将不再具有:不确定状态。

:在射程内而且:超出范围

:在射程内而且:超出范围伪类可用于范围、数字和日期输入表单控件。使用:在射程内而且:超出范围需要设置最小值和/或马克斯属性值。下面是一个使用数字输入类型的例子:

让我们添加一点CSS来改变样式,如果值在1到100的范围之内或之外:

如果用户输入-3或101,则背景颜色# picknum将更改为黄色,如定义在我们:超出范围规则。

样式:超出范围的值"loading=

否则,它将保持白色,如定义中的:在射程内规则。

:有效而且:无效

:有效而且:无效伪类,我们可以根据表单输入是否满足我们的要求来设置样式。这将取决于类型或模式属性值施加的验证约束。例如,<输入>type = "电子邮件"如果用户输入是" foo 123 "则无效,如下所示。

处于无效状态的电子邮件字段"loading=

在以下情况下,表单控件将处于无效状态:

  • 当必填字段为空时<李类="">当用户的输入与类型或模式约束不匹配时,例如美国广播公司进入输入(type =数量)<李类="">当字段的输入落在其范围之外时最小值而且马克斯属性值

默认情况下,带空值的可选字段有效。显然,如果用户输入满足字段的约束,那么它就处于有效状态。

表单控件可以同时具有多个状态。因此,您可能会发现自己在管理专用性(将在下一节讨论)和级联冲突。缓解这种情况的一种方法是限制在项目中使用哪些伪类。例如,不必费心定义an:可选规则集,如果您还将定义:有效规则集。

但是,也可以将伪类链接起来。例如,我们可以混合:专注而且:无效只在元素有焦点时才对其进行样式化的伪类:输入:专注:无效的.通过链接伪类,我们可以为具有多个状态的元素设置样式。

: placeholder-shown

在哪里::占位符与占位符文本匹配: placeholder-shown伪类的比赛<新兴市场类="">元素目前有一个可见的占位符。占位符文本通常在表单控件为空时可见——也就是说,在用户在字段中输入任何信息之前。任何可以使用的属性<输入>元素也可以用于: placeholder-shown。

记住,:无效属性的窗体控件进行匹配要求属性,没有用户数据。但是我们可以通过组合来排除没有输入数据的字段:无效:不()而且: placeholder-shown

下图显示了结果。这两个表单字段都是必需的,但是只有用户输入的数据无效的字段会突出显示。

这两个表单字段都是必需的,但是只有用户输入的数据无效的字段会突出显示"loading=

我们的第一个字段在视觉上被标记为无效,因为用户输入了无效的电子邮件地址。但是,第二个字段没有改变,因为用户没有输入数据。

正如本节前面提到的,占位符文本会带来可用性挑战。出于这个原因,最好避免。但是,删除属性将阻止我们使用: placeholder-shown伪类。

但有一个简单的解决办法。的值占位符属性赋给空白字符:占位符= " ".这让我们避免了与使用占位符文本相关的可用性问题,但仍然利用了: placeholder-shown选择器。

结论

你已经看到这一章的结尾了!我知道你一时难以接受。现在你应该已经很好地理解了:

  • 哪些类型的选择器可用于匹配元素<李类="">伪元素和伪类的区别<李类="">如何使用由选择器级别3和4规范引入的新的伪类

在下一章中,我们将介绍一些编写可维护、可扩展CSS的黄金法则。

社区问题

<按钮类="边境-2 rounded-sm transition-colors cursor-pointer disabled:cursor-not-allowed disabled:pointer-events-none border-none text-primary-700 hover:text-primary-500 dark:text-primary-300 dark:hover:text-primary-200 disabled:text-primary-100 px-2 py-1 text-xs font-bold flex items-center">关闭<年代vg aria-hidden="true" focusable="false" data-prefix="far" data-icon="times" class="svg-inline--fa fa-times fa-w-10 m-0 p-0 ml-1 text-sm" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 320 512">
Baidu

虽然我们可以根据属性值选择元素,如上面所讨论的,但选择器如(rel =外部)不匹配,因为rel价值并不完全是外部.相反,我们需要使用一个可以容纳空格分隔值的选择器,其形式为(att ~ = val)