: nth-child () 또는 : nth-of-type ()을 임의의 선택기와 결합 할 수 있습니까?


116

임의의 선택자와 일치하는 (또는 일치하지 않는) 모든 n 번째 자식을 선택하는 방법이 있습니까? 예를 들어, 모든 홀수 테이블 행을 선택하려고하지만 행의 하위 집합 내에서 다음을 수행합니다.

table.myClass tr.row:nth-child(odd) {
  ...
}
<table class="myClass">
  <tr>
    <td>Row
  <tr class="row"> <!-- I want this -->
    <td>Row
  <tr class="row">
    <td>Row
  <tr class="row"> <!-- And this -->
    <td>Row
</table>

그러나 "row"클래스인지 여부에 관계없이 :nth-child()모든 tr요소 를 계산하는 것처럼 보이 므로 찾고있는 두 개 대신 하나의 "row"요소로 끝납니다 . 같은 일이 :nth-of-type().

누군가 이유를 설명 할 수 있습니까?

답변:


144

이것은 방법 :nth-child():nth-of-type()작업 에 대한 오해로 인해 발생하는 매우 일반적인 문제입니다 . 안타깝게도 현재 선택기 기반 솔루션은 없습니다. 선택자는 홀수, 짝수 또는 임의의 an+b위치 a != 1와 같은 패턴을 기반으로 임의의 선택자와 일치하는 n 번째 자식을 일치시키는 방법을 제공하지 않기 때문 b != 0입니다. 이것은 클래스 선택자뿐만 아니라 속성 선택자, 부정 및 단순한 선택 자의 더 복잡한 조합까지 확장됩니다.

:nth-child()의사 클래스 사이의 요소를 계산 모두 같은 부모 아래에서 자신의 형제를. 나머지 선택기와 일치하는 형제 만 계산하지 않습니다. 유사하게, :nth-of-type()유사 클래스 는 동일한 요소 유형을 공유하는 형제를 계산합니다. 이는 나머지 선택자가 아닌 HTML의 태그 이름을 참조합니다.

이것은 또한 같은 부모의 모든 경우 자녀는 자녀 테이블 본체의 경우, 예를 들어, 같은 요소 유형의 것을 의미 tr요소 나 어린이 만하는리스트 요소 li요소는 다음 :nth-child():nth-of-type()동일하게 동작합니다, 즉, 의 모든 값에 대해 an+b, :nth-child(an+b)그리고 :nth-of-type(an+b)요소의 동일한 세트를 일치합니다.

사실, 다음과 같은 가상 클래스를 포함하는 특정 화합물 선택기 모두 간단한 선택기, :nth-child():not()작업 독립적으로 서로, 오히려 찾고보다 일부 선택기의 나머지가 매칭 소자.

이는 또한 각 개별 화합물 선택자 1 내에서 단순 선택자간에 순서 개념이 없음 을 의미합니다. 즉, 예를 들어 다음 두 선택자가 동일하다는 것을 의미합니다.

table.myClass tr.row:nth-child(odd)
table.myClass tr:nth-child(odd).row

영어로 번역하면 둘 다 다음을 의미합니다.

다음의 모든 tr독립 조건과 일치 하는 요소를 선택하십시오 .

  • 부모의 홀수 번째 자식입니다.
  • "row"클래스가 있습니다. 과
  • table"myClass"클래스가 있는 요소 의 자손입니다 .

(단지 포인트를 집으로 옮기기 위해 여기에서 정렬되지 않은 목록을 사용하는 것을 알 수 있습니다.)

현재 순수한 CSS 솔루션이 없기 때문에 스크립트를 사용하여 요소를 필터링하고 그에 따라 스타일 또는 추가 클래스 이름을 적용해야합니다. 예를 들어, 다음은 jQuery를 사용하는 일반적인 해결 방법입니다 ( tr테이블 내에 요소로 채워진 행 그룹이 하나만 있다고 가정 ).

$('table.myClass').each(function() {
  // Note that, confusingly, jQuery's filter pseudos are 0-indexed
  // while CSS :nth-child() is 1-indexed
  $('tr.row:even').addClass('odd');
});

해당 CSS 사용 :

table.myClass tr.row.odd {
  ...
}

Selenium과 같은 자동화 된 테스트 도구를 사용하거나 lxml과 같은 도구로 HTML을 처리하는 경우 이러한 도구 중 대부분은 XPath를 대안으로 허용합니다.

//table[contains(concat(' ', @class, ' '), ' myClass ')]//tr[contains(concat(' ', @class, ' '), ' row ')][position() mod 2)=1]

