一尘不染

可以重复使用类型选择器以提高特异性吗?

css

该规范对于计算CSS具体规定:(粗体雷)

注意:允许重复出现同一 简单选择器 ,并且确实会增加特异性。

因此,例如,.class.class {}具有两倍的特异性比.class {}-
DEMO

但是,对于“ 简单选择器 ” 一词,规格说明如下:(粗体字)

简单选择器可以是 类型选择 器,也可以是通用选择器,紧随其后的是零个或多个属性选择器,ID选择器或伪类(以任何顺序)。

因此,由于规范说允许重复出现相同的 简单选择器
-这意味着您也可以重复使用类型选择器。

那么很明显这样的事情是行不通的:h1h1 { }

所以我尝试了:h1[]h1[] {}-也不起作用,

所以我想知道是否有办法做到这一点?


阅读 313

收藏
2020-05-16

共1个答案

一尘不染

可以使用类型选择器来提高选择器的特异性,但传统上无法。其原因将在下面说明,但是对于那些只是在寻找替代方案的人,有两种。您可以:not()在单个复合选择器中链接包含类型选择器的伪类:

h1                      {} /* 1 type  -> specificity = 0-0-1 */
h1:not(_)               {} /* 2 types -> specificity = 0-0-2 */
h1:not(_):not(_)        {} /* 3 types -> specificity = 0-0-3 */
h1:not(_):not(_):not(_) {} /* 4 types -> specificity = 0-0-4 */

或者,如果您需要支持不支持的旧版浏览器,则:not()可以将冗余类型选择器(例如html和)添加body到复杂选择器的开头,尽管在这种情况下您的限制更大,因为您可能无法考虑所有元素:

h1                {} /* 1 type  -> specificity = 0-0-1 */
body h1           {} /* 2 types -> specificity = 0-0-2 */
html body h1      {} /* 3 types -> specificity = 0-0-3 */
html body tr > td {} /* 4 types -> specificity = 0-0-4, assumes every td is a child of tr */

不用说,这些被认为是特异性黑客。与所有其他CSS hack一样,请尽量少用。


复合选择器在所有其他简单选择器之前最多只能具有一个类型选择器。从选择器3(将其称为简单选择器序列)中:

简单选择的序列 是不是由一个组合子分隔的简单选择器的链。它总是以类型选择器或通用选择器开头。序列中不允许使用其他类型选择器或通用选择器。

和选择器4:

化合物选择
是不是由一个组合子分隔的简单选择的序列。如果它包含类型选择器或通用选择器,则该选择器排在序列的首位。序列中仅允许使用一种类型选择器或通用选择器。

仅类型选择器和通用选择器受此规则约束;您可以组合并重复其他简单的选择器以提高特异性。规范也许可以在有关计算特异性的部分中提醒读者这一点,但我认为这不是绝对必要的。

从未明确说明此规则的原因,但可以很容易地推论出:

  • 请记住,类型选择器仅包含一个标识符,例如h1。这与其他在语法中具有自己的区别符号的简单选择器不同,例如ID(#),类(.),伪类(:)或属性选择器([])。您将无法拥有多个连续的类型选择器,而无法单独解析它们。

  • 而且即使您 可以 链接类型选择器(例如,如果它们之间有另一个简单的选择器),它唯一可能的用途是作为特定性技巧,如问题中所述,这意味着您只能在以下情况下使用它:所有类型选择器都相同;类型选择器的其他组合无法正常工作。

这是因为Selectors假定文档语言将每个元素定义为完全具有一种元素类型。例如,在HTML中,an h1始终是h1;
它永远不能是任何其他类型的元素。化合物选择要求,既是一个元素h1,以及一个p永远无法匹配任何内容,对于同样的原因,类似的[type=text][type=password]不能匹配,不支持重复属性的文件语言的任何东西。

但是,考虑到以上几点,仍然可以使用:not()伪类创建一个复合选择器,该选择器包含多个类型选择器以实现特异性。

  • :not()伪类的特异性等于其参数。伪类本身不计算在内。第一个链接中提到了这一点。这意味着的特异性:not(h1)等同于h1-一种类型选择器。

  • 由于一个元素只能是一种类型,这意味着:not()与任何其他类型的选择器将保证匹配。

  • 由于复合选择器可以包含任意数量的伪类,因此即使否定全部使用相同的类型选择器,也可以根据需要重复否定多次。

  • 而且由于选择器并不关心选择器在任何特定文档语言的上下文中是否有意义,因此您可以使用类型选择器,只要该选择器满足标准HTML语法中的选择器语法,就绝不会匹配该元素。类型选择器。类型选择器仅由CSS标识符组成,因此 任何CSS标识符都是fair game 。包括_

2020-05-16