"CSS选择器用于选择第一个具有类的元素"

11 浏览
0 Comments

"CSS选择器用于选择第一个具有类的元素"

我有很多带有类名为 red 的元素,但是我似乎不能使用以下 CSS 规则选择第一个带有 class="red" 的元素:

.home .red:first-child {
    border: 1px solid red;
}


    blah

first

 

second

 

third

 

fourth

 

这个选择器有什么问题,我该如何修正它以定位第一个带有类名为 red 的元素?

admin 更改状态以发布 2023年5月21日
0
0 Comments

:first-child选择器是用来选择父标签的第一个子标签的。所以这个例子会起作用(在这里试试 here):


    

first

second

如果您已将标签嵌套在不同的父标签下,或者如果您的类为red的标签不是父标签下的第一个标签,则这不会起作用。

还请注意,这不仅适用于整个文档中的第一个这样的标签,而且每次在其周围包装一个新的父标签时都会自动应用,例如:

    

first

second

third

fourth

firstthird将变成红色。

对于您的情况,您可以使用:nth-of-type选择器:

.red:nth-of-type(1)
{
    border:5px solid red;
} 


    blah
    

first

second

third

fourth

鸣谢Martyn,他删除了包含这种方法的答案。

有关:nth-child():nth-of-type()的更多信息,请访问http://www.quirksmode.org/css/nthchild.html

请注意,这是CSS3选择器,因此一些旧版本的浏览器可能无法像预期的那样工作(例如IE8或更早版本)。请访问https://caniuse.com/?search=nth-of-type以了解更多详情。

0
0 Comments

这是一个作者误解:first-child 如何工作的最著名的例子之一。在 CSS2 中介绍的 :first-child 伪类代表 其父元素的第一个子元素。就是这样。有一个非常普遍的误解,认为它会拾取任何第一个匹配复合选择器其余条件的子元素。由于选择器的工作方式(请参见 这里进行解释),这是不正确的。

选择器级别 3 引入了一个 :first-of-type 伪类,它代表其元素类型的同级元素中的第一个元素。 这个答案 通过插图解释了 :first-child:first-of-type 之间的区别。然而,与 :first-child 一样,它不考虑任何其他条件或属性。在 HTML 中,元素类型由标记名称表示。在问题中,该类型是 p

不幸的是,没有类似的 :first-of-class 伪类来匹配给定类的第一个子元素。在本回答发布时,选择器级别 4 的新发布的 FPWD 引入了一个 :nth-match() 伪类,它围绕现有的选择器机制进行设计,如我在第一段中提到的添加了一个选择器列表参数,通过可以提供其余复合选择器以获取所需的过滤行为。在最近几年中,这个功能被 并入了 :nth-child() 自身,选择器列表出现为可选的第二个参数,为了简化事情并避免误解 :nth-match() 匹配整个文档(请参见下面的最终说明)。

在等待跨浏览器支持(说真的,已经快10年了,而在这些年中只有一个实现),Lea Verou和我都独立开发了一个解决方法(她先搞定了!)首先将所需的样式应用于该类所有元素:

/* 
 * Select all .red children of .home, including the first one,
 * and give them a border.
 */
.home > .red {
    border: 1px solid red;
}

…然后使用覆盖规则中的通用同级元素选择器 ~取消后面带有该类的元素的样式:

/* 
 * Select all but the first .red child of .home,
 * and remove the border from the previous rule.
 */
.home > .red ~ .red {
    border: none;
}

现在,只有第一个带有class="red"的元素才会有边框。

下面是规则应用示例:

.home > .red {
    border: 1px solid red;
}
.home > .red ~ .red {
    border: none;
}


  blah         
  

first

second

third

fourth

  1. 不应用任何规则;不会呈现边框。
    此元素没有red类,因此被跳过。

  2. 只应用第一个规则;呈现红色边框。
    此元素具有red类,但是它不是父级中具有red类的任何元素的前一个元素。因此,第二个规则不会应用,只会应用第一个规则,元素保持其边框。

  3. 应用两个规则;不会呈现边框。
    此元素具有red类。它之前至少有一个具有red类的其他元素。因此,两个规则都将应用,并且第二个border声明将覆盖第一个,从某种意义上来说,将其“撤消”。

作为一个额外的福利,尽管它是在选择器3中引入的,但是通用兄弟组合器实际上在IE7及更高版本中得到相当好的支持,不像:first-of-type:nth-of-type()只有在IE9及更高版本中才得到支持。如果你需要好的浏览器支持,你很幸运。

事实上,兄弟组合器是这种技术中唯一重要的组件,它有如此惊人的浏览器支持,使得这种技术非常通用 - 你可以根据其他东西(而不是类选择器)过滤元素:

- 你可以使用这个来解决IE7和IE8中的:first-of-type,只需提供一个类型选择器而不是一个类选择器(关于在后面的部分对其不正确使用的更多说明):

 article > p {
     /* Apply styles to article > p:first-of-type, which may or may not be :first-child */
 }
 article > p ~ p {
     /* Undo the above styles for every subsequent article > p */
 }


- 你可以按属性选择器或任何其他简单选择器而不是类过滤。
- 即使伪元素在技术上不是简单选择器,你也可以将这个覆盖技术与伪元素结合使用。

请注意,为了使这个工作,您需要事先知道其他兄弟元素的默认样式,以便覆盖第一条规则。此外,由于这涉及覆盖CSS中的规则,因此您无法通过单个选择器实现与选择器API或Selenium的CSS定位器一样的事情。最后需要注意的是,此答案假设问题是要查找具有特定类的任意数量的第一个子元素。无论是伪类还是通用CSS解决方案都无法解决整个文档中复杂选择器的第n个匹配项——解决方案是否存在严重依赖于文档结构。jQuery提供了:eq():first:last等功能,但请再次注意,它们与:nth-child()等功能非常不同。使用选择器API,您可以使用document.querySelector()来获得第一个匹配项:

var first = document.querySelector('.home > .red');

或使用document.querySelectorAll()和索引器来选择任何特定的匹配项:

var redElements = document.querySelectorAll('.home > .red');
var first = redElements[0];
var second = redElements[1];
// etc


尽管由Philip Daubmeier提供的原始已接受答案中的.red:nth-of-type(1)解决方案有效(原本由Martyn编写,但已被删除),但它的行为方式与您期望的不同。

例如,如果您只想选择这里的p

那么您不能使用.red:first-of-type(相当于.red:nth-of-type(1)),因为每个元素都是其类型(分别是pdiv)的第一个(也是唯一的)元素,因此选择器将匹配两个元素。

当某个类的第一个元素也是其类型的第一个元素时,伪类会起作用,但这只是巧合。Philip的答案中展示了这种行为。一旦在此元素之前插入同类型的元素,选择器将失效。取题目中的标记:

  blah
  

first

second

third

fourth

使用.red:first-of-type规则会起作用,但是一旦添加了另一个没有类的p

  blah
  

dummy

first

second

third

fourth

...选择器将立即失效,因为第一个.red元素现在是第二个p元素。

0