다른 기술을 사용하는 다른 솔루션은 독자에게 연습으로 남겨집니다. 이것은 단지 설명을위한 간단하고 인위적인 예입니다.


그만한 가치를 위해, 주어진 선택자와 일치하는 모든 n 번째 자식을 선택하는 특정 목적을 위해 선택기 레벨 4에 추가 할 표기법대한 확장에:nth-child() 대한 제안 이 있습니다. 2

일치 항목을 필터링 :nth-child()할 선택자는 기존 선택자 구문에서 지시 한대로 선택자가 시퀀스에서 서로 독립적으로 작동하는 방식으로 인해에 인수로 제공됩니다 . 따라서 귀하의 경우에는 다음과 같이 보일 것입니다.

table.myClass tr:nth-child(odd of .row)

(기민한 독자는 :nth-child(odd of tr.row)단순한 선택자 tr이고 :nth-child()서로 독립적으로 작동하기 때문에 이것이 대신 있어야한다는 것을 바로 알아 차릴 것입니다 . 이것은 선택자를 받아들이는 기능적 가상 클래스의 문제 중 하나입니다. 웜 캔입니다. 대신이 답변의 중간에 열리지 않습니다. 대신 대부분의 사이트는 tr테이블 본문에서 서로의 형제 요소가 아닌 다른 요소를 가지지 않으므로 두 옵션 중 하나를 기능적으로 동일하게 만들 것입니다.)

물론, 완전히 새로운 사양의 새로운 제안이기 때문에 몇 년 후에야 구현 될 것입니다. 그동안 위와 같이 스크립트를 계속 사용해야합니다.


1 유형 또는 범용 선택기를 지정하는 경우 먼저 와야합니다. 그러나 이것은 선택자가 기본적으로 작동하는 방식을 변경하지 않습니다. 통사론 적 특징에 지나지 않습니다.

2 이것은 원래로 제안되었지만 :nth-match(), 주어진 선택자와 일치하는 다른 모든 요소가 아닌 형제에 대해서만 상대적인 요소를 계산하기 때문에 2014 년부터 기존의 확장으로 용도가 변경되었습니다 :nth-child().


3
"(여기에서 순서가없는 목록을 사용하는 것을 알 수 있습니다. 단지 포인트를 집으로 가져 가기 위해)"더 많은 사람들이 순서가 지정된 총알과 순서없는 총알을 사용하는 것에 대해 신중하게 생각했으면합니다. 답변 주셔서 감사합니다.
The Red Pea

1
@The Red Pea : 가장 큰 HTML 애완 동물 중 하나 : "최고 / 최저에서 최저 / 최고 순으로 :"다음에 정렬되지 않은 목록이 있습니다. 제 말은 진지하게?
BoltClock

6

별로 ..

문서에서 인용

:nth-child가상 클래스는 + (B-1)를 갖는 요소와 일치하는 문서 트리에서 이전 형제 주어진 양 또는 N에 대한 제로 값을, 그리고 부모 구성 요소를 갖는다.

자체 선택자이며 클래스와 결합되지 않습니다. 규칙에서 동시에 두 선택자를 충족해야하므로 :nth-child(even)테이블 행에도 .row클래스 가 있으면 표시됩니다 .


0

nth-of-type동일한 유형의 요소의 nth-child인덱스에 따라 작동 하지만 형제 요소의 유형에 관계없이 인덱스에 따라서 만 작동합니다.

예를 들면

<div class="one">...</div>
<div class="two">...</div>
<div class="three">...</div>
<div class="four">...</div>
<div class="five">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
<div class="rest">...</div>

위의 html에서 나머지 클래스가있는 모든 요소를 ​​숨기려고한다고 가정합니다.

이 경우 nth-childnth-of-type모두 같은 요소를 정확히 동일하게 작동 것이다 같은 유형 <div>CSS를해야하므로

.rest:nth-child(6), .rest:nth-child(7), .rest:nth-child(8), .rest:nth-child(9), .rest:nth-child(10){
    display:none;
}

또는

.rest:nth-of-type(6), .rest:nth-of-type(7), .rest:nth-of-type(8), .rest:nth-of-type(9), .rest:nth-of-type(10){
    display:none;
}

이제 당신은 차이점이 무엇인지 궁금해야 nth-child하고 nth-of-type이 그렇게하면 차이

HTML이

<div class="one">...</div>
<div class="two">...</div>
<div class="three">...</div>
<div class="four">...</div>
<div class="five">...</div>
<p class="rest">...</p>
<p class="rest">...</p>
<p class="rest">...</p>
<p class="rest">...</p>
<p class="rest">...</p>

위의 html에서 .rest요소 의 유형 은 다른 .rest단락과 다른 요소는 div이므로이 경우 사용 nth-child하면 다음과 같이 작성해야합니다

.rest:nth-child(6), .rest:nth-child(7), .rest:nth-child(8), .rest:nth-child(9), .rest:nth-child(10){
    display:none;
}

그러나 nth-of-type css를 사용하면 이것이 될 수 있습니다.

.rest:nth-of-type(1), .rest:nth-of-type(2), .rest:nth-of-type(3), .rest:nth-of-type(4), .rest:nth-of-type(5){
    display:none;
}

.rest요소의 유형이 그렇듯이 <p>여기 nth-of-type에서 유형을 감지하고 .rest.NET의 1, 2, 3, 4, 5 번째 요소에 CSS를 적용했습니다 <p>.


<tr>태그에 얼마나 유용 할까요?
Alexis Wilke 2016 년

0

xpath로 할 수 있습니다. 같은 //tr[contains(@class, 'row') and position() mod 2 = 0]것이 작동 할 수 있습니다. 클래스를 더 정확하게 일치시키는 방법에 대한 자세한 내용을 확장하는 다른 SO 질문이 있습니다.


0

여기 당신의 대답입니다

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>TEST</title>

  <style>

    .block {
      background: #fc0;
      margin-bottom: 10px;
      padding: 10px;
    }
    /* .large > .large-item:nth-of-type(n+5) {
      background: #f00;
    } */

    .large-item ~ .large-item ~ .large-item ~ .large-item ~ .large-item {
      background: #f00;
    }

  </style>
</head>
<body>

<h1>Should be the 6th Hello Block that start red</h1>
<div class="small large">
  <div class="block small-item">Hello block 1</div>
  <div class="block small-item large-item">Hello block 2</div>
  <div class="block small-item large-item">Hello block 3</div>
  <div class="block small-item large-item">Hello block 4</div>
  <div class="block small-item large-item">Hello block 5</div>
  <div class="block small-item large-item">Hello block 6</div>
  <div class="block small-item large-item">Hello block 7</div>
  <div class="block small-item large-item">Hello block 8</div>
</div>

</body>
</html>

0

nth-child를 사용하고 숨겨진 태그를 건너 뛰는 것과 관련된 모든 질문은 이것의 속임수로 리디렉션되는 것처럼 보이므로 여기에 남겨 두겠습니다. nth-child가 숨겨진 요소를 무시하도록 영리한 CSS 접근 방식을 사용하는 https://blog.blackbam.at/2015/04/09/css-nth-child-selector-ignore-hidden-element/ 블로그를 보았습니다. 다음과 같이 :

다음 CSS는 어떤 요소에 cpw 클래스가 있는지에 관계없이 모든 두 번째 표시 요소에 여백을 추가합니다.

.cpw {
    display:none;
}

.video_prewrap {
    margin-right:20px;
}

.video_prewrap:nth-child(2n) {
    margin-right:0;
}

.cpw ~ .video_prewrap:nth-child(2n) {
    margin-right:20px;
}

.cpw ~ .video_prewrap:nth-child(2n-1) {
    margin-right:0;
}

숨겨진 요소 무시 질문에 대한 속임수를 따르는 사람에게 도움이되기를 바랍니다!


1
나는 이것을 찬성하고 싶지만 작동하는 데모가 필요합니다.
Moob

내 기억은 이것이 처음에 보였던 것처럼 실제로 강력하지 않다는 것입니다. 이제는 가장 많이 득표 한 댓글로 가겠습니다. 이것은 불가능합니다.
IrishDubGuy

0

모든 선택기에 대해 동일한 부모 클래스 document.querySelector("main .box-value:nth-child(3) select.priorityOption"); 가있는 경우 해당 클래스를 사용합니다 document.querySelector("main .box-value select.priorityOption:nth-child(3)");. 이 경우 작동하지 않기 때문입니다. 감사합니다

<div class="card table">
    <div class="box">
        <div class="box-value">
            <select class="priorityOption">
                <option value="">--</option>
                <option value="">LOREM</option>
                <option value="">LOREM</option>
            </select>
        </div>

        <div class="box-value">
            <select class="priorityOption">
                <option value="">--</option>
                <option value="">LOREM</option>
                <option value="">LOREM</option>
            </select>
        </div>

        <div class="box-value">
            <select class="priorityOption">
                <option value="">--</option>
                <option value="">LOREM</option>
                <option value="">LOREM</option>
            </select>
        </div>
    </div>
</div>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